<p>Currently, I'm attempting to make multiple beziers have equidistant points.  I'm currently using cubic interpolation to find the points, but because the way beziers work some areas are more dense than others and proving gross for texture mapping because of the variable distance.  <strong>Is there a way to find points on a bezier by distance rather than by percentage?  Furthermore, is it possible to extend this to multiple connected curves?</strong></p>

[{'answer_id': 10538, 'author': 'nlucaroni', 'author_id': 157, 'author_profile': 'https://Stackoverflow.com/users/157', 'pm_score': 3, 'selected': True, 'text': '<p>distance between P_0 and P_3 (in cubic form), yes, but I think you knew that, is straight forward.</p>\n\n<p>Distance on a curve is just arc length:</p>\n\n<p><a href="http://www.codecogs.com/eq.latex?%5Cint_%7Bt_0%7D%5E%7Bt_1%7D%20%7B%20|P&#39;(t)|%20dt" rel="nofollow noreferrer">fig 1 http://www.codecogs.com/eq.latex?%5Cint_%7Bt_0%7D%5E%7Bt_1%7D%20%7B%20|P&#39;(t)|%20dt</a></p>\n\n<p>where:</p>\n\n<p><a href="http://www.codecogs.com/eq.latex?P%27(t)%20=%20[%7Bx%27,y%27,z%27%7D]%20=%20[%7B%5Cfrac%7Bdx(t)%7D%7Bdt%7D,%5Cfrac%7Bdy(t)%7D%7Bdt%7D,%5Cfrac%7Bdz(t)%7D%7Bdt%7D%7D]" rel="nofollow noreferrer">fig 2 http://www.codecogs.com/eq.latex?P%27(t)%20=%20[%7Bx%27,y%27,z%27%7D]%20=%20[%7B%5Cfrac%7Bdx(t)%7D%7Bdt%7D,%5Cfrac%7Bdy(t)%7D%7Bdt%7D,%5Cfrac%7Bdz(t)%7D%7Bdt%7D%7D]</a></p>\n\n<p><a href="http://steve.hollasch.net/cgindex/curves/cbezarclen.html" rel="nofollow noreferrer">(see the rest)</a></p>\n\n<p>Probably, you\'d have t_0 = 0, t_1 = 1.0, and dz(t) = 0 (2d plane).</p>\n'}, {'answer_id': 855177, 'author': 'J. Peterson', 'author_id': 105767, 'author_profile': 'https://Stackoverflow.com/users/105767', 'pm_score': 3, 'selected': False, 'text': '<p>This is called "arc length" parameterization.  I wrote a paper about this several years ago:</p>\n\n<p><a href="http://www.saccade.com/writing/graphics/RE-PARAM.PDF" rel="noreferrer">http://www.saccade.com/writing/graphics/RE-PARAM.PDF</a></p>\n\n<p>The idea is to pre-compute a "parameterization" curve, and evaluate the curve through that.</p>\n'}, {'answer_id': 34804516, 'author': 'enc_life', 'author_id': 3166209, 'author_profile': 'https://Stackoverflow.com/users/3166209', 'pm_score': 2, 'selected': False, 'text': '<p>I know this is an old question but I recently ran into this problem and created a <code>UIBezierPath</code> extention to solve for an <code>X</code> coordinate given a <code>Y</code> coordinate and vise versa. Written in swift. </p>\n\n<p><a href="https://github.com/rkotzy/RKBezierMath" rel="nofollow">https://github.com/rkotzy/RKBezierMath</a></p>\n\n<pre><code>extension UIBezierPath {\n\nfunc solveBezerAtY(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, y: CGFloat) -&gt; [CGPoint] {\n\n    // bezier control points\n    let C0 = start.y - y\n    let C1 = point1.y - y\n    let C2 = point2.y - y\n    let C3 = end.y - y\n\n    // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D\n    let A = C3 - 3.0*C2 + 3.0*C1 - C0\n    let B = 3.0*C2 - 6.0*C1 + 3.0*C0\n    let C = 3.0*C1 - 3.0*C0\n    let D = C0\n\n    let roots = solveCubic(A, b: B, c: C, d: D)\n\n    var result = [CGPoint]()\n\n    for root in roots {\n        if (root &gt;= 0 &amp;&amp; root &lt;= 1) {\n            result.append(bezierOutputAtT(start, point1: point1, point2: point2, end: end, t: root))\n        }\n    }\n\n    return result\n}\n\nfunc solveBezerAtX(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, x: CGFloat) -&gt; [CGPoint] {\n\n    // bezier control points\n    let C0 = start.x - x\n    let C1 = point1.x - x\n    let C2 = point2.x - x\n    let C3 = end.x - x\n\n    // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D\n    let A = C3 - 3.0*C2 + 3.0*C1 - C0\n    let B = 3.0*C2 - 6.0*C1 + 3.0*C0\n    let C = 3.0*C1 - 3.0*C0\n    let D = C0\n\n    let roots = solveCubic(A, b: B, c: C, d: D)\n\n    var result = [CGPoint]()\n\n    for root in roots {\n        if (root &gt;= 0 &amp;&amp; root &lt;= 1) {\n            result.append(bezierOutputAtT(start, point1: point1, point2: point2, end: end, t: root))\n        }\n    }\n\n    return result\n\n}\n\nfunc solveCubic(a: CGFloat?, var b: CGFloat, var c: CGFloat, var d: CGFloat) -&gt; [CGFloat] {\n\n    if (a == nil) {\n        return solveQuadratic(b, b: c, c: d)\n    }\n\n    b /= a!\n    c /= a!\n    d /= a!\n\n    let p = (3 * c - b * b) / 3\n    let q = (2 * b * b * b - 9 * b * c + 27 * d) / 27\n\n    if (p == 0) {\n        return [pow(-q, 1 / 3)]\n\n    } else if (q == 0) {\n        return [sqrt(-p), -sqrt(-p)]\n\n    } else {\n\n        let discriminant = pow(q / 2, 2) + pow(p / 3, 3)\n\n        if (discriminant == 0) {\n            return [pow(q / 2, 1 / 3) - b / 3]\n\n        } else if (discriminant &gt; 0) {\n            let x = crt(-(q / 2) + sqrt(discriminant))\n            let z = crt((q / 2) + sqrt(discriminant))\n            return [x - z - b / 3]\n        } else {\n\n            let r = sqrt(pow(-(p/3), 3))\n            let phi = acos(-(q / (2 * sqrt(pow(-(p / 3), 3)))))\n\n            let s = 2 * pow(r, 1/3)\n\n            return [\n                s * cos(phi / 3) - b / 3,\n                s * cos((phi + CGFloat(2) * CGFloat(M_PI)) / 3) - b / 3,\n                s * cos((phi + CGFloat(4) * CGFloat(M_PI)) / 3) - b / 3\n            ]\n\n        }\n\n    }\n}\n\nfunc solveQuadratic(a: CGFloat, b: CGFloat, c: CGFloat) -&gt; [CGFloat] {\n\n    let discriminant = b * b - 4 * a * c;\n\n    if (discriminant &lt; 0) {\n        return []\n\n    } else {\n        return [\n            (-b + sqrt(discriminant)) / (2 * a),\n            (-b - sqrt(discriminant)) / (2 * a)\n        ]\n    }\n\n}\n\nprivate func crt(v: CGFloat) -&gt; CGFloat {\n    if (v&lt;0) {\n        return -pow(-v, 1/3)\n    }\n    return pow(v, 1/3)\n}\n\nprivate func bezierOutputAtT(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, t: CGFloat) -&gt; CGPoint {\n\n    // bezier control points\n    let C0 = start\n    let C1 = point1\n    let C2 = point2\n    let C3 = end\n\n    // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D\n    let A = CGPointMake(C3.x - 3.0*C2.x + 3.0*C1.x - C0.x, C3.y - 3.0*C2.y + 3.0*C1.y - C0.y)\n    let B = CGPointMake(3.0*C2.x - 6.0*C1.x + 3.0*C0.x, 3.0*C2.y - 6.0*C1.y + 3.0*C0.y)\n    let C = CGPointMake(3.0*C1.x - 3.0*C0.x, 3.0*C1.y - 3.0*C0.y)\n    let D = C0\n\n    return CGPointMake(((A.x*t+B.x)*t+C.x)*t+D.x, ((A.y*t+B.y)*t+C.y)*t+D.y)\n}\n\n// TODO: - future implementation\nprivate func tangentAngleAtT(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, t: CGFloat) -&gt; CGFloat {\n\n    // bezier control points\n    let C0 = start\n    let C1 = point1\n    let C2 = point2\n    let C3 = end\n\n    // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D\n    let A = CGPointMake(C3.x - 3.0*C2.x + 3.0*C1.x - C0.x, C3.y - 3.0*C2.y + 3.0*C1.y - C0.y)\n    let B = CGPointMake(3.0*C2.x - 6.0*C1.x + 3.0*C0.x, 3.0*C2.y - 6.0*C1.y + 3.0*C0.y)\n    let C = CGPointMake(3.0*C1.x - 3.0*C0.x, 3.0*C1.y - 3.0*C0.y)\n\n    return atan2(3.0*A.y*t*t + 2.0*B.y*t + C.y, 3.0*A.x*t*t + 2.0*B.x*t + C.x)\n}\n\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/10477', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1256/']