Tenga cuidado al usar atan2 para evitar problemas de cuadrante y división por cero. Para eso está ahí.
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;
}
Sin embargo, si no se preocupan por si se trata de un + ve o -ve ángulo, sólo tiene que utilizar la regla del producto de punto (menos carga de la 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;
}
Tenga en cuenta que en cualquier código La sección anterior, si uno (o ambos) vectores tienen una longitud cercana a 0, esto va a fallar. Entonces quizás quieras atrapar eso de alguna manera.
¿Puedes explicar un poco más? ¿Esto es en el espacio 2D o 3D, puede dar un ejemplo de código y cómo se ven sus matrices? ¿Están estas matrices almacenando datos de rotación (probablemente debería ser un cuaternión) o están describiendo transformaciones? –
http://en.wikipedia.org/wiki/Slope_formula? – Ross
Gracias Ross, actualmente estoy intentando poner las respuestas en práctica. Te dejaré saber cómo me llevo en un segundo ... –