2012-02-29 13 views
10

Quiero mover mi imagen en una trayectoria curva de Bézier de arriba a abajo pero no puedo obtener cómo puedo calcular puntos x/y y pendiente desde esta ruta. La ruta es la siguiente imagen:Mover un objeto en una trayectoria de curva de Bézier

enter image description here

tengo iniciar puntos, puntos finales y los dos puntos de control.

Path path = new Path(); 
Point s = new Point(150, 5); 
Point cp1 = new Point(140, 125); 
Point cp2 = new Point(145, 150); 
Point e = new Point(200, 250); 
path.moveTo(s.x, s.y); 
path.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y); 

Respuesta

11

Esta es una curva cúbica de Bézier para el que la fórmula es simplemente [x,y]=(1–t)^3*P0+3(1–t)^2*t*P1+3(1–t)t^2*P2+t^3*P3. Con esto puedes resolver cada punto evaluando la ecuación. En Java esto se podría hacer de esta manera:

/* t is time(value of 0.0f-1.0f; 0 is the start 1 is the end) */ 
Point CalculateBezierPoint(float t, Point s, Point c1, Point c2, Point e) 
{ 
    float u = 1 – t; 
    float tt = t*t; 
    float uu = u*u; 
    float uuu = uu * u; 
    float ttt = tt * t; 

    Point p = new Point(s.x * uuu, s.y * uuu); 
    p.x += 3 * uu * t * c1.x; 
    p.y += 3 * uu * t * c1.y; 
    p.x += 3 * u * tt * c2.x; 
    p.y += 3 * u * tt * c2.y; 
    p.x += ttt * e.x; 
    p.y += ttt * e.y; 

    return p; 
} 

Así que si quería mover un sprite a lo largo del camino, entonces sólo tendría que establecer el valor t de un valor de 0 - 1, dependiendo de qué tan lejos en el camino que quieres ser Ejemplo:

int percentMovedPerFrame = 1;// Will complete path in 100 frames 
int currentPercent = 0; 
update() { 
    if (currentPercent < 100) { 
     this.pos = CalculateBezierPoint(currentPercent/100.0f, this.path.s, this.path.c1, this.path.c2, this.path.e); 
     currentPercent += percentMovedPerFrame 
    } 
} 
+0

hola ... quiero mover el imagen en la ruta de forma manual. Quiero decir que quiero mover la imagen en el evento táctil ... ¿cómo puedo modificar tu código para eso? –

+0

Mi código es tan manual como podría obtener a menos que desee escribir rutinas de rasterización para esa imagen ... –

4

Si solo tiene 2 puntos de control, una curva de bezier es una línea lineal.

Si tiene 3, tiene una curva cuadrática. 4 puntos de control definen una curva cúbica.

Las curvas de Bezier son funciones que dependen del "tiempo". Va de 0.0 - 1.0. Si ingresas 0 en la ecuación, obtienes el valor al principio de la curva. Si ingresas 1.0, el valor al final.

Las curvas de Bezier interpolan el primer y último punto de control, por lo que esos serían sus puntos de inicio y final. Mire cuidadosamente qué paquete o biblioteca está utilizando para generar la curva.

Para orientar su imagen con el vector tangente de la curva, debe diferenciar la ecuación de la curva (puede buscar la ecuación de curva de bezier cúbica en wiki). Eso le dará el vector tangente para orientar su imagen.

+0

puede darme alguna pista sobre cómo encontrar la ecuación cuadrática de una curva bezier con 2 y 3 puntos de control. –

+0

Mira en: http://en.wikipedia.org/wiki/B%C3%A9zier_curve Muestra ecuaciones para lineal, cuadrático y cúbico – PixelPerfect3

+0

también tenga en cuenta que en su ejemplo tiene 4 puntos de control. el punto inicial y final también se consideran puntos de control. Para evaluar la curva, simplemente use la última fórmula en la sección 'Curvas cubicas de Bézier' de la wiki. p.ej. P0 = s, P1 = cp1, P2 = cp2, P3 = e B (0) = s y B (1) = e en su ejemplo. – Dirk

16

Android le ofrece una API para lograr lo que desea. Use la clase llamada android.graphics.PathMeasure. Hay dos métodos que le serán útiles: getLength(), para recuperar la longitud total en píxeles de la ruta, y getPosTan(), para recuperar la posición X, Y de un punto en la curva a una distancia especificada (así como la tangente en esta ubicación.)

Por ejemplo, si getLength() devuelve 200 y desea conocer la posición X, Y del punto en el medio de la curva, llame a getPosTan() con distance = 100.

Más información: http://developer.android.com/reference/android/graphics/PathMeasure.html

+0

http://stackoverflow.com/questions/18651025/how-to-move-image-on-curve-on-touch-event-in-android Por favor, ayúdenme en esta pregunta –

3

Nota que el cambio del parámetro en forma paramétrica de una Bezier cúbica no produce resultados lineales. En otras palabras, establecer t = 0.5 no le da un punto que está a la mitad de la curva. Dependiendo de la curvatura (que está definida por los puntos de control) habrá no linealidades a lo largo de la ruta.

0

Para cualquier persona que necesite calcular puntos de valor estático de la curva Bezier Bezier curve calculator es una buena fuente. Especialmente si usa el cuarto cuadrante (es decir, entre la línea X y la línea Y).Entonces puede mapearlo completamente al sistema de coordenadas de Android haciendo mod en valor negativo.

Cuestiones relacionadas