Como encontro o ângulo entre dois vetores?

9

Eu tenho 3 pontos na minha tela:

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     |
|______._______|

Eu desenhei algumas linhas para que você possa ver os vetores.

Eu quero ser capaz de obter o ângulo entre a e b. Eu tentei isso, mas não funciona, alguém sabe o que estou fazendo de errado ?:

//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));

A resposta que normalmente recebo é entre 0 e 1. Como faço para corrigir isso para obter o ângulo em graus?

maffo
fonte

Respostas:

16

Você está procurando o maravilhoso 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 é usado como, atan2(y,x)mas como você está procurando o ângulo com a linha vertical, é necessário usá-lo atan2(-x,y).

sam hocevar
fonte
+1 na maneira como você gira o quadro de referência 90 graus.
27512 Steve
@ PoiXen desculpe, eu tinha confundido v1 e v2 na fórmula; Agora eu consertei, mas realmente funcionou para você na primeira vez?
Sam Hocevar
2

Vejo que você usa o produto escalar, tente invcos (valor) que pode fazer a coisa (mas não tenho certeza).

Caso contrário, faça da maneira 'regular' com atan2 (dy / dx):

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