Veillez à utiliser atan2 pour éviter les problèmes de quadrant et la division par zéro. C'est ce qu'il y a là-bas.
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;
}
Cependant, si vous ne se soucient pas que ce soit un + ve ou angle -ve, il suffit d'utiliser la règle de produit scalaire (moins de charge CPU):
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;
}
Notez que dans les deux codes section ci-dessus, si un (ou les deux) vecteurs sont proches de 0, cela va échouer. Donc, vous pourriez vouloir piéger cela en quelque sorte.
Pouvez-vous expliquer un peu plus? Est-ce que c'est dans un espace 2D ou 3D, pouvez-vous donner un exemple de code et à quoi ressemblent vos matrices? Ces matrices stockent-elles des données de rotation (il devrait probablement s'agir alors d'un quaternion) ou décrivent-elles des transformations? –
http://en.wikipedia.org/wiki/Slope_formula? – Ross
Merci ross, j'essaie actuellement de mettre les réponses en pratique. Je vais vous faire savoir comment je m'entends en une seconde ... –