private List <Curve> GenerateThickCurves(int typology, int maxHeight, int crHeight, int clHeight, List <Point3d> basePointsList, int level) { List <Curve> baseCurves = new List <Curve>(); Vector3d vector1 = new Vector3d(basePointsList[1] - basePointsList[0]); Vector3d vector2 = new Vector3d(basePointsList[1] - basePointsList[2]); double angle = Vector3d.VectorAngle(vector1, vector2); // draw straight lines if ((typology != 1) || (maxHeight == crHeight && maxHeight == clHeight || angle == 0 || angle == Math.PI)) { // draw the typology curve Line line1 = new Line(basePointsList[0], basePointsList[level == 0 ? 1 : 2]); Line line2 = new Line(basePointsList[level == 0 ? 2 : 4], basePointsList[level == 0 ? 1 : 2]); baseCurves.Add(line1.ToNurbsCurve()); baseCurves.Add(line2.ToNurbsCurve()); } // else draw arch else { Arc arc = new Arc(basePointsList[level == 0 ? 0 : 1], basePointsList[level == 0 ? 1 : 2], basePointsList[level == 0 ? 2 : 3]); Point3d pt1 = new Point3d((basePointsList[level == 0 ? 0 : 1].X + basePointsList[level == 0 ? 1 : 2].X) / 2, (basePointsList[level == 0 ? 0 : 1].Y + basePointsList[level == 0 ? 1 : 2].Y) / 2, (basePointsList[level == 0 ? 0 : 1].Z + basePointsList[level == 0 ? 1 : 2].Z) / 2); Point3d pt2 = new Point3d((basePointsList[level == 0 ? 1 : 2].X + basePointsList[level == 0 ? 2 : 3].X) / 2, (basePointsList[level == 0 ? 1 : 2].Y + basePointsList[level == 0 ? 2 : 3].Y) / 2, (basePointsList[level == 0 ? 1 : 2].Z + basePointsList[level == 0 ? 2 : 3].Z) / 2); pt1 = arc.ClosestPoint(pt1); pt2 = arc.ClosestPoint(pt2); Arc arc1 = new Arc(basePointsList[level == 0 ? 0 : 1], pt1, basePointsList[level == 0 ? 1 : 2]); Arc arc2 = new Arc(basePointsList[level == 0 ? 2 : 3], pt2, basePointsList[level == 0 ? 1 : 2]); if (level == 1) { List <Curve> tempList = new List <Curve>(); Line tangentStart = new Line(basePointsList[0], basePointsList[1]); tempList.Add(tangentStart.ToNurbsCurve()); tempList.Add(arc1.ToNurbsCurve()); baseCurves.Add(Curve.JoinCurves(tempList, 0.001, true)[0]); tempList = new List <Curve>(); Line tangentEnd = new Line(basePointsList[4], basePointsList[3]); tempList.Add(tangentEnd.ToNurbsCurve()); tempList.Add(arc2.ToNurbsCurve()); baseCurves.Add(Curve.JoinCurves(tempList, 0.001, true)[0]); } else { baseCurves.Add(arc1.ToNurbsCurve()); baseCurves.Add(arc2.ToNurbsCurve()); } } return(baseCurves); }
/***************************************************/ /**** Public Methods - Curves ****/ /***************************************************/ public static double ParameterAtPoint(this Arc curve, Point point, double tolerance = Tolerance.Distance) { if (curve.ClosestPoint(point).SquareDistance(point) > tolerance * tolerance) { return(-1); } Point centre = curve.CoordinateSystem.Origin; Vector normal = curve.CoordinateSystem.Z; Vector v1 = curve.CoordinateSystem.X; Vector v2 = point - centre; double angle = v1.SignedAngle(v2, normal) - curve.StartAngle; angle = Math.Abs(angle) < Tolerance.Angle ? 0 : angle; //Really small negative angles gives wrong result. This solves that problem. return(((angle + 2 * Math.PI) % (2 * Math.PI)) / curve.Angle()); }
/***************************************************/ public static double Distance(this Point point, Arc arc) { return(point.Distance(arc.ClosestPoint(point))); }
/***************************************************/ /**** public Methods - Vectors ****/ /***************************************************/ public static List <Point> SortAlongCurve(this List <Point> points, Arc arc, double distanceTolerance = Tolerance.Distance, double angleTolerance = Tolerance.Angle) { if (arc.Angle() <= angleTolerance) { return(points.Select(p => p.Clone()).ToList()); } List <Tuple <Point, double> > cData = points.Select(p => new Tuple <Point, double>(p.Clone(), arc.ParameterAtPoint(arc.ClosestPoint(p)))).ToList(); cData.Sort(delegate(Tuple <Point, double> d1, Tuple <Point, double> d2) { return(d1.Item2.CompareTo(d2.Item2)); }); return(cData.Select(d => d.Item1).ToList()); }
/***************************************************/ public static Output <Point, Point> CurveProximity(this Arc curve1, Circle curve2, double tolerance = Tolerance.Distance) { List <Point> cIntersections = curve1.CurveIntersections(curve2); if (cIntersections.Count > 0) { return new Output <Point, Point> { Item1 = cIntersections[0], Item2 = cIntersections[0] } } ; Output <Point, Point> result = new Output <Point, Point>(); Plane ftPln1 = curve1.FitPlane(); Plane ftPln2 = curve2.FitPlane(); List <Point> intPts = new List <Point>(); Point tmp = null; if ((intPts = curve1.PlaneIntersections(ftPln2)).Count != 0) { if (intPts.Count == 1) { tmp = intPts[0]; } else { if (intPts[0].Distance(curve2) < intPts[1].Distance(curve2)) { tmp = intPts[0]; } else { tmp = intPts[1]; } } } else if ((intPts = curve2.PlaneIntersections(ftPln1)).Count != 0) { if (intPts.Count == 1) { if (tmp == null) { tmp = intPts[0]; } else if (tmp.Distance(curve2) > intPts[0].Distance(curve1)) { tmp = intPts[0]; } } else { if (intPts[0].Distance(curve1) < intPts[1].Distance(curve1)) { if (tmp == null) { tmp = intPts[0]; } else if (tmp.Distance(curve2) > intPts[0].Distance(curve1)) { tmp = intPts[0]; } } else { if (tmp == null) { tmp = intPts[1]; } else if (tmp.Distance(curve2) > intPts[1].Distance(curve1)) { tmp = intPts[1]; } } } } Output <Point, Point> oldresult = new Output <Point, Point>(); Output <Point, Point> oldresult2 = new Output <Point, Point>(); Output <Point, Point> result2 = new Output <Point, Point>(); if (tmp != null) { if (tmp.IsOnCurve(curve1)) { result.Item1 = tmp; result.Item2 = curve2.ClosestPoint(result.Item1); } else { result.Item2 = tmp; result.Item1 = curve1.ClosestPoint(result.Item2); } do { oldresult.Item1 = result.Item1; oldresult.Item2 = result.Item2; result.Item1 = curve2.ClosestPoint(result.Item2); result.Item2 = curve1.ClosestPoint(result.Item1); }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance); } else { Line intersect = new Line { Start = curve1.Centre(), End = curve2.Centre }; Point tmp1 = intersect.CurveProximity(curve1).Item1; Point tmp2 = intersect.CurveProximity(curve2).Item1; if (tmp == null) { tmp = tmp1; } if (tmp1.Distance(curve2) < tmp.Distance(curve1) || tmp1.Distance(curve2) < tmp.Distance(curve2)) { tmp = tmp1; } if (tmp2.Distance(curve1) < tmp.Distance(curve1) || tmp2.Distance(curve1) < tmp.Distance(curve2)) { tmp = tmp2; } if (tmp.IsOnCurve(curve1)) { result.Item1 = tmp; result.Item2 = curve2.ClosestPoint(tmp); } else { result.Item2 = tmp; result.Item1 = curve1.ClosestPoint(tmp); } do { oldresult.Item1 = result.Item1; oldresult.Item2 = result.Item2; result.Item1 = curve2.ClosestPoint(result.Item2); result.Item2 = curve1.ClosestPoint(result.Item1); }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance); } if (curve1.EndPoint().Distance(curve2.ClosestPoint(curve1.EndPoint())) < result.Item1.Distance(result.Item2)) { result.Item1 = curve1.EndPoint(); result.Item2 = curve2.ClosestPoint(result.Item1); } if (curve1.StartPoint().Distance(curve2.ClosestPoint(curve1.StartPoint())) < result.Item1.Distance(result.Item2)) { result.Item1 = curve1.StartPoint(); result.Item2 = curve2.ClosestPoint(result.Item1); } tmp = curve1.PointAtParameter((curve1.ParameterAtPoint(result.Item1) + 0.6) % 1); result2.Item1 = tmp; result2.Item2 = curve2.ClosestPoint(tmp); do { oldresult2.Item1 = result2.Item1; oldresult2.Item2 = result2.Item2; result2.Item1 = curve2.ClosestPoint(result2.Item2); result2.Item2 = curve1.ClosestPoint(result2.Item1); }while (oldresult2.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult2.Item1.Distance(result2.Item1) > tolerance * tolerance); if (result.Item1.Distance(result.Item2) > result2.Item1.Distance(result2.Item2)) { result = result2; } return(result); }
/***************************************************/ public static Output <Point, Point> CurveProximity(this Arc curve1, Arc curve2, double tolerance = Tolerance.Distance) { List <Point> cIntersections = curve1.CurveIntersections(curve2); if (cIntersections.Count > 0) { return new Output <Point, Point> { Item1 = cIntersections[0], Item2 = cIntersections[0] } } ; Output <Point, Point> result = new Output <Point, Point>(); Output <Point, Point> oldresult = new Output <Point, Point>(); Output <Point, Point> result2 = new Output <Point, Point>(); Output <Point, Point> result3 = new Output <Point, Point>(); Output <Point, Point> result4 = new Output <Point, Point>(); Output <Point, Point> result5 = new Output <Point, Point>(); Output <Point, Point> result6 = new Output <Point, Point>(); Plane ftPln1 = curve1.FitPlane(); Plane ftPln2 = curve2.FitPlane(); List <Point> fitPoints = new List <Point>(); bool check = false; if ((fitPoints = curve1.PlaneIntersections(ftPln2)).Count > 0) { if (fitPoints.Count == 1) { result.Item1 = fitPoints[0]; result.Item2 = curve2.ClosestPoint(fitPoints[0]); check = true; } else if (fitPoints.Count > 1) { if (fitPoints[0].Distance(curve2) < fitPoints[1].Distance(curve2)) { result.Item1 = fitPoints[0]; result.Item2 = curve2.ClosestPoint(fitPoints[0]); check = true; } else { result.Item1 = fitPoints[1]; result.Item2 = curve2.ClosestPoint(fitPoints[1]); check = true; } } } if ((fitPoints = curve2.PlaneIntersections(ftPln1)).Count > 0) { if (check) { if (fitPoints.Count == 1 && (fitPoints[0].Distance(curve1) < result.Item1.Distance(curve2))) { result.Item2 = fitPoints[0]; result.Item1 = curve1.ClosestPoint(fitPoints[0]); } else if (fitPoints.Count > 1) { if (fitPoints[0].Distance(curve1) < fitPoints[1].Distance(curve1)) { if (fitPoints[0].Distance(curve1) < result.Item1.Distance(curve2)) { result.Item2 = fitPoints[0]; result.Item1 = curve1.ClosestPoint(fitPoints[0]); } } else { if (fitPoints[1].Distance(curve1) < result.Item1.Distance(curve2)) { result.Item2 = fitPoints[1]; result.Item1 = curve1.ClosestPoint(fitPoints[1]); } } } } else if (fitPoints.Count == 1) { result.Item2 = fitPoints[0]; result.Item1 = curve1.ClosestPoint(fitPoints[0]); check = true; } else if (fitPoints.Count > 1) { if (fitPoints[0].Distance(curve1) < fitPoints[1].Distance(curve1)) { result.Item2 = fitPoints[0]; result.Item1 = curve1.ClosestPoint(fitPoints[0]); check = true; } else { result.Item2 = fitPoints[1]; result.Item1 = curve1.ClosestPoint(fitPoints[1]); check = true; } } } if (check) { do { oldresult.Item1 = result.Item1; oldresult.Item2 = result.Item2; result.Item1 = curve2.ClosestPoint(result.Item2); result.Item2 = curve1.ClosestPoint(result.Item1); }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance); } check = false; Line intersect = new Line { Start = curve1.Centre(), End = curve2.Centre() }; Point tmp1 = intersect.CurveProximity(curve1).Item2; Point tmp2 = intersect.CurveProximity(curve2).Item2; if (tmp1.Distance(curve2) < tmp2.Distance(curve1)) { result2.Item1 = tmp1; result2.Item2 = curve2.ClosestPoint(tmp1); } else { result2.Item2 = tmp2; result2.Item1 = curve1.ClosestPoint(tmp2); } do { oldresult.Item1 = result2.Item1; oldresult.Item2 = result2.Item2; result2.Item1 = curve2.ClosestPoint(result2.Item2); result2.Item2 = curve1.ClosestPoint(result2.Item1); }while (oldresult.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result2.Item1) > tolerance * tolerance); if (curve1.EndPoint().Distance(curve2.ClosestPoint(curve1.EndPoint())) < curve1.StartPoint().Distance(curve2.ClosestPoint(curve1.StartPoint()))) { result3.Item1 = curve1.EndPoint(); result3.Item2 = curve2.ClosestPoint(result3.Item1); } else { result3.Item1 = curve1.StartPoint(); result3.Item2 = curve2.ClosestPoint(result3.Item1); } if (curve2.EndPoint().Distance(curve1.ClosestPoint(curve2.EndPoint())) < curve2.StartPoint().Distance(curve1.ClosestPoint(curve2.StartPoint()))) { result4.Item2 = curve2.EndPoint(); result4.Item1 = curve1.ClosestPoint(result4.Item2); } else { result4.Item2 = curve2.StartPoint(); result4.Item1 = curve1.ClosestPoint(result4.Item2); } do { oldresult.Item1 = result3.Item1; oldresult.Item2 = result3.Item2; result3.Item1 = curve2.ClosestPoint(result3.Item2); result3.Item2 = curve1.ClosestPoint(result3.Item1); }while (oldresult.Item2.Distance(result3.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result3.Item1) > tolerance * tolerance); do { oldresult.Item1 = result4.Item1; oldresult.Item2 = result4.Item2; result4.Item1 = curve2.ClosestPoint(result4.Item2); result4.Item2 = curve1.ClosestPoint(result4.Item1); }while (oldresult.Item2.Distance(result4.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result4.Item1) > tolerance * tolerance); result5.Item2 = curve2.PointAtParameter(0.5); result5.Item1 = curve1.ClosestPoint(result5.Item2); result6.Item1 = curve1.PointAtParameter(0.5); result6.Item2 = curve2.ClosestPoint(result6.Item1); do { oldresult.Item1 = result5.Item1; oldresult.Item2 = result5.Item2; result5.Item1 = curve2.ClosestPoint(result5.Item2); result5.Item2 = curve1.ClosestPoint(result5.Item1); }while (oldresult.Item2.Distance(result5.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result5.Item1) > tolerance * tolerance); do { oldresult.Item1 = result6.Item1; oldresult.Item2 = result6.Item2; result6.Item1 = curve2.ClosestPoint(result6.Item2); result6.Item2 = curve1.ClosestPoint(result6.Item1); }while (oldresult.Item2.Distance(result6.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result6.Item1) > tolerance * tolerance); if (result.Item1 == null || result.Item2 == null) { result = result2; } if (result2.Item2.Distance(result2.Item1) < result.Item1.Distance(result.Item2)) { result = result2; } if (result3.Item2.Distance(result3.Item1) < result.Item1.Distance(result.Item2)) { result = result3; } if (result4.Item2.Distance(result4.Item1) < result.Item1.Distance(result.Item2)) { result = result4; } if (result5.Item2.Distance(result5.Item1) < result.Item1.Distance(result.Item2)) { result = result5; } if (result6.Item2.Distance(result6.Item1) < result.Item1.Distance(result.Item2)) { result = result6; } return(result); }
/***************************************************/ public static Output <Point, Point> CurveProximity(this Line curve1, Arc curve2, double tolerance = Tolerance.Distance) { List <Point> cIntersections = curve1.CurveIntersections(curve2); if (cIntersections.Count > 0) { return new Output <Point, Point> { Item1 = cIntersections[0], Item2 = cIntersections[0] } } ; List <Point> plnPts = new List <Point>(); plnPts.Add(curve1.Start); plnPts.Add(curve1.End); plnPts.Add(curve2.Centre()); Point tmp; Plane ftPln = plnPts.FitPlane(); if (ftPln != null) { List <Point> intersecting = curve2.PlaneIntersections(ftPln); if (intersecting.Count > 1) { if (intersecting[0].Distance(curve1) < intersecting[1].Distance(curve1)) { tmp = intersecting[0]; } else { tmp = intersecting[1]; } } else if (intersecting.Count == 1) { tmp = intersecting[0]; } else { tmp = curve2.StartPoint(); } } else { tmp = curve2.StartPoint(); } if (curve2.StartPoint().Distance(curve1) < tmp.Distance(curve1)) { tmp = curve2.StartPoint(); } if (curve2.EndPoint().Distance(curve1) < tmp.Distance(curve1)) { tmp = curve2.EndPoint(); } Line prLn = curve1.Project(curve2.FitPlane()); List <Point> lnInt = prLn.CurveIntersections(curve2); if (lnInt.Count > 0) { if (lnInt.Count > 1) { if (lnInt[0].Distance(curve1) > lnInt[0].Distance(curve1)) { lnInt[0] = lnInt[1]; } } if (lnInt[0].Distance(curve1) < tmp.Distance(curve1)) { tmp = lnInt[0]; } } Output <Point, Point> result = new Output <Point, Point>(); result.Item1 = curve1.ClosestPoint(tmp); result.Item2 = curve2.ClosestPoint(result.Item1); result.Item1 = curve1.ClosestPoint(result.Item2); Output <Point, Point> oldfinal = new Output <Point, Point>(); Output <Point, Point> result2 = new Output <Point, Point>(); if (curve1.Start.Distance(curve2) < curve1.End.Distance(curve2)) { result2.Item1 = curve1.Start; } else { result2.Item1 = curve1.End; } result2.Item2 = curve2.ClosestPoint(result2.Item1); result2.Item1 = curve1.ClosestPoint(result2.Item2); Output <Point, Point> final = new Output <Point, Point>(); if (result.Item1.Distance(result.Item2) < result2.Item1.Distance(result2.Item2)) { final = result; } else { final = result2; } do { oldfinal.Item1 = final.Item1; oldfinal.Item2 = final.Item2; final.Item2 = curve2.ClosestPoint(final.Item1); final.Item1 = curve1.ClosestPoint(final.Item2); }while (Math.Abs(oldfinal.Item1.Distance(oldfinal.Item2) - final.Item1.Distance(final.Item2)) > tolerance * tolerance); return(final); }
public static Point ClosestPoint(this Arc arc, Point point) { return(arc.ClosestPoint(point, Tolerance.Distance)); }