2012-04-03 9 views
10

Yo estaba esperando que alguien podría ayudarme a descubrir un método computacionalmente barato para detectar torceduras en una línea paralela a una curva de Bezier como se puede ver aquídetectar "problemillas" en líneas paralelas a las curvas de Bézier

Kink in Line Parallel to Bezier Curve

Lo que me gustaría hacer es poder determinar la intersección de la curvatura, el segmento con un punto de inicio antes de la intersección y el primer segmento con un punto final después del pliegue. De esta manera, simplemente puedo eliminar cualquier segmento innecesario y ajustar el primer y el último segmento para encontrarme en la intersección.

Disculpa si uso los términos incorrectos. Pero por lo que yo entiendo, la forma en que estoy posicionando estos segmentos es determinando el vector unitario de los segmentos para la curva de Bezier (amarillo) y multiplicándolo por el desplazamiento y encontrando el vector normal para crear dos nuevos puntos de inicio y finalización para el segmento de compensación (blanco).

Las matemáticas no son mi fuerte, así que espero que alguien me pueda dar un empujón en la dirección correcta.

EDIT: La imagen en realidad ha sido redimensionada por HTML por lo que si usted está teniendo dificultades para ver lo que estoy hablando aquí es el enlace directo: http://i.stack.imgur.com/xtils.png

+0

Buen diagrama. ¿Qué quieres hacer en el caso en que el Bezier se auto cruce? –

+1

No necesito que ocurra nada especial en esos casos. –

+0

los chicos de math.stackexchange.com pueden estar mejor equipados para ayudarte con esto. –

Respuesta

5

En una primera aproximación, calcular el radius of curvature de su Bezier curve. Si el desplazamiento es mayor o igual que el radio de curvatura, debe buscar un pliegue.

En concreto, para un Bezier cúbica con puntos de control P0, P1, P2, P3:

B(t) = P0 * (1-t)^3 + P1 * 3*t*(1-t)^2 + P2 * 3*t^2*(1-t) + P3 * t^3 
-> B'(t) = (P1-P0) * 3*(1-t)^2 + (P2-P1) * 6*t*(1-t) + (P3-P2) * 3*t^2 
-> B''(t) = (P2+P0-2*P1) * 6*(1-t) + (P3+P1-2*P2) * 6*t 

let: cross2d(p, q) = p.x*q.y - p.y*q.x 
then, radius of curvature = |B'(t)|^3/cross2d(B'(t), B''(t)) 

me quedan el radio de curvatura en forma firmado; el letrero debe indicar el lado de la curva en el que puede esperar el pliegue.

Nota: puede tener un radio de curvatura cero o un radio infinito de curvatura; puede ser mejor comparar |B'(t)|^3 con signed_offset * cross2d(B'(t), B''(t)) en su lugar.

+0

Impresionante. Parece que funcionará. Lo intentaré y te llamaré. Podría llevarme un tiempo.:) +1 –

+0

Perdóname si esta es una pregunta tonta, pero como dije, las matemáticas no son mi fuerte. Mientras su función cross2d (p, q) toma nota de que mis puntos P son coordenadas xey, las funciones B, B 'y B' 'no. ¿Esto significa que acabo de ejecutar estos una vez para cada eje? –

+0

Los 'B (t)', 'B '(t)' y 'B' '(t)' deben ser vectores bidimensionales, como 'P0',' P1', 'P2', y' P3' . Además, tenga en cuenta que '| B '(t) |' debería tomar la longitud del vector 2-D. Probablemente sea mejor utilizar una estructura 'Vector2' (o cualquier estructura existente que esté utilizando actualmente para sus puntos 2-D), por lo que no tiene que volver a calcular los pesos Bezier varias veces. Sin embargo, puede escribir funciones escalares y ejecutarlas para cada eje si lo desea. Solo tenga en cuenta que deberá volver a unirlos cuando calcule la longitud del vector y el cross2d(). – comingstorm

Cuestiones relacionadas