/// <summary> /// Initializes a new instance of the <see cref="LinearDimension"/> class, based on three points. /// </summary> public static LinearDimension FromPoints(Point3d extensionLine1End, Point3d extensionLine2End, Point3d pointOnDimensionLine) { Point3d[] points = new Point3d[] { extensionLine1End, extensionLine2End, pointOnDimensionLine }; // Plane dimPlane = new Plane(extensionLine1End, extensionLine2End, pointOnDimensionLine); Plane dimPlane; if (Plane.FitPlaneToPoints(points, out dimPlane) != PlaneFitResult.Success) { return(null); } double s, t; if (!dimPlane.ClosestParameter(extensionLine1End, out s, out t)) { return(null); } Point2d ext1 = new Point2d(s, t); if (!dimPlane.ClosestParameter(extensionLine2End, out s, out t)) { return(null); } Point2d ext2 = new Point2d(s, t); if (!dimPlane.ClosestParameter(pointOnDimensionLine, out s, out t)) { return(null); } Point2d linePt = new Point2d(s, t); return(new LinearDimension(dimPlane, ext1, ext2, linePt)); }
/// <summary> /// Attempts to fit a sphere to a collection of points. /// </summary> /// <param name="points">Points to fit. The collection must contain at least two points.</param> /// <returns>The Sphere that best approximates the points or Sphere.Unset on failure.</returns> /// <since>5.0</since> public static Sphere FitSphereToPoints(System.Collections.Generic.IEnumerable <Point3d> points) { if (points == null) { throw new ArgumentNullException("points"); } Rhino.Collections.Point3dList pts = new Rhino.Collections.Point3dList(points); if (pts.Count < 2) { return(Sphere.Unset); } Plane plane; if (Plane.FitPlaneToPoints(points, out plane) == PlaneFitResult.Failure) { return(Sphere.Unset); } Point3d meanP = new Point3d(0, 0, 0); for (int i = 0; i < pts.Count; i++) { meanP += pts[i]; } meanP /= pts.Count; Point3d center = meanP; double radius = -1; for (int k = 0; k < 2048; k++) { double meanL = 0.0; Vector3d meanD = new Vector3d(0, 0, 0); Point3d current = center; for (int i = 0; i < pts.Count; i++) { Vector3d diff = pts[i] - center; double length = diff.Length; if (length > RhinoMath.SqrtEpsilon) { meanL += length; meanD -= (diff / length); } } meanL /= pts.Count; meanD /= pts.Count; center = meanP + (meanD * meanL); radius = meanL; if (center.DistanceTo(current) < RhinoMath.SqrtEpsilon) { break; } } plane.Origin = center; return(new Sphere(plane, radius)); }