Comment trouver l'angle entre deux vecteurs?

9

J'ai 3 points sur mon écran:

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

J'ai tracé quelques lignes pour que vous puissiez voir les vecteurs.

Je veux pouvoir obtenir l'angle entre a et b. J'ai essayé, mais cela ne fonctionne pas, est-ce que quelqu'un sait ce que je fais 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 réponse que j'obtiens habituellement se situe entre 0 et 1. Comment puis-je résoudre ce problème afin d'obtenir l'angle en degrés?

maffo
la source

Réponses:

16

Vous recherchez le merveilleux 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);

Normalement, il est utilisé comme atan2(y,x)mais puisque vous recherchez l'angle avec la ligne verticale, vous devez utiliser à la atan2(-x,y)place.

sam hocevar
la source
+1 pour la façon dont vous faites pivoter le cadre de référence de 90 degrés.
Steve H
@PoiXen désolé, j'avais confondu v1 et v2 dans la formule; Je l'ai maintenant corrigé mais cela a-t-il vraiment fonctionné pour vous la première fois?
sam hocevar
2

Je vois que vous utilisez un produit scalaire, essayez invcos (valeur), cela pourrait faire la chose (mais pas sûr).

Sinon, faites-le simplement de la manière «régulière» avec atan2 (dy / dx):

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