private static BezierSegment3D[] GetModel_Symetrical_Segments(Point3D[] endPoints, AxeSymetricalProps arg) { const int TOPLEFT = 0; const int BOTTOMLEFT = 1; const int TOPRIGHT = 2; const int BOTTOMRIGHT = 3; // Edge Point3D controlTR = BezierUtil.GetControlPoint_End(endPoints[TOPRIGHT], endPoints[BOTTOMRIGHT], endPoints[TOPLEFT], true, arg.edgeAngle, arg.edgePercent); Point3D controlBR = BezierUtil.GetControlPoint_End(endPoints[BOTTOMRIGHT], endPoints[TOPRIGHT], endPoints[BOTTOMLEFT], true, arg.edgeAngle, arg.edgePercent); BezierSegment3D edge = new BezierSegment3D(TOPRIGHT, BOTTOMRIGHT, new[] { controlTR, controlBR }, endPoints); // Bottom Point3D controlBL = BezierUtil.GetControlPoint_End(endPoints[BOTTOMLEFT], endPoints[BOTTOMRIGHT], endPoints[TOPRIGHT], arg.leftAway, arg.leftAngle, arg.leftPercent); controlBR = BezierUtil.GetControlPoint_End(endPoints[BOTTOMRIGHT], endPoints[BOTTOMLEFT], endPoints[TOPRIGHT], arg.rightAway, arg.rightAngle, arg.rightPercent); BezierSegment3D bottom = new BezierSegment3D(BOTTOMLEFT, BOTTOMRIGHT, new[] { controlBL, controlBR }, endPoints); // Top Point3D controlTL = BezierUtil.GetControlPoint_End(endPoints[TOPLEFT], endPoints[TOPRIGHT], endPoints[BOTTOMRIGHT], arg.leftAway, arg.leftAngle, arg.leftPercent); controlTR = BezierUtil.GetControlPoint_End(endPoints[TOPRIGHT], endPoints[TOPLEFT], endPoints[BOTTOMRIGHT], arg.rightAway, arg.rightAngle, arg.rightPercent); BezierSegment3D top = new BezierSegment3D(TOPLEFT, TOPRIGHT, new[] { controlTL, controlTR }, endPoints); return(new[] { bottom, top, edge }); }
private static void AddBezierPlate(int count, BezierSegment3D seg1, BezierSegment3D seg2, Model3DGroup group, Material material) { // Since the bezier curves will have the same number of points, create a bunch of squares linking them (it's up to the caller // to make sure the curves don't cross, or you would get a bow tie) Point3D[] rim1 = BezierUtil.GetPoints(count, seg1); Point3D[] rim2 = BezierUtil.GetPoints(count, seg2); Point3D[] allPoints = UtilityCore.Iterate(rim1, rim2).ToArray(); List <TriangleIndexed> triangles = new List <TriangleIndexed>(); for (int cntr = 0; cntr < count - 1; cntr++) { triangles.Add(new TriangleIndexed(count + cntr, count + cntr + 1, cntr, allPoints)); // bottom left triangles.Add(new TriangleIndexed(cntr + 1, cntr, count + cntr + 1, allPoints)); // top right } // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = material; geometry.BackMaterial = material; geometry.Geometry = UtilityWPF.GetMeshFromTriangles(triangles.ToArray()); group.Children.Add(geometry); }
void DrawBezier(int splineInd) { Vector3[] pnts = curve.GetSplinePoints(splineInd); Vector3 start = curve.transform.TransformPoint(BezierUtil.GetPoint(pnts, 0f)); //Vector3 start = BezierUtil.GetPoint(pnts, 0f); curve.curvePoints.Add(curve.transform.InverseTransformPoint(start)); float i = 0; while (i < 1) { Handles.color = Color.red; i += .1f; Vector3 end = curve.transform.TransformPoint(BezierUtil.GetPoint(pnts, i)); //Vector3 end = BezierUtil.GetPoint(pnts, i); curve.curvePoints.Add(curve.transform.InverseTransformPoint(end)); Handles.DrawLine(start, end); /* * Handles.color = Color.green; * Vector3 velocity = (end - start) * 15; * Handles.DrawLine(end, end + velocity); */ start = end; } if (curve.Splines - 1 != splineInd) { // Avoid overlapping of curves curve.curvePoints.RemoveAt(curve.curvePoints.Count - 1); } }
public static void Render(RenderManager.CameraInfo cameraInfo, AngleMeasurement angle) { if (angle.HideOverlay) { return; } var renderManager = RenderManager.instance; var centreAngle = Vector3.Angle(Vector3.right, angle.AngleNormal); if (Vector3.Cross(Vector3.right, angle.AngleNormal).y > 0f) { centreAngle = -centreAngle; } var arcs = BezierUtil.CreateArc(angle.Position, GetAngleDistance(angle.Flags), centreAngle - angle.AngleSize * .5f, centreAngle + angle.AngleSize * .5f); for (var i = 0; i < arcs.Count; i++) { var isFirst = i == 0; var isLast = i == arcs.Count - 1; renderManager.OverlayEffect.DrawBezier(cameraInfo, GetAngleColor(angle.Flags), arcs[i], .7f, 0f, 0f, angle.Position.y - 20f, angle.Position.y + 20f, false, true); } }
static void DrawDC(RenderManager.CameraInfo cameraInfo, ushort segmentID1, ushort segmentID2, ushort nodeID) { NetUtil.CalculateSegEndCenter(segmentID1, nodeID, out var pos1, out var dir1); NetUtil.CalculateSegEndCenter(segmentID2, nodeID, out var pos2, out var dir2); Bezier3 b = BezierUtil.Bezier3ByDir(pos1, -dir1, pos2, -dir2); b.RenderArrow(cameraInfo, Color.cyan, 1); }
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); }
public static double NextBell(this Random rand, RandomBellArgs args) { double retVal = BezierUtil.GetPoint(rand.NextDouble(), args.Bezier).Y; if (retVal < 0) { retVal = 0; } else if (retVal > 1) { retVal = 1; } return(retVal); }
private void DrawBell3() { Point[] points = GetBellPoints(txtBell3.Text); if (points == null) { txtBell3.Effect = _errorEffect; return; } txtBell3.Effect = null; BezierSegment3D bezier = new BezierSegment3D(0, 1, points.Select(o => o.ToPoint3D()).ToArray(), new[] { new Point3D(0, 0, 0), new Point3D(1, 1, 0) }); Random rand = StaticRandom.GetRandomForThread(); IEnumerable <double> samples = Enumerable.Range(0, 100000). Select(o => BezierUtil.GetPoint(rand.NextDouble(), bezier).Y); IEnumerable <Point> idealLine = BezierUtil.GetPoints(100, bezier). Select(o => o.ToPoint2D()); DrawGraph(samples, idealLine); Rect bounds = GetBounds(); for (int cntr = 0; cntr < bezier.ControlPoints.Length - 1; cntr++) { Point from = GetScaledPoint(bezier.ControlPoints[cntr], bounds); Point to = GetScaledPoint(bezier.ControlPoints[cntr + 1], bounds); AddLine(from, to, _brushLightBlue); } if (bezier.ControlPoints.Length > 0) { Point from = GetScaledPoint(bezier.EndPoint0, bounds); Point to = GetScaledPoint(bezier.ControlPoints[0], bounds); AddLine(from, to, _brushLightBlue); from = GetScaledPoint(bezier.EndPoint1, bounds); to = GetScaledPoint(bezier.ControlPoints[bezier.ControlPoints.Length - 1], bounds); AddLine(from, to, _brushLightBlue); } }
private Vector3 GetPos(int x, int z, int max) { float t = (x + z) / (max * 2f); float xT = (float)x / max; float zT = (float)z / max; float yPox = BezierUtil.GetCubic( t, BezierUtil.GetCubic(xT, 0f, _ampl00, _ampl01, 0f), BezierUtil.GetCubic(zT, 0f, _ampl10, _ampl11, 0f), BezierUtil.GetCubic(zT, 0f, _ampl20, _ampl21, 0f), BezierUtil.GetCubic(xT, 0f, _ampl30, _ampl31, 0f) ); return(new Vector3( x, roundFloorYPos ? Mathf.Floor(yPox) : yPox, z )); }
void DrawLine() { if (goList.Count < count || LineMat == null) { return; } var p0 = goList[0].transform.position; var p1 = goList[1].transform.position; var p2 = goList[2].transform.position; var points1 = new Vector3[] { p0, p1 }; DrawLine_Impl(points1, Color.red); var points2 = new Vector3[] { p1, p2 }; DrawLine_Impl(points2, Color.red); var points3 = new Vector3[num]; BezierUtil.GetBezier(ref points3, p0, p1, p2, num); DrawLine_Impl(points3, Color.blue); }
// returns false if angle>180 bool CalculateMiddlePoint() { Vector2 v21 = corner2.Point - corner1.Point; float angle1 = VectorUtil.UnsignedAngleRad(v21, corner1.DirMain); // expected Accute float angle2 = VectorUtil.UnsignedAngleRad(-v21, corner2.DirMain); // expected Accute float c = Mathf.PI * .5f - Epsilon; if (angle1 >= c || angle2 >= c) { Log.Debug("Roundabout angle >= 180"); return(false); } var b2 = BezierUtil.Bezier2ByDir( corner1.Point, corner1.DirMain, corner2.Point, corner2.DirMain); MiddlePoint = b2.Travel2(b2.ArcLength() * .5f, out MDir2); MDir1 = -MDir2; return(true); }
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 BezierSegment3D[] GetModel_Second_Segments(AxeSecondProps arg) { Point3D[] points = arg.GetAllPoints(); // Top BezierSegment3D top = new BezierSegment3D(arg.IndexTL, arg.IndexTR, null, points); // Edge Point3D controlTR = BezierUtil.GetControlPoint_End(arg.EndTR, arg.EndBR, arg.EndBL_1, true, arg.EdgeAngleT, arg.EdgePercentT); Point3D controlBR = BezierUtil.GetControlPoint_End(arg.EndBR, arg.EndTR, arg.EndTL, true, arg.EdgeAngleB, arg.EdgePercentB); BezierSegment3D edge = new BezierSegment3D(arg.IndexTR, arg.IndexBR, new[] { controlTR, controlBR }, points); // Bottom (right portion) BezierSegment3D bottomRight = null; if (arg.EndBL_2 == null) { Point3D controlR = BezierUtil.GetControlPoint_End(arg.EndBR, arg.EndBL_1, arg.EndTR, false, arg.B1AngleR, arg.B1PercentR); Point3D controlL = BezierUtil.GetControlPoint_End(arg.EndBL_1, arg.EndBR, arg.EndTR, false, arg.B1AngleL, arg.B1PercentL); bottomRight = new BezierSegment3D(arg.IndexBR, arg.IndexBL_1, new[] { controlR, controlL }, points); } else { bottomRight = new BezierSegment3D(arg.IndexBR, arg.IndexBL_1, null, points); } // Bottom (left portion) BezierSegment3D bottomLeft = null; if (arg.EndBL_2 != null) { Point3D controlR = BezierUtil.GetControlPoint_End(arg.EndBL_1, arg.EndBL_2.Value, arg.EndTR, false, arg.B2AngleR, arg.B2PercentR); Point3D controlL = BezierUtil.GetControlPoint_End(arg.EndBL_2.Value, arg.EndBL_1, arg.EndTR, false, arg.B2AngleL, arg.B2PercentL); bottomLeft = new BezierSegment3D(arg.IndexBL_1, arg.IndexBL_2, new[] { controlR, controlL }, points); } return(UtilityCore.Iterate <BezierSegment3D>(top, edge, bottomRight, bottomLeft).ToArray()); }
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); }
public void GenerateMesh() { mf = GetComponent <MeshFilter>(); mf.mesh = null; if (mf.sharedMesh == null) { mf.sharedMesh = new Mesh(); } mesh = mf.sharedMesh; s = Parent._Spline; if (shape == null) { shape = new ExtrudeShape(); } shape.verts = verts.ToArray(); shape.normals = new Vector2[GetVertCount()]; shape.uCoords = new float[GetVertCount()]; float uLength = 0; float[] pointPos = new float[GetVertCount()]; pointPos[0] = 0; for (int i = 1; i < verts.Count; i++) { uLength += Vector2.Distance(verts[i - 1], verts[i]); pointPos[i] = uLength; } for (int i = 0; i < GetVertCount(); i++) { shape.uCoords[i] = pointPos[i] / uLength; float dx, dy; Vector2 normal; if (i == 0) { dx = shape.verts[1].x - shape.verts[0].x; dy = shape.verts[1].y - shape.verts[0].y; normal = new Vector2(dy, -dx); shape.normals[i] = BezierUtil.Cross(new Vector2(dx, dy), normal) > 0 ? normal : new Vector2(-dy, dx); } else if (i == GetVertCount() - 1) { dx = shape.verts[0].x - shape.verts[i].x; dy = shape.verts[0].y - shape.verts[i].y; normal = new Vector2(dy, -dx); } else { dx = shape.verts[i + 1].x - shape.verts[i].x; dy = shape.verts[i + 1].y - shape.verts[i].y; normal = new Vector2(dy, -dx); } normal = BezierUtil.Cross(new Vector2(dy, dx), normal) > 0 ? normal : new Vector2(-dy, dx); shape.normals[i] = normal.normalized; //print(string.Format("{0}:{1}", i, normal.normalized)); } float[] samples = BezierUtil.GenerateSamples(s.curvePoints.ToArray()); if (s != null) { OrientedPoint[] op = new OrientedPoint[s.curvePoints.Count]; string debug = ""; for (int i = 0; i < op.Length; i++) { //op[i] = BezierUtil.GetOrientedPoint(s.curvePoints.ToArray(), ((float)i / (float)op.Length), samples); op[i] = new OrientedPoint(s.curvePoints[i], Quaternion.identity, samples.Sample(((float)i / (float)op.Length))); //debug += " " + op[i].vCoordinate; } //Debug.Log(debug); BezierUtil.Extrude(ref mesh, shape, op); //mesh.RecalculateNormals(); } else { Debug.Log("no s"); } }
private void DrawBellArms() { #region OLD //var controlPoints = new List<Tuple<Point, Point>>(); //// Arm1 //if (!trkBellArmsLeftLen.Value.IsNearZero()) //{ // Vector arm1 = new Vector(1, 1).ToUnit() * trkBellArmsLeftLen.Value; // arm1 = arm1. // ToVector3D(). // GetRotatedVector(new Vector3D(0, 0, -1), trkBellArmsLeftAngle.Value). // ToVector2D(); // controlPoints.Add(Tuple.Create(new Point(0, 0), arm1.ToPoint())); //} //// Arm2 //if (!trkBellArmsRightLen.Value.IsNearZero()) //{ // Vector arm2 = new Vector(-1, -1).ToUnit() * trkBellArmsRightLen.Value; // arm2 = arm2. // ToVector3D(). // GetRotatedVector(new Vector3D(0, 0, -1), trkBellArmsRightAngle.Value). // ToVector2D(); // Point point = new Point(1, 1); // controlPoints.Add(Tuple.Create(point, point + arm2)); //} //// Bezier //Point3D[] controlPoints3D = controlPoints. // Select(o => o.Item2.ToPoint3D()). // ToArray(); //BezierSegment3D bezier = new BezierSegment3D(0, 1, controlPoints3D, new[] { new Point3D(0, 0, 0), new Point3D(1, 1, 0) }); #endregion RandomBellArgs bezier = new RandomBellArgs(trkBellArmsLeftLen.Value, trkBellArmsLeftAngle.Value, trkBellArmsRightLen.Value, trkBellArmsRightAngle.Value); // Points Random rand = StaticRandom.GetRandomForThread(); IEnumerable <double> samples = Enumerable.Range(0, 75000). //Select(o => BezierUtil.GetPoint(rand.NextDouble(), bezier).Y); Select(o => rand.NextBell(bezier)); IEnumerable <Point> idealLine = BezierUtil.GetPoints(100, bezier.Bezier). Select(o => o.ToPoint2D()); // Draw DrawGraph(samples, idealLine); Rect bounds = GetBounds(); if (!trkBellArmsLeftLen.Value.IsNearZero()) { Point from = GetScaledPoint(bezier.Bezier.EndPoint0, bounds); Point to = GetScaledPoint(bezier.Bezier.ControlPoints[0], bounds); AddLine(from, to, _brushLightBlue); } if (!trkBellArmsRightLen.Value.IsNearZero()) { Point from = GetScaledPoint(bezier.Bezier.EndPoint1, bounds); Point to = GetScaledPoint(bezier.Bezier.ControlPoints[bezier.Bezier.ControlPoints.Length - 1], bounds); AddLine(from, to, _brushLightBlue); } // Report coords lblBellValues.Text = GetBellArmValues(); lblBellCtrlPoints.Text = GetBellPoints(bezier.Bezier.ControlPoints.Select(o => o.ToPoint2D())); }
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); } }