¿Cómo encuentro el ángulo entre dos vectores?

9

Tengo 3 puntos en mi pantalla:

a = a point which is (c.x, 0) makes a line pointing straight up
b = a user input touch, can be anywhere on the screen
c = a moving object

       a
_______.________
|      |       |
|      |       | 
|   b  |       |
|  .   |       |
|   \  |       |
|    \ |       | 
|     \|       |
|      | c     |
|______._______|

He dibujado algunas líneas para que puedas ver los vectores.

Quiero poder obtener el ángulo entre a y b. He intentado esto, pero no funciona, ¿alguien sabe lo que estoy haciendo mal ?:

//v1 moving object
float boxX = this.mScene.getLastChild().getX(); 
float boxY = this.mScene.getLastChild().getY();

//v2 user touch
float touchX = pSceneTouchEvent.getX();
float touchY = pSceneTouchEvent.getY();     

//v3 top of screen
float topX = boxX;
final float topY = 0;

float dotProd = (touchX * topX) + (touchY * topY);

float sqrtBox = (touchX * touchX) + (touchY * touchY);
float sqrtTouch = (topX * topX) + (topY * topY);

double totalSqrt = sqrtBox * sqrtTouch;
double theta = Math.acos(dotProd / Math.sqrt(totalSqrt));

La respuesta que generalmente obtengo es entre 0 y 1. ¿Cómo soluciono esto para obtener el ángulo en grados?

maffo
fuente

Respuestas:

16

Estás buscando el maravilloso atan2 .

// v1 moving object
float boxX = this.mScene.getLastChild().getX(); 
float boxY = this.mScene.getLastChild().getY();

// v2 user touch
float touchX = pSceneTouchEvent.getX();
float touchY = pSceneTouchEvent.getY();     

double theta = 180.0 / Math.PI * Math.atan2(boxX - touchX, touchY - boxY);

Normalmente se usa como atan2(y,x)pero, dado que está buscando el ángulo con la línea vertical, debe usarlo atan2(-x,y)en su lugar.

sam hocevar
fuente
+1 por la forma en que está girando el marco de referencia 90 grados.
Steve H
@PoiXen lo siento, había confundido v1 y v2 en la fórmula; Ahora lo arreglé, pero ¿realmente funcionó para ti la primera vez?
sam hocevar
2

Veo que usas un producto punto, prueba invcos (valor), podría hacer lo correcto (pero no estoy seguro).

De lo contrario, hágalo de la manera 'regular' con atan2 (dy / dx):

b=b-c:
angle=atan2(b.y, b.x);
Valmond
fuente