Bagaimana cara menemukan sudut antara dua vektor?

9

Saya memiliki 3 poin di layar saya:

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

Saya telah menggambar beberapa garis sehingga Anda dapat melihat vektor.

Saya ingin bisa mendapatkan sudut antara a dan b. Saya sudah mencoba ini, tetapi tidak berhasil, apakah ada yang tahu apa yang saya lakukan salah ?:

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

Jawaban yang biasanya saya dapatkan adalah antara 0 dan 1. Bagaimana cara memperbaikinya sehingga saya mendapatkan sudut dalam derajat?

maffo
sumber

Jawaban:

16

Anda mencari atan2 yang menakjubkan .

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

Biasanya digunakan sebagai atan2(y,x)tetapi karena Anda mencari sudut dengan garis vertikal, Anda harus menggunakannya atan2(-x,y).

sam hocevar
sumber
+1 untuk cara Anda memutar kerangka referensi 90 derajat.
Steve H
@PoiXen maaf, saya bingung v1 dan v2 dalam rumus; Saya sekarang memperbaikinya tetapi apakah itu benar-benar bekerja untuk Anda pertama kali?
sam hocevar
2

Saya melihat Anda menggunakan produk titik, coba invcos (nilai) mungkin melakukan hal itu (tetapi tidak yakin).

Kalau tidak, lakukan saja dengan cara 'biasa' dengan atan2 (dy / dx):

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