public static Point2D CubicBezierEnvelope0( Point2D point, Rectangle2D bounds, Point2D topLeft, Point2D topLeftH, Point2D topLeftV, Point2D topRight, Point2D topRightH, Point2D topRightV, Point2D bottomRight, Point2D bottomRightH, Point2D bottomRightV, Point2D bottomLeft, Point2D bottomLeftH, Point2D bottomLeftV) { // topLeft topRight // 0--------0 0----------0 // | topLeftH topRightH | // | | // | | // 0 topLeftV topRightV 0 // // // // 0 bottomLeftV bottomRightV 0 // | | // | | // | bottomLeftH bottomRightH | // 0--------0 0----------0 // bottomLeft bottomRight // // Install "Match Margin" Extension to enable word match highlighting, to help visualize where a variable resides in the ASCI map. var normal = (X : (point.X - bounds.X) / bounds.Width, Y : (point.Y - bounds.Top) / bounds.Height); var leftAnchor = BezierInterpolateCubic2DTests.CubicBezierCurve(normal.Y, topLeft.X, topLeft.Y, topLeftV.X, topLeftV.Y, bottomLeftV.X, bottomLeftV.Y, bottomLeft.X, bottomLeft.Y); var leftHandle = InterpolateLinear2DTests.LinearInterpolate2D(normal.Y, topLeftH.X, topLeftH.Y, bottomLeftH.X, bottomLeftH.Y); var rightHandle = InterpolateLinear2DTests.LinearInterpolate2D(normal.Y, topRightH.X, topRightH.Y, bottomRightH.X, bottomRightH.Y); var rightAnchor = BezierInterpolateCubic2DTests.CubicBezierCurve(normal.Y, topRight.X, topRight.Y, topRightV.X, topRightV.Y, bottomRightV.X, bottomRightV.Y, bottomRight.X, bottomRight.Y); return(new Point2D(BezierInterpolateCubic2DTests.CubicBezierCurve(normal.X, leftAnchor.X, leftAnchor.Y, leftHandle.X, leftHandle.Y, rightHandle.X, rightHandle.Y, rightAnchor.X, rightAnchor.Y))); }
public static (Point2D, double) FindNearestPoint(double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double x, double y) { var(a, b, c, d, e, f) = GetQuinticPolynomialFromCubicBezierAndPointTests.GetQuinticPolynomialFromCubicBezierAndPoint(aX, aY, bX, bY, cX, cY, dX, dY, x, y); var candidates = FindAllRealRootsInIntervalTests.FindAllRootsInInterval(0d, 1d, a, b, c, d, e, f); // Find the candidate that yields the closest point on the bezier to the given point. var t = double.NaN; var output = (double.NaN, double.NaN); var minDistance = double.MaxValue; foreach (var candidate in candidates) { var ptAtCandidate = BezierInterpolateCubic2DTests.CubicBezierInterpolate2D(candidate, aX, aY, bX, bY, cX, cY, dX, dY); var distance = SquareDistanceTests.SquareDistance(ptAtCandidate.X, ptAtCandidate.Y, x, y); if (distance < minDistance) { minDistance = distance; t = candidate; output = ptAtCandidate; } } return(output, t); }