una pierre online illustrator hacer graficar graficacion ejemplo curvas curva como caracteristicas bézier graphics interpolation bezier curve

graphics - pierre - Puntos equidistantes en las curvas de Bezier



graficar curvas de bezier online (3)

Actualmente, intento hacer que múltiples beziers tengan puntos equidistantes. Actualmente estoy usando la interpolación cúbica para encontrar los puntos, pero debido a la forma en que trabajan los beziers, algunas áreas son más densas que otras y resultan ser burdas para el mapeo de texturas debido a la distancia variable. ¿Hay alguna forma de encontrar puntos en un bezier por distancia en lugar de por porcentaje? Además, ¿es posible extender esto a múltiples curvas conectadas?


distancia entre P_0 y P_3 (en forma cúbica), sí, pero creo que lo sabías, es sencillo.

La distancia en una curva es solo la longitud del arco:

fig 1 http://www.codecogs.com/eq.latex?%5Cint_%7Bt_0%7D%5E%7Bt_1%7D%20%7B%20|P''(t)|%20dt

dónde:

fig 2 http://www.codecogs.com/eq.latex?P%27(t)%20=%20[%7Bx%27,y%27,z%27%7D]%20=%20[%20 7B% 5Cfrac% 7Bdx (t)% 7D% 7Bdt% 7D,% 5Cfrac% 7Bdy (t)% 7D% 7Bdt% 7D,% 5Cfrac% 7Bdz (t)% 7D% 7Bdt% 7D% 7D]

(mira el resto)

Probablemente, tendrías t_0 = 0, t_1 = 1.0 y dz (t) = 0 (plano 2d).


Esto se llama parametrización de "longitud del arco". Escribí un artículo sobre esto hace varios años:

http://www.saccade.com/writing/graphics/RE-PARAM.PDF

La idea es calcular previamente una curva de "parametrización" y evaluar la curva a través de eso.


Sé que esta es una pregunta antigua, pero recientemente me encontré con este problema y creé una extensión UIBezierPath para resolver una coordenada X dada una coordenada Y y viceversa. Escrito a la velocidad

https://github.com/rkotzy/RKBezierMath

extension UIBezierPath { func solveBezerAtY(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, y: CGFloat) -> [CGPoint] { // bezier control points let C0 = start.y - y let C1 = point1.y - y let C2 = point2.y - y let C3 = end.y - y // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D let A = C3 - 3.0*C2 + 3.0*C1 - C0 let B = 3.0*C2 - 6.0*C1 + 3.0*C0 let C = 3.0*C1 - 3.0*C0 let D = C0 let roots = solveCubic(A, b: B, c: C, d: D) var result = [CGPoint]() for root in roots { if (root >= 0 && root <= 1) { result.append(bezierOutputAtT(start, point1: point1, point2: point2, end: end, t: root)) } } return result } func solveBezerAtX(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, x: CGFloat) -> [CGPoint] { // bezier control points let C0 = start.x - x let C1 = point1.x - x let C2 = point2.x - x let C3 = end.x - x // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D let A = C3 - 3.0*C2 + 3.0*C1 - C0 let B = 3.0*C2 - 6.0*C1 + 3.0*C0 let C = 3.0*C1 - 3.0*C0 let D = C0 let roots = solveCubic(A, b: B, c: C, d: D) var result = [CGPoint]() for root in roots { if (root >= 0 && root <= 1) { result.append(bezierOutputAtT(start, point1: point1, point2: point2, end: end, t: root)) } } return result } func solveCubic(a: CGFloat?, var b: CGFloat, var c: CGFloat, var d: CGFloat) -> [CGFloat] { if (a == nil) { return solveQuadratic(b, b: c, c: d) } b /= a! c /= a! d /= a! let p = (3 * c - b * b) / 3 let q = (2 * b * b * b - 9 * b * c + 27 * d) / 27 if (p == 0) { return [pow(-q, 1 / 3)] } else if (q == 0) { return [sqrt(-p), -sqrt(-p)] } else { let discriminant = pow(q / 2, 2) + pow(p / 3, 3) if (discriminant == 0) { return [pow(q / 2, 1 / 3) - b / 3] } else if (discriminant > 0) { let x = crt(-(q / 2) + sqrt(discriminant)) let z = crt((q / 2) + sqrt(discriminant)) return [x - z - b / 3] } else { let r = sqrt(pow(-(p/3), 3)) let phi = acos(-(q / (2 * sqrt(pow(-(p / 3), 3))))) let s = 2 * pow(r, 1/3) return [ s * cos(phi / 3) - b / 3, s * cos((phi + CGFloat(2) * CGFloat(M_PI)) / 3) - b / 3, s * cos((phi + CGFloat(4) * CGFloat(M_PI)) / 3) - b / 3 ] } } } func solveQuadratic(a: CGFloat, b: CGFloat, c: CGFloat) -> [CGFloat] { let discriminant = b * b - 4 * a * c; if (discriminant < 0) { return [] } else { return [ (-b + sqrt(discriminant)) / (2 * a), (-b - sqrt(discriminant)) / (2 * a) ] } } private func crt(v: CGFloat) -> CGFloat { if (v<0) { return -pow(-v, 1/3) } return pow(v, 1/3) } private func bezierOutputAtT(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, t: CGFloat) -> CGPoint { // bezier control points let C0 = start let C1 = point1 let C2 = point2 let C3 = end // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D 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) 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) let C = CGPointMake(3.0*C1.x - 3.0*C0.x, 3.0*C1.y - 3.0*C0.y) let D = C0 return CGPointMake(((A.x*t+B.x)*t+C.x)*t+D.x, ((A.y*t+B.y)*t+C.y)*t+D.y) } // TODO: - future implementation private func tangentAngleAtT(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, t: CGFloat) -> CGFloat { // bezier control points let C0 = start let C1 = point1 let C2 = point2 let C3 = end // The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D 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) 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) let C = CGPointMake(3.0*C1.x - 3.0*C0.x, 3.0*C1.y - 3.0*C0.y) 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) } }