Vector3 calculate(float percentage) { var low = 0; var high = points.Length - 2; while (low < high) { var mid = (low + high) / 2; if (points[mid + 1].percentageOfPathTraveled < percentage) { low = mid + 1; } else { high = mid; } } var segmentPercentage = (percentage - points[low].percentageOfPathTraveled) / (points[low + 1].percentageOfPathTraveled - points[low].percentageOfPathTraveled); switch (method) { case InterpolationMethod.Linear: return(Vector3.Lerp( points[low].point, points[low + 1].point, segmentPercentage )); case InterpolationMethod.Cubic: return(InterpolationUtils.cubicGetPt( idx => points[idx].point, points.Length, low, segmentPercentage, closed )); case InterpolationMethod.Hermite: return(InterpolationUtils.hermiteGetPt( idx => points[idx].point, points.Length, low, segmentPercentage, closed )); case InterpolationMethod.CatmullRom: return(InterpolationUtils.catmullRomGetPt( idx => points[idx].point, points.Length, low, segmentPercentage, closed )); default: throw new ArgumentOutOfRangeException(); } }
private void SetPathData() { if (Points == null) { return; } var points = new List <Point>(); foreach (var point in Points) { var pointProperties = point.GetType().GetProperties(); if (pointProperties.All(p => p.Name != "X") || pointProperties.All(p => p.Name != "Y")) { continue; } var x = (double)point.GetType().GetProperty("X").GetValue(point, new object[] { }); var y = (double)point.GetType().GetProperty("Y").GetValue(point, new object[] { }); points.Add(new Point(x, y)); } if (points.Count <= 1) { return; } var Teeth_PathFigure = new PathFigure { StartPoint = points.FirstOrDefault() }; var Teeth_SegmentCollection = new PathSegmentCollection(); var bezierSegments = InterpolationUtils.InterpolatePointWithBezierCurves(points, true); if (bezierSegments == null || bezierSegments.Count < 1) { foreach (var point in points.GetRange(1, points.Count - 1)) { var lineSegment = new LineSegment { Point = point }; Teeth_SegmentCollection.Add(lineSegment); } } else { foreach (var curveSeg in bezierSegments) { var segment = new BezierSegment { Point1 = curveSeg.FirstControlPoint, Point2 = curveSeg.SecondControlPoint, Point3 = curveSeg.EndPoint }; Teeth_SegmentCollection.Add(segment); } } Teeth_PathFigure.Segments = Teeth_SegmentCollection; var Teeth_PathFigureCollection = new PathFigureCollection { Teeth_PathFigure }; var Teeth_PathGeometry = new PathGeometry { Figures = Teeth_PathFigureCollection }; path.Data = Teeth_PathGeometry; }
void SetPathData() { if (Points == null) { return; } var points = new List <Point>(); foreach (var point in Points) { var pointProperties = point.GetType().GetProperties(); if (pointProperties.All(p => p.Name != "X") || pointProperties.All(p => p.Name != "Y")) { continue; } var x = (float)point.GetType().GetProperty("X").GetValue(point, new object[] { }); var y = (float)point.GetType().GetProperty("Y").GetValue(point, new object[] { }); points.Add(new Point(x, y)); } if (points.Count <= 1) { return; } var myPathFigure = new PathFigure { StartPoint = points.FirstOrDefault() }; var myPathSegmentCollection = new PathSegmentCollection(); var beizerSegments = InterpolationUtils.InterpolatePointWithBeizerCurves(points, IsClosedCurve); if (beizerSegments == null || beizerSegments.Count < 1) { //Add a line segment <this is generic for more than one line> foreach (var point in points.GetRange(1, points.Count - 1)) { var myLineSegment = new LineSegment { Point = point }; myPathSegmentCollection.Add(myLineSegment); } } else { foreach (var beizerCurveSegment in beizerSegments) { var segment = new BezierSegment { Point1 = beizerCurveSegment.FirstControlPoint, Point2 = beizerCurveSegment.SecondControlPoint, Point3 = beizerCurveSegment.EndPoint }; myPathSegmentCollection.Add(segment); } } myPathFigure.Segments = myPathSegmentCollection; var myPathFigureCollection = new PathFigureCollection { myPathFigure }; var myPathGeometry = new PathGeometry { Figures = myPathFigureCollection }; path.Data = myPathGeometry; }
public Vector3Path( InterpolationMethod method, bool closed, ImmutableArray <Vector3> positions, Option <Transform> relativeTo, int pathResolution ) { this.method = method; this.closed = closed; this.relativeTo = relativeTo; resolution = pathResolution; points = segmentLengthRatios(); //Distance to the last node is the whole path distance realLength = points[points.Length - 1].realDistanceToThisPoint; constantSpeedTable = new ConstantSpeedTable(resolution, calculate); // Returns list of Points with Vector3 coordinates, // length and segment length ratios added to prev element ratio and // distance from the start to this point ImmutableArray <Point> segmentLengthRatios() { switch (method) { case InterpolationMethod.Linear: { var builder = ImmutableArray.CreateBuilder <Point>(positions.Length); var length = positions.Aggregate(0f, (node, current, idx) => idx == 0 ? current : current + Vector3.Distance(positions[idx - 1], node) ); builder.Add(new Point(positions[0], 0f, 0f)); for (var idx = 1; idx < positions.Length; idx++) { var distanceBetweenPositions = Vector3.Distance(positions[idx - 1], positions[idx]); var previousPoint = builder[idx - 1]; builder.Add(new Point( positions[idx], distanceBetweenPositions / length + previousPoint.percentageOfPathTraveled, distanceBetweenPositions + previousPoint.realDistanceToThisPoint )); } return(builder.MoveToImmutable()); } case InterpolationMethod.Hermite: { return(getSegmentRatios( positions, (segmentIndex, percentageOfPath) => InterpolationUtils.hermiteGetPt( idx => positions[idx], positions.Length, segmentIndex, percentageOfPath, closed ))); } case InterpolationMethod.Cubic: { return(getSegmentRatios( positions, (segmentIndex, percentageOfPath) => InterpolationUtils.cubicGetPt( idx => positions[idx], positions.Length, segmentIndex, percentageOfPath, closed ))); } case InterpolationMethod.CatmullRom: { return(getSegmentRatios( positions, (segmentIndex, percentageOfPath) => InterpolationUtils.catmullRomGetPt( idx => positions[idx], positions.Length, segmentIndex, percentageOfPath, closed ))); } default: throw new ArgumentOutOfRangeException(); } } }