Wie finde ich den Winkel zwischen zwei Vektoren?

9

Ich habe 3 Punkte auf meinem Bildschirm:

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

Ich habe einige Linien gezeichnet, damit Sie die Vektoren sehen können.

Ich möchte den Winkel zwischen a und b ermitteln können. Ich habe es versucht, aber es funktioniert nicht. Weiß jemand, was ich falsch mache?:

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

Die Antwort, die ich normalerweise bekomme, liegt zwischen 0 und 1. Wie behebe ich das, damit ich den Winkel in Grad erhalte?

maffo
quelle

Antworten:

16

Sie suchen den wundersamen 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);

Normalerweise wird es als verwendet, atan2(y,x)aber da Sie nach dem Winkel mit der vertikalen Linie suchen, müssen Sie atan2(-x,y)stattdessen verwenden.

Sam Hocevar
quelle
+1 für die Art und Weise, wie Sie den Referenzrahmen um 90 Grad drehen.
Steve H
@PoiXen sorry, ich hatte v1 und v2 in der Formel verwechselt; Ich habe es jetzt behoben, aber hat es beim ersten Mal wirklich für Sie funktioniert?
Sam Hocevar
2

Ich sehe, dass Sie Punktprodukt verwenden, versuchen Sie invcos (Wert), es könnte die Sache tun (aber nicht sicher).

Ansonsten mache es einfach 'normal' mit atan2 (dy / dx):

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