private static double[] ConvertToVector_Text_Fit(double[] normalized, int width, TextAlignment justify) { if (normalized.Length == width) { return(normalized); } else if (normalized.Length == 0) { return(new double[width]); } if (normalized.Length < width) { #region Expand switch (justify) { case TextAlignment.Left: return(normalized. Concat(new double[width - normalized.Length]). ToArray()); case TextAlignment.Right: return(new double[width - normalized.Length]. Concat(normalized). ToArray()); case TextAlignment.Center: int left = (width - normalized.Length) / 2; int right = width - (left + normalized.Length); return(new double[left]. Concat(normalized). Concat(new double[right]). ToArray()); case TextAlignment.Justify: // Nothing needs to be done break; default: throw new ApplicationException("Unknown TextAlignment"); } #endregion } // Create a bezier through the points, then pull points off of that curve. Unless I read this wrong, this is what bicubic interpolation of images does (I'm just doing 1D instead of 2D) return(BezierUtil.GetPath(width, BezierUtil.GetBezierSegments(normalized.Select(o => new Point3D(o, 0, 0)).ToArray(), isClosed: false)). Select(o => o.X). ToArray()); }
private static SOMItem GetSOMItem_1D(VectorND item, ToVectorInstructions instr) { if (instr.FromSizes[0] == instr.ToSize) { return(new SOMItem(item, item)); } // Create a bezier through the points, then pull points off of that curve. Unless I read this wrong, this is what bicubic interpolation of images does (I'm just doing 1D instead of 2D) Point3D[] points = item. Select(o => new Point3D(o, 0, 0)). ToArray(); BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(points); VectorND resized = BezierUtil.GetPath(instr.ToSize, bezier). Select(o => o.X). ToArray(). ToVectorND(); return(new SOMItem(item, resized)); }
private static Canvas DrawVoronoi_Blobs(VoronoiResult2D voronoi, Color[] colors, SOMNode[] nodes, ISOMInput[][] inputsByNode, int imageWidth, int imageHeight, BlobEvents events) { const double MARGINPERCENT = 1.05; // Analyze size ratios double[] areas = AnalyzeVoronoiCellSizes(voronoi, inputsByNode); #region transform var aabb = Math2D.GetAABB(voronoi.EdgePoints); aabb = Tuple.Create((aabb.Item1.ToVector() * MARGINPERCENT).ToPoint(), (aabb.Item2.ToVector() * MARGINPERCENT).ToPoint()); TransformGroup transform = new TransformGroup(); transform.Children.Add(new TranslateTransform(-aabb.Item1.X, -aabb.Item1.Y)); transform.Children.Add(new ScaleTransform(imageWidth / (aabb.Item2.X - aabb.Item1.X), imageHeight / (aabb.Item2.Y - aabb.Item1.Y))); #endregion Canvas retVal = new Canvas(); retVal.Effect = new DropShadowEffect() { Color = Colors.Gray, Opacity = .2, BlurRadius = 5, Direction = 0, ShadowDepth = 0, }; for (int cntr = 0; cntr < voronoi.ControlPoints.Length; cntr++) { #region polygon Polygon polygon = new Polygon(); if (voronoi.EdgesByControlPoint[cntr].Length < 3) { throw new ApplicationException("Expected at least three edge points"); } Edge2D[] edges = voronoi.EdgesByControlPoint[cntr].Select(o => voronoi.Edges[o]).ToArray(); Point[] edgePoints = Edge2D.GetPolygon(edges, 1d); // Resize to match the desired area edgePoints = ResizeConvexPolygon(edgePoints, areas[cntr]); // Convert into a smooth blob BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(edgePoints.Select(o => o.ToPoint3D()).ToArray(), .25, true); edgePoints = BezierUtil.GetPath(75, bezier). Select(o => o.ToPoint2D()). ToArray(); // Transform to canvas coords edgePoints = edgePoints. Select(o => transform.Transform(o)). ToArray(); foreach (Point point in edgePoints) { polygon.Points.Add(point); } polygon.Fill = new SolidColorBrush(colors[cntr]); polygon.Stroke = null; // new SolidColorBrush(UtilityWPF.OppositeColor(colors[cntr], false)); polygon.StrokeThickness = 1; polygon.Tag = Tuple.Create(events, nodes[cntr], inputsByNode[cntr]); if (events != null) { if (events.MouseMove != null && events.MouseLeave != null) { polygon.MouseMove += Polygon2D_MouseMove; polygon.MouseLeave += Polygon2D_MouseLeave; } if (events.Click != null) { polygon.MouseUp += Polygon_MouseUp; } } retVal.Children.Add(polygon); #endregion } return(retVal); }
private void DrawBell2() { Point[] points = GetBellPoints(txtBell2.Text); if (points == null) { txtBell2.Effect = _errorEffect; return; } txtBell2.Effect = null; BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(points.Select(o => o.ToPoint3D()).ToArray(), trkBell2.Value); for (int cntr = 0; cntr < bezier.Length; cntr++) { bezier[cntr] = new BezierSegment3D(bezier[cntr].EndIndex0, bezier[cntr].EndIndex1, new Point3D[0], bezier[cntr].AllEndPoints); } Random rand = StaticRandom.GetRandomForThread(); IEnumerable <double> samples = Enumerable.Range(0, 50000). Select(o => BezierUtil.GetPoint(rand.NextDouble(), bezier).Y); IEnumerable <Point> idealLine = BezierUtil.GetPath(100, bezier). Select(o => o.ToPoint2D()); DrawGraph(samples, idealLine); var samples2 = Enumerable.Range(0, 1000). Select(o => { double randPercent = rand.NextDouble(); Point3D point = BezierUtil.GetPoint(randPercent, bezier); return(Tuple.Create(randPercent, point.X, point.Y, point.Z)); }). OrderBy(o => o.Item1). ToArray(); if (!samples2.All(o => o.Item4.IsNearZero())) { int three = 2; } if (!samples2.All(o => o.Item2.IsNearValue(o.Item3))) { int four = 7; } var samples2a = samples2. Select(o => Tuple.Create(o.Item1, o.Item2, o.Item1 - o.Item2)). ToArray(); //IEnumerable<Point> testLine = Enumerable.Range(0, 150). // Select(o => BezierUtil.GetPoint(o / 150d, bezier).ToPoint2D()); //Rect bounds = GetBounds(); //IEnumerable<Point> testLineFinal = idealLine // .Select(o => new Point(bounds.Left + (o.X * bounds.Width), bounds.Bottom - (o.Y * bounds.Height))); //AddLine(testLineFinal, new SolidColorBrush(UtilityWPF.ColorFromHex("FF0000")), 1, "test line"); }
private void DrawBellFail() { double midX = trkBellFailPeak.Value; BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(new[] { new Point3D(0, 0, 0), new Point3D(midX, 1, 0), new Point3D(1, 0, 0) }, trkBellFailPinch.Value); // Add a control point so the curve will be attracted to the x axis at the two end points double run; if (trkBellFailLeftZero.Value > 0) { run = (bezier[0].EndPoint1.X - bezier[0].EndPoint0.X) * trkBellFailLeftZero.Value; bezier[0] = new BezierSegment3D(bezier[0].EndIndex0, bezier[0].EndIndex1, new[] { new Point3D(run, 0, 0), bezier[0].ControlPoints[0] }, bezier[0].AllEndPoints); } if (trkBellFailRightZero.Value > 0) { run = (bezier[1].EndPoint1.X - bezier[1].EndPoint0.X) * trkBellFailRightZero.Value; bezier[1] = new BezierSegment3D(bezier[1].EndIndex0, bezier[1].EndIndex1, new[] { bezier[1].ControlPoints[0], new Point3D(bezier[1].EndPoint1.X - run, 0, 0), }, bezier[1].AllEndPoints); } Random rand = StaticRandom.GetRandomForThread(); //TODO: There is still a bug with calculating percent, or something //It might be treating X as a percent. Maybe need to get the length of the lines, and take the percent of those???? - should be the same though IEnumerable <double> samples = Enumerable.Range(0, 50000). Select(o => { double percent = rand.NextDouble(); int index; if (percent < midX) { index = 0; percent = percent / midX; } else { index = 1; percent = (percent - midX) / (1d - midX); } double retVal = BezierUtil.GetPoint(percent, bezier[index]).Y; if (retVal < 0) { retVal = 0; } else if (retVal > 1) { retVal = 1; } return(retVal); }); IEnumerable <Point> idealLine = BezierUtil.GetPath(100, bezier). Select(o => o.ToPoint2D()); DrawGraph(samples, idealLine); }
private void BellFailDebug_Click(object sender, RoutedEventArgs e) { const int COUNT = 25; // The problem that this method illustrates is that rand.nextdouble() is thought of as x, but it's really % along arc length of the curve // And because there are two curves, it's some hacked up hybrid // // The original intent was to get the y coord at some fixed x. But there's no one single calculation that would get that. Samples would // need to be taken to figure out which percent along curve to use to get the desired x, and corresponding y try { double midX = trkBellFailPeak.Value; BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(new[] { new Point3D(0, 0, 0), new Point3D(midX, 1, 0), new Point3D(1, 0, 0) }, trkBellFailPinch.Value); // Add a control point so the curve will be attracted to the x axis at the two end points double run; if (trkBellFailLeftZero.Value > 0) { run = (bezier[0].EndPoint1.X - bezier[0].EndPoint0.X) * trkBellFailLeftZero.Value; bezier[0] = new BezierSegment3D(bezier[0].EndIndex0, bezier[0].EndIndex1, new[] { new Point3D(run, 0, 0), bezier[0].ControlPoints[0] }, bezier[0].AllEndPoints); } if (trkBellFailRightZero.Value > 0) { run = (bezier[1].EndPoint1.X - bezier[1].EndPoint0.X) * trkBellFailRightZero.Value; bezier[1] = new BezierSegment3D(bezier[1].EndIndex0, bezier[1].EndIndex1, new[] { bezier[1].ControlPoints[0], new Point3D(bezier[1].EndPoint1.X - run, 0, 0), }, bezier[1].AllEndPoints); } //bezier[0] = new BezierSegment3D(bezier[0].EndIndex0, bezier[0].EndIndex1, new Point3D[0], bezier[0].AllEndPoints); //bezier[1] = new BezierSegment3D(bezier[1].EndIndex0, bezier[1].EndIndex1, new Point3D[0], bezier[1].AllEndPoints); var samples = Enumerable.Range(0, COUNT). Select(o => { double percentOrig = o.ToDouble() / COUNT.ToDouble(); int index; double percent; if (percentOrig < midX) { index = 0; percent = percentOrig / midX; } else { index = 1; percent = (percentOrig - midX) / (1d - midX); } Point3D point = BezierUtil.GetPoint(percent, bezier[index]); //if (retVal < 0) retVal = 0; //else if (retVal > 1) retVal = 1; return(new { PercentOrig = percentOrig, PercentSub = percent, Index = index, Point = point, }); }). ToArray(); Clear(); Rect bounds = GetBounds(); // Grid AddLine(bounds.BottomLeft, bounds.TopRight, _brushVeryLight); // diagonal AddLine(bounds.TopLeft, bounds.TopRight, _brushVeryLight); // 1 double y = bounds.Bottom - (bounds.Height * .75); AddLine(new Point(bounds.Left, y), new Point(bounds.Right, y), _brushVeryLight); // .75 y = bounds.Bottom - (bounds.Height * .5); AddLine(new Point(bounds.Left, y), new Point(bounds.Right, y), _brushVeryLight); // .5 y = bounds.Bottom - (bounds.Height * .25); AddLine(new Point(bounds.Left, y), new Point(bounds.Right, y), _brushVeryLight); // .25 AddLine(new[] { bounds.TopLeft, bounds.BottomLeft, bounds.BottomRight }, _brushDark); // axiis // Samples foreach (var sample in samples) { AddLine(new Point(bounds.Left + (sample.PercentOrig * bounds.Width), bounds.Bottom), new Point(bounds.Left + (sample.Point.X * bounds.Width), bounds.Bottom - (sample.Point.Y * bounds.Height)), Brushes.Black); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }