Muy buenas,
como de matematicas voy pez ^_^' os pongo un poco en situacion, ya que no se si el algoritmo usado es incorrecto o me estoy liando por alguna otra parte.
Tenemos dos algoritmos, uno para calcular el angulo entre dos objetos (de Origen a Destino) y otro para hacer avanzar un objeto una distancia D en el angulo ANGLE. Estoy usando C/C++.
Los angulos usados son los mismos que teniamos en DIV2, los pongo aqui por si acaso.
0 grados, angulo hacia la derecha
+90 grados, angulo hacia arriba
+180 grados, angulo hacia la izquierda
+270 grados, angulo hacia abajo
estos angulos pueden tener valores negativos:
-90 grados, angulo hacia abajo
-180 grados, angulo hacia la derecha
... etc ...
El algoritmo para calcular en angulo es este, entity_id1 es el objeto origen y entity_id2 el objeto remoto.
double PI_detail;
int x1, y1, x2, y2;
float angulo;
PI_detail=3.141592;
x1=entity_id1->x;
y1=entity_id1->y;
x2=entity_id2->x;
y2=entity_id2->y;
angulo=atan2(x1 - x2, y1 - y2) * 180 / PI_detail;
if (angulo<0) { angulo += 360; }
Y luego tengo el algoritmo para hacer avanzar X pixels un objeto, que me ha dado dos sorpresas. La primera es que no puedo hacer avanzar el objeto 1 pixel porque no se mueve, deben ser como minimo 2. La segunda es que si la hago avanzar con angulo 0, y por tanto a la derecha, el movimiento es correcto, pero con un angulo de 90 grados (deberia ir hacia arriba), el objeto se mueve en diagonal abajo y a la izquierda.
El algoritmo de avance es este:
float radian;
float angulo;
angulo=entity_id->angle;
radian=(float)(3.1415926535897931/180)*angulo; // Pasamos el angulo a radianes.
entity_id->x=entity_id->x+(distance*cos(radian));
entity_id->y=entity_id->y+(distance*sin(radian));
Por ultimo, decir que no es imprescindible que se use el mismo sistema de angulos que div2 si es mejor usar otro sistema de angulos.
Supongo que te refieres a esto:
(http://i280.photobucket.com/albums/kk177/The_Dragon_Ladis/Trigo.png)
Si el angulo que quieres es ese, simplemente será
arctan( ( B.x - A.x ) / ( B.y - A.y ) )
Por la forma que lo planteas, creo que es ese angulo.
Lo malo es que esta formula atan2((x2-x1), (y2-y1)) no me da valores correctos. En este momento estoy ejecutando el ejemplo y donde deberia ponerme +45 grados me pone 2.18 grados. Donde deberia marcarme 0 grados me pone 1.57 grados.
En cambio esta formula angulo=atan2((x2-x1), (y2-y1)) * 180 / PI_detail me da valores CASI correctos. Y digo CASI porque me da 0 grados hacia abajo y 90 grados a la derecha. Teoria: ¿sera algo del sistema de coordenadas?
Pues tiene toda la pinta. Revisa que el eje y sea el vertical y el x el horizontal. En algunos sistemas de coordenadas están cambiados o están implementados invertidos.
La función te da el valor en radianes. Por eso que la primera no te devuelve los valores que tu esperabas. Fijate en esta regla de tres:
Pi -> 180º
X -> Grados
Donde X es el valor devuelto por la función y Grados es su equivalencia en grados.
Grados = (X * 180) / Pi
Es la misma conversión que estás haciendo en tu segunda ecuación, y por eso los valores se parecen más a lo que esperas. Te lo explico para que sepas de donde viene y sepas el porqué :D
Pd: ¿Para cuando la función de escribir fórmulas en LaTeX en el foro? xD
Veamos, he conseguido desarrollar un sistema que parece funcionar
El eje X es horizontal y es positivo hacia la derecha
El eje Y es vertical y es positivo hacia abajo
Los 0 grados estan en el eje X positivo y crecen en sentido horario
x=0
y=0
distancia=100
angulo=80
Esto nos pone un objeto en las coordenadas X e Y indicadas, que avanzara 100 pixels con un angulo de 80 grados. Teniendo en cuenta como van los angulos, eso indica que va hacia abajo casi en linea recta, un poco a la derecha del eje Y positivo.
Finales teoricos:
x=0+100=100
y=0+100=100
Teniendo en cuenta solamente las coordenadas X e Y y la distancia, las coordenadas destino quedarian asi.
Lado X:
100 -> 100%
X -> 10 grados
X= 100*10/100=1000/100=10
x=0+10=10
Si avanzamos un 100%, recorremos 100 pixels.
El lado opuesto del angulo tiene 10 grados (recordemos que tenemos un giro de 80 grados, 90-80=10) y tenemos que calcular los pixels correspondientes.
Haciendo una regla de tres, nos da que tenemos una "ganancia" de 10 pixels.
Lado Y:
100 -> 100%
Y -> 80 grados
y=100*80/100=8000/100=80
y=0+80=80
Muy parecido a lo de antes.
Si avanzamos un 100%, recorremos 100 pixels.
El lado opuesto del angulo tiene ahora 80 grados (90-10).
Hacemos regla de tres y sale una ganancia en Y de 80 pixels
Coordenadas finales
x=0+10=10
y=0+80=80
A la coordenada X original (0) le sumamos la "ganancia" en X (10).
Hacemos lo mismo con la coordenada Y.
Lo que me tiene un tanto escamado es que 10+80 no suman 100 (la distancia que buscamos recorrer). Creo que eso indica que este metodo puede ser valido pero que falta pulirlo de alguna forma.
Es normal que la distancia no sea de 100. Primero porque 10 + 80 es 90, y lo segundo porque para calcular la distancia no se suma lo que mueves en x e y, sino tal que así:
(http://i280.photobucket.com/albums/kk177/The_Dragon_Ladis/Trigoagain.png)
Y la distancia d entre el punto Inicial y el Final sería (código en Mathematica, por si te sirve :P):
f[x_, y_] := N[Sqrt[(x^2) + (y^2) ]];
En tu caso concreto para x=10 e y=80 el resultado sería 80.6226.
El cálculo para dos puntos cualesquiera (ya que en el ejemplo suponemos que calculamos la distancia desde el origen de coordenadas) sería aplicando este calculo a la diferencia entre las coordenadas de cada punto.
Sqrt[(x1 - x2)^2 + (y1 - y2)^2]
Espero que sea eso lo que preguntas.
Creo que tienes un cacao del bueno :P
¿He entendido reglas de tres entre angulos y distancias?
* Para avanzar con un angulo Alfa y una velocidad V lo mas sencilo es:
1. Obtener un vector director que tenga siga la direccion Alfa:
D.X = Cos(Alfa);
D.Y = Sen(Alfa);
2. Este vector es unitario, su modulo es 1, mide 1 de longitud,... asi que si queremos avanzar con una velocidad V (pix / segundo) solo hay que multiplicarlo por V
D = D * V;
Lo he puesto usando Velocidad porque es lo mas logico para un juego... pej una nave para llegar de un punto a otro necesita un tiempo y pasar por varias posiciones.
3. Si sumamos D al punto inicial nos da un nuevo punto, equivalente a la distancia recorrida en 1 seg, si solo quieres recorrer un 10% de ese segundo, multiplicalo por 0.1f
D = D * 0.1f;
4. Lo sumas al punto inicial y tienes el punto que querias....
* Para calcular un angulo con dos puntos, A y B:
1. Se calcula el vector director: V = B-A;
2. El angulo se obtiene mediante la Arcotangente: Alfa = Atan2(V.Y, V.X);