2015-03-05 1 views
0

Je travaille sur la rotation des sommets de mon objet autour d'un point situé sur l'objet qui n'est pas nécessairement son centre. J'ai suivi de très près this tutorial et j'ai obtenu que les sommets conservent leurs mêmes proportions, c'est-à-dire que la forme qu'ils créent ne tourne pas autour du point donné, mais la quantité par laquelle il tourne semble arbitraire. Je vais expliquer dans le code et les captures d'écran. J'utilise SFML, mais je vais expliquer les espaces de noms sf :: dans les commentaires où ils sont utilisés pour ceux qui en ont besoin. Quoi qu'il en soit, voici mon fichier principal qui montre le problème:Comment faire pivoter des points sur une origine spécifique?

int _tmain(int argc, _TCHAR* argv[]){ 
sf::RenderWindow window(sf::VideoMode(500, 500, 32), "Animation"); 

//sf::vertexarray is a list of POINTS on the screen, their position is determined with a sf::vector 
sf::VertexArray vertices; 

//arrange 6 points in a shape 
vertices.setPrimitiveType(sf::PrimitiveType::Points); 
//bottom middle 
vertices.append(sf::Vector2f(200, 200)); 
//left bottom edge 
vertices.append(sf::Vertex(sf::Vector2f(195, 195))); 
//left top edge 
vertices.append(sf::Vertex(sf::Vector2f(195, 175))); 
//top middle 
vertices.append(sf::Vertex(sf::Vector2f(200, 170))); 
//top right corner 
vertices.append(sf::Vertex(sf::Vector2f(205, 175))); 
//bottom right corner 
vertices.append(sf::Vertex(sf::Vector2f(205, 195))); 

//rotation is the shape's rotation... 0 means it's straight up, and it rotates clockwise with positive rotation 
float rotation = 0; 
//used later to pause the program 
bool keypressed = false; 

while(window.isOpen()){ 
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){ 
     window.close(); 
    } 
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){ 
     //this SHOULD rotate the shape by 10 degrees, however it rotates it by like 150-ish 
     //why does this not work as expected? 
     rotation = 10; 
     //this transformation part works fine, it simply moves the points to center them on the origin, rotates them using a rotation matrix, and moves 
     //them back by their offset 
     for(int i = 1; i < vertices.getVertexCount(); i++){ 
      //translate current point so that the origin is centered 
      vertices[i].position -= vertices[0].position; 

      //rotate points 
      //I'm guessing this is the part where the rotation value is screwing up? 
      //because rotation is simply theta in a regular trig function, so the shape should only rotate 10 degrees 
      float newPosX = vertices[i].position.x * cosf(rotation) + vertices[i].position.y * sinf(rotation); 
      float newPosY = -vertices[i].position.x * sinf(rotation) + vertices[i].position.y * cosf(rotation); 

      //translate points back 
      vertices[i].position.x = newPosX + vertices[0].position.x; 
      vertices[i].position.y = newPosY + vertices[0].position.y; 
     } 
     keypressed = true; 
    } 

    //draw 
    window.clear(); 
    window.draw(vertices); 
    window.display(); 
    if(keypressed == true){ 
     //breakpoint here so the points only rotate once 
     system("pause"); 
    } 
} 
return 0; 

}

, voici également les captures d'écran montrant ce que je veux dire. Désolé, c'est un peu petit. Le côté gauche montre la forme créée au début du programme, le point vert étant l'origine. Le côté droit montre la forme après que la rotation pour la boucle est appelée, avec les points rouges montrant où la forme tourne réellement (certainement pas 10 degrés) par rapport aux points bleus, qui sont environ où je m'attendais à la forme à, environ 10 degrés. En utilisant une matrice de rotation, les points en rotation conservent leurs proportions, mais la quantité de rotation est totalement arbitraire. Des suggestions/améliorations?

enter image description here

Répondre

1

Utilisation du SFML, vous créez d'abord une transformation:

sf::Transform rotation; 
rotation.rotate(10, centerOfRotationX, centerOfRotationY); 

Ensuite, vous appliquer cette transformation à la position de chaque sommet:

sf::Vector2f positionAfterRotation = rotation.transformPoint(positionBeforeRotation); 

Sources: sf::Transform::rotate et sf::Transform::transformPoint .

+0

Oh, quelle fonction utile de la bibliothèque. C'est ce que j'ai pour essayer de réinventer la roue. Mais qu'est-ce qui n'allait pas avec mes maths ci-dessus? – jburn7