/***************************************************/ public static bool IsCoplanar(this PolyCurve curve1, PolyCurve curve2, double tolerance = Tolerance.Distance) { List <Point> pts = new List <Point> { curve1.Curves[0].IStartPoint() }; foreach (ICurve crv in curve1.SubParts()) { if (crv is Line) { pts.Add((crv as Line).End); } else if (crv is Arc) { pts.Add((crv as Arc).PointAtParameter(0.5)); pts.Add((crv as Arc).EndPoint()); } else if (crv is Circle) { pts.Add((crv as Circle).PointAtParameter(0.3)); pts.Add((crv as Circle).PointAtParameter(0.6)); } else { throw new NotImplementedException(); } } pts.Add(curve2.Curves[0].IStartPoint()); foreach (ICurve crv in curve2.ISubParts()) { if (crv is Line) { pts.Add((crv as Line).End); } else if (crv is Arc) { pts.Add((crv as Arc).PointAtParameter(0.5)); pts.Add((crv as Arc).EndPoint()); } else if (crv is Circle) { pts.Add((crv as Circle).PointAtParameter(0.3)); pts.Add((crv as Circle).PointAtParameter(0.6)); } else { throw new NotImplementedException(); } } return(pts.IsCoplanar(tolerance)); }
public static Vector Normal(this PolyCurve curve, double tolerance = Tolerance.Distance) { List <ICurve> crvs = new List <ICurve>(curve.ISubParts()); if (crvs.Any(x => x is NurbsCurve)) { Reflection.Compute.RecordError("Querying normal from PolyCurves with segments of type NurbsCurve is not supported."); return(null); } if (!curve.IsPlanar(tolerance)) { Reflection.Compute.RecordError("A single normal vector is not unambiguously definable for non-planar curves."); return(null); } else if (!curve.IsClosed(tolerance)) { Reflection.Compute.RecordError("A single normal vector is not unambiguously definable for open curves."); return(null); } else if (curve.IsSelfIntersecting(tolerance)) { Reflection.Compute.RecordWarning("Input curve is self-intersecting. Resulting normal vector might be flipped."); } if (crvs.Count() == 0) { return(null); } else if (crvs.Count() == 1) { return(crvs[0].INormal()); } else { List <Point> points = new List <Point>(); foreach (ICurve crv in crvs) { if (crv is Line) { points.Add((crv as Line).End); } else if (crv is Arc) { for (int j = 1; j < 5; j++) { points.Add((crv as Arc).PointAtParameter(j * 0.25)); } } } Point avg = points.Average(); Vector normal = new Vector(); //Get out normal, from cross products between vectors from the average point to adjecent controlpoints on the curve for (int i = 0; i < points.Count - 1; i++) { normal += (points[i] - avg).CrossProduct(points[i + 1] - avg); } if (normal.Length() < tolerance) { Reflection.Compute.RecordError("Couldn't calculate a normal vector of the given curve."); return(null); } normal = normal.Normalise(); //Check if normal needs to be flipped from the right hand rule if (!curve.IsClockwise(normal, tolerance)) { normal = -normal; } return(normal); } }
/***************************************************/ public static Vector Normal(this PolyCurve curve) { if (!curve.IsPlanar()) { Reflection.Compute.RecordError("Input must be planar."); return(null); } else if (!curve.IsClosed()) { Reflection.Compute.RecordError("Curve is not closed. Input must be a polygon"); return(null); } else if (curve.IsSelfIntersecting()) { Reflection.Compute.RecordWarning("Curve is self intersecting"); return(null); } Vector normal = new Vector { X = 0, Y = 0, Z = 0 }; List <Point> pts = new List <Point> { curve.Curves[0].IStartPoint() }; foreach (ICurve crv in curve.ISubParts()) { if (crv is Line) { pts.Add((crv as Line).End); } else if (crv is Arc) { int numb = 4; List <Point> aPts = crv.SamplePoints(numb); for (int i = 1; i < aPts.Count; i++) { pts.Add(aPts[i]); } } else { throw new NotImplementedException(); } } Point pA = pts[0]; for (int i = 1; i < pts.Count - 1; i++) { Point pB = pts[i]; Point pC = pts[i + 1]; normal += CrossProduct((pB - pA).Normalise(), (pC - pB).Normalise()); normal += CrossProduct(pB - pA, pC - pA); } return(normal.Normalise()); }
/***************************************************/ public static Vector Normal(this PolyCurve curve, double tolerance = Tolerance.Distance) { if (!curve.IsPlanar(tolerance)) { Reflection.Compute.RecordError("Input must be planar."); return(null); } else if (!curve.IsClosed(tolerance)) { Reflection.Compute.RecordError("Curve is not closed. Input must be a polygon"); return(null); } else if (curve.IsSelfIntersecting(tolerance)) { Reflection.Compute.RecordWarning("Curve is self intersecting"); return(null); } List <ICurve> crvs = new List <ICurve>(curve.ISubParts()); if (crvs.Count() == 0) { return(null); } else if (crvs.Count() == 1) { return(crvs[0].INormal()); } else { List <Point> points = new List <Point>(); foreach (ICurve crv in crvs) { if (crv is Line) { points.Add((crv as Line).End); } else if (crv is Arc) { for (int j = 1; j < 5; j++) { points.Add((crv as Arc).PointAtParameter(j * 0.25)); } } else { throw new NotImplementedException(); } } Point avg = points.Average(); Vector normal = new Vector(); //Get out normal, from cross products between vectors from the average point to adjecent controlpoints on the curve for (int i = 0; i < points.Count - 1; i++) { normal += (points[i] - avg).CrossProduct(points[i + 1] - avg); } normal = normal.Normalise(); //Check if normal needs to be flipped from the right hand rule if (!curve.IsClockwise(normal, tolerance)) { normal = -normal; } return(normal); } }