2010-11-22 19 views
6

Estoy trabajando en un juego basado en el tacto, y estoy teniendo problemas para dibujar un camino que el usuario haya tocado. Estoy tratando de imitar algo así como estas aplicaciones http://www.youtube.com/watch?v=G3CECr6mT1Q o http://www.youtube.com/watch?v=r34-_0wrVC4Dibujando un camino entre dos puntos

Estoy haciendo esto en XNA/C#.

Mi problema es: Tengo el conjunto de puntos de referencia que definen que los usuarios toquen la ruta. No estaba segura de cómo conseguir una línea estilizada entre todos estos puntos, así que pensé "hey, voy a tener una imagen realmente pequeña que es 'la línea', dibujarla en cada punto entre los puntos de referencia y rotarla en consecuencia . No estoy seguro si esta es la mejor solución o no.

Pero estaba atrapado porque no sabía cómo obtener todas las coordenadas entre estos dos puntos. Tengo los dos puntos, puedo obtener un vector desde el primero al segundo, etc, pero me parece que no puede obtener la matemática correcta.

Cualquier sugerencia o ayuda? Gracias!

Respuesta

5

Para calcular un punto intermedio entre dos puntos, encuentre el vector de dirección de un punto al otro y la distancia entre los puntos. Escala la distancia por un factor t entre 0 y 1 donde t = 0 corresponde al primer punto t = 0.5 está a medio camino entre ellos y t = 1 corresponde al segundo punto. Luego escale el vector de dirección por este valor y agréguelo al punto original.

Vector2 IntermediatePoint(Vector2 p0, Vector2 p1, float t) 
{ 
    Vector2 delta = p1 - p0; 

    float distance = delta.Length(); 

    if (distance == 0.0f) 
    { 
     return p0; 
    } 
    else 
    { 
     Vector2 direction = delta/distance; 

     return p0 + direction * (distance * t); 
    } 
} 

Si calcula puntos múltiples entre p0 y p1, solo debe calcular la distancia y la dirección una vez.

También podría utilizar XNA RoundLine para conectar sus puntos.

Otra sugerencia es set up a textured rotated quad.

+0

+1 para RoundLine. –

+0

Empyrean - ¡GRACIAS! Eso funcionó como un encanto! ¡Muy apreciado! ¿Sabes si tu código es más o menos del mismo modo que XNA dibujaría primitivas, o tomaría un golpe de percusión? Además, publicaré mi fragmento de código en caso de que alguien se aventure en este hilo en el futuro. Además, RoundLine se ve muy bien, lo comprobaré. – Steve

+0

Calcular la longitud de un vector es una operación costosa. Pero no es demasiado caro para lo que estás haciendo aquí. XNA no hace esto como parte de su dibujo de líneas primitivo. Sin embargo, no recomiendo usar la primitiva de dibujo lineal. Como sugiere en su pregunta, no es personalizable en absoluto. – Empyrean

0

salida de la muestra a http://create.msdn.com/en-US/education/catalog/sample/primitives para obtener detalles sobre cómo dibujar simples "Primitivos", incluida una línea.

+0

gracias, pero en realidad ya he echado un vistazo a eso antes. Al mirar eso, no estaba seguro de cómo podría personalizar su línea para que sea algo un poco más atractiva, la única personalización que encontré fue la opción de color. También creo que hacen que XNA haga muchos cálculos para dibujar, por lo que no puedo ver sus cálculos sobre cómo lo hicieron. – Steve

1
pointA = waypointsToDraw.ElementAt(i); 
pointB = waypointsToDraw.ElementAt(i + 1); 
deltaVector = pointB - pointA; 
distance = deltaVector.Length(); 
direction = deltaVector/distance; 
for (int z = 1; z < distance; z++) 
{ 
    newPoint = pointA + direction * (distance * (z/distance)); 
    //this is the newPoint - it will be every point/pixel between pointA and pointB. Put drawing code here 

} 

Muestree el código anterior. PointA y pointB son los dos puntos finales, newPoint será cada punto entre ellos

+0

Sugiero que z sea del tipo float para evitar la conversión de int a float una vez por loop cuando se divide por distancia. Intente evitar los tipos de mezcla en operaciones matemáticas para un rendimiento óptimo. – Empyrean

+0

gracias por los comentarios, lo tendré en cuenta. Solo para mantener el ejercicio de aprendizaje en marcha, si quisiera aplicar una curva bezier o una spline catmull-rom a la anterior, ¿sería fácil ajustar lo anterior para esto? :) – Steve

Cuestiones relacionadas