2010-07-02 3 views
14

Est-ce que l'une ou l'autre des approches ci-dessous utilise les bonnes mathématiques pour faire pivoter un point? Si oui, lequel est correct?Trigonométrie appropriée pour faire pivoter un point autour de l'origine

POINT rotate_point(float cx,float cy,float angle,POINT p) 
{ 
    float s = sin(angle); 
    float c = cos(angle); 

    // translate point back to origin: 
    p.x -= cx; 
    p.y -= cy; 

    // Which One Is Correct: 
    // This? 
    float xnew = p.x * c - p.y * s; 
    float ynew = p.x * s + p.y * c; 
    // Or This? 
    float xnew = p.x * c + p.y * s; 
    float ynew = -p.x * s + p.y * c; 

    // translate point back: 
    p.x = xnew + cx; 
    p.y = ynew + cy; 
} 
+10

Je ne Je comprends très bien. Quels sont cx et cy? De plus, vous avez déclaré votre fonction de type POINT, mais elle ne renvoie pas de POINT, ni même rien. –

+1

@Brian Hooper: +1 pour souligner les avantages des noms de variables significatifs;) – Cogwheel

Répondre

22

Cela dépend de la façon dont vous définissez angle. Si elle est mesurée dans le sens antihoraire (qui est la convention mathématique), la rotation correcte est votre première:

// This? 
float xnew = p.x * c - p.y * s; 
float ynew = p.x * s + p.y * c; 

Mais si elle est mesurée dans le sens horaire, la seconde est correcte:

// Or This? 
float xnew = p.x * c + p.y * s; 
float ynew = -p.x * s + p.y * c; 
27

From Wikipedia

Pour effectuer une rotation à l'aide des matrices du point (x, y) pour être mis en rotation est écrit comme un vecteur, puis multiplié par une matrice calculée à partir de l'angle, θ, comme suit:

https://upload.wikimedia.org/math/0/e/d/0ed0d28652a45d730d096a56e2d0d0a3.png

où (x ', y') sont les coordonnées du point après rotation, et les formules de x 'et y' peut être vu pour être

alt text

+0

N'oubliez pas que si vous travaillez dans un espace de coordonnées d'écran typique, votre axe y sera inversé à partir de la norme mathématique (vers le bas est + y, up est -y) et vous devrez en tenir compte. –

1

Ceci est extrait de ma propre bibliothèque vectoriel ..

//---------------------------------------------------------------------------------- 
// Returns clockwise-rotated vector, using given angle and centered at vector 
//---------------------------------------------------------------------------------- 
CVector2D CVector2D::RotateVector(float fThetaRadian, const CVector2D& vector) const 
{ 
    // Basically still similar operation with rotation on origin 
    // except we treat given rotation center (vector) as our origin now 
    float fNewX = this->X - vector.X; 
    float fNewY = this->Y - vector.Y; 

    CVector2D vectorRes( cosf(fThetaRadian)* fNewX - sinf(fThetaRadian)* fNewY, 
          sinf(fThetaRadian)* fNewX + cosf(fThetaRadian)* fNewY); 
    vectorRes += vector; 
    return vectorRes; 
} 
+2

Vous pouvez enregistrer les résultats 'cosf' et' sinf' dans les variables pour utiliser la moitié des appels de fonction trig. :) –

+0

bonne prise ..... – YeenFei

Questions connexes