Hãy cẩn thận sử dụng atan2 để tránh các vấn đề về góc phần tư và chia cho số không. Đó là những gì nó có cho.
float getAngle(CGPoint ptA, CGPoint ptOrigin, CGPoint ptB)
{
CGPoint A = makeVec(ptOrigin, ptA);
CGPoint B = makeVec(ptOrigin, ptB);
// angle with +ve x-axis, in the range (−π, π]
float thetaA = atan2(A.x, A.y);
float thetaB = atan2(B.x, B.y);
float thetaAB = thetaB - thetaA;
// get in range (−π, π]
while (thetaAB <= - M_PI)
thetaAB += 2 * M_PI;
while (thetaAB > M_PI)
thetaAB -= 2 * M_PI;
return thetaAB;
}
Tuy nhiên, nếu bạn không quan tâm đến dù đó là một ve hoặc góc-ve, chỉ cần sử dụng quy tắc chấm sản phẩm (ít CPU load):
float dotProduct(CGPoint p1, CGPoint p2) { return p1.x * p2.x + p1.y * p2.y; }
float getAngle(CGPoint A, CGPoint O, CGPoint B)
{
CGPoint U = makeVec(O, A);
CGPoint V = makeVec(O, B);
float magU = vecGetMag(U);
float magV = vecGetMag(V);
float magUmagV = magU * magV; assert (ABS(magUmagV) > 0.00001);
// U.V = |U| |V| cos t
float cosT = dotProduct(U, V)/magUmagV;
float theta = acos(cosT);
return theta;
}
Lưu ý rằng trong cả hai đang ở trên, nếu một (hoặc cả hai) vectơ ở gần 0 thì điều này sẽ thất bại. Vì vậy, bạn có thể muốn bẫy bằng cách nào đó.
Nguồn
2010-09-28 11:51:40
Bạn có thể giải thích thêm một chút không? Đây có phải là không gian 2D hoặc 3D, bạn có thể đưa ra một ví dụ về mã và ma trận của bạn trông như thế nào không? Các ma trận này có lưu trữ dữ liệu luân phiên (có lẽ nó phải là một quaternion sau đó) hay là chúng mô tả các phép biến đổi? –
http://en.wikipedia.org/wiki/Slope_formula? – Ross
Cảm ơn ross, tôi hiện đang cố gắng đưa câu trả lời vào thực tế. Sẽ cho bạn biết làm thế nào tôi nhận được trong một giây ... –