Question

Dire que j'ai deux vecteurs 2D, l'un pour une position actuelle des objets et l'autre pour que les objets position précédente. Comment puis-je travailler la direction angulaire de Voyage?

Cette image peut aider à comprendre ce que je suis après:

(image) http://files.me.com/james.ingham/crcvmy

Était-ce utile?

La solution

Le vecteur de direction de Voyage sera la différence des deux vecteurs de position,

d = (x1, y1) - (x, y) = (x1 - x, y1 - y)

Maintenant, quand vous demandez l'angle de direction, cela dépend dans quelle direction vous voulez mesurer l'angle contre. Est-ce contre l'axe x? Aller avec la réponse de Radu. Contre un vecteur arbitraire? Voir la réponse justjeff.

Edit: Pour obtenir l'angle contre l'axe y:

tan (theta) = (x1 -x)/(y1 - y)          

la tangente de l'angle est le rapport de la coordonnée x du vecteur de différence à la coordonnée y du vecteur de différence.

theta = arctan[(x1 - x)/(y1 - y)]

Où arctan moyens de tangente inverse. À ne pas confondre avec l'inverse de la tangente, que beaucoup de gens le font, car ils sont tous les deux souvent tan ^ -1 notée. Et assurez-vous de savoir si vous travaillez en degrés ou radians.

Autres conseils

Si vous êtes en C (ou autre langue qui utilise le même jeu de fonction), alors vous êtes probablement pour la fonction atan2(). A partir de votre schéma:

double theta = atan2(x1-x, y1-y);

Cet angle sera de l'axe vertical, comme vous avez marqué, et sera mesurée dans radians (propre unité d'angle de Dieu).

Veillez à utiliser atan2 pour éviter les problèmes de quadrant et division par zéro. C'est ce qu'il est là pour cela.

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 une des sections de code ci-dessus, si un des vecteurs (ou les deux) sont proches de 0 longueur cela va à l'échec. Donc, vous voudrez peut-être piège en quelque sorte.

Toujours pas sûr ce que vous entendez par des matrices de rotation, mais c'est un cas simple d'obtenir un azimut à partir d'un vecteur de direction.

La réponse complexe:

Normalement, vous devez emballer quelques fonctions de conversion / utilitaires avec vos vecteurs 2D: l'un pour convertir X, Y (cartésienne) à Theta, R (Les coordonnées polaires). Vous devez également prendre en charge les opérations de vecteur de base comme l'addition, et soustractions produit scalaire. Votre réponse dans ce cas serait:

 double azimuth  =  (P2 - P1).ToPolarCoordinate().Azimuth;

Où ToPolarCoordinate () et ToCarhtesianCoordinate () sont deux fonctions inverses de commutation d'un type de vecteur à un autre.

Le simple:

 double azimuth = acos ((x2-x1)/sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
 //then do a quadrant resolution based on the +/- sign of (y2-y1) and (x2-x1)
 if (x2-x1)>0 {
   if (y2-y1)<0 {  azimuth = Pi-azimuth; } //quadrant 2
 } else 
 { if (y2-y1)> 0 {  azimuth = 2*Pi-azimuth;} //quadrant 4
    else  { azimuth = Pi + azimuth;} //quadrant 3
 }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top