/// <summary> /// Sort curves on the shortest path. /// </summary> /// <param name="curvesToSort"></param> /// <returns></returns> public static List <V2GCurve> SortCurves(List <V2GCurve> curvesToSort) { List <V2GCurve> sortedCurves = new List <V2GCurve>(); List <V2GCurve> curves = new List <V2GCurve>(); curves.AddRange(curvesToSort); // todo: first curve could be the furthest from the center // as of now it's the last curve of the list V2GCurve currentCurve = curves[curves.Count - 1]; curves.RemoveAt(curves.Count - 1); sortedCurves.Add(currentCurve); // find ouf next curve either startpoint or endpoint is closest to the end point of the current curve while (curves.Count != 0) { int bestI = 0; double bestDistance = double.MaxValue; V2GPoint currentPoint = currentCurve.EndPoint; for (int i = 0; i < curves.Count; ++i) { V2GCurve c = curves[i]; double d = Math.Min(currentPoint.DistanceTo(c.StartPoint), currentPoint.DistanceTo(c.EndPoint)); if (bestDistance > d) { bestI = i; bestDistance = d; } } currentCurve = curves[bestI]; curves.RemoveAt(bestI); if (currentPoint.DistanceTo(currentCurve.EndPoint) < currentPoint.DistanceTo(currentCurve.StartPoint)) { currentCurve.Reverse(); } sortedCurves.Add(currentCurve); } return(sortedCurves); }
/// <summary> /// Walk through the contour and gradient curves of a voxel field. /// </summary> /// <param name="VoxelImage">A voxel.</param> /// <param name="Point">A Point3d.</param> /// <param name="SegmentLength"></param> /// <param name="MaxIterations"></param> /// <param name="VectorType"></param> /// <returns></returns> public static List <V2GPoint> VoxelCurvePoints(VoxelImage VoxelImage, V2GPoint Point, double SegmentLength = 0.0001, int MaxIterations = 10000, int VectorType = 0) { List <V2GPoint> Points = new List <V2GPoint>(); List <V2GLine> lines = new List <V2GLine>(); V2GPoint lastPoint = Point; bool ContourEnded = false; int i = 0; Points.Add(Point); while (ContourEnded == false) { if (i > MaxIterations) { ContourEnded = true; } V2GPoint pathVector = new V2GPoint(); V2GVoxelPoint voxelPoint = V2GVoxel.GetVoxelPoint(VoxelImage as VoxelImage, lastPoint); if (voxelPoint.FieldValue > 0.995) { ContourEnded = true; } if (voxelPoint.FieldValue < 0.005) { ContourEnded = true; } if (Points.Count > 500 && lastPoint.DistanceTo(Points[Points.Count - 20]) < 0.001) { ContourEnded = true; } switch (VectorType) { case 0: pathVector = voxelPoint.ContourVector; break; case 1: pathVector = voxelPoint.GradientVector; break; case 2: pathVector = voxelPoint.ContourVector3d; break; default: pathVector = voxelPoint.ContourVector; break; } V2GPoint newPoint = lastPoint + pathVector * SegmentLength; lines.Add(new V2GLine(newPoint, Point)); Points.Add(newPoint); lastPoint = newPoint; if (i > 50 && newPoint.DistanceTo(Point) < 0.001) { ContourEnded = true; Points.Add(Point); } ++i; } return(Points); }