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 Model3D GetModel_Second_Axe(BezierSegment3D[][] segmentSets, MaterialGroup materialMiddle, MaterialGroup materialEdge) { Model3DGroup retVal = new Model3DGroup(); int numSegments = segmentSets[0].Length; int squareCount = 8; // 2 is z=0. 0,4 are z=max. 1,3 are intermediate z's // Z to Z AddBezierPlates(squareCount, segmentSets[0], segmentSets[1], retVal, materialMiddle); if (numSegments == 3) { AddBezierPlates(squareCount, new[] { segmentSets[1][0], segmentSets[1][2] }, new[] { segmentSets[2][0], segmentSets[2][2] }, retVal, materialMiddle); AddBezierPlate(squareCount, segmentSets[1][1], segmentSets[2][1], retVal, materialEdge); AddBezierPlates(squareCount, new[] { segmentSets[2][0], segmentSets[2][2] }, new[] { segmentSets[3][0], segmentSets[3][2] }, retVal, materialMiddle); AddBezierPlate(squareCount, segmentSets[2][1], segmentSets[3][1], retVal, materialEdge); } else { AddBezierPlates(squareCount, new[] { segmentSets[1][0], segmentSets[1][3] }, new[] { segmentSets[2][0], segmentSets[2][3] }, retVal, materialMiddle); AddBezierPlates(squareCount, new[] { segmentSets[1][1], segmentSets[1][2] }, new[] { segmentSets[2][1], segmentSets[2][2] }, retVal, materialEdge); AddBezierPlates(squareCount, new[] { segmentSets[2][0], segmentSets[2][3] }, new[] { segmentSets[3][0], segmentSets[3][3] }, retVal, materialMiddle); AddBezierPlates(squareCount, new[] { segmentSets[2][1], segmentSets[2][2] }, new[] { segmentSets[3][1], segmentSets[3][2] }, retVal, materialEdge); } AddBezierPlates(squareCount, segmentSets[3], segmentSets[4], retVal, materialMiddle); // End cap plates for (int cntr = 0; cntr < 2; cntr++) { int index = cntr == 0 ? 0 : 4; // Turn the end cap into a polygon, then triangulate it Point3D[] endCapPoly = BezierUtil.GetPath(squareCount, segmentSets[index].Select(o => new[] { o }).ToArray()); // Call the jagged array overload so that the individual bezier end points don't get smoothed out TriangleIndexed[] endCapTriangles = Math2D.GetTrianglesFromConcavePoly3D(endCapPoly); if (cntr == 0) { endCapTriangles = endCapTriangles.Select(o => new TriangleIndexed(o.Index0, o.Index2, o.Index1, o.AllPoints)).ToArray(); // need to do this so the normals point in the proper direction } AddPolyPlate(endCapTriangles, retVal, materialMiddle); } return(retVal); }
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); }