2015-03-05 4 views
0

Я работаю над поворотом вершин моего объекта вокруг точки, расположенной на объекте, который не обязательно является его центром. Я довольно внимательно следил за this tutorial и получил вершины, чтобы сохранить их одинаковые пропорции, т. Е. Форма, которую они создают, вращается вокруг данной точки, однако количество, на которое оно вращается, кажется произвольным. Я объясню в коде и скриншотах. Я использую SFML, но я объясню sf :: namespaces в комментариях, где они используются для тех, кто в ней нуждается. В любом случае, вот мой главный файл, который показывает проблему:Как повернуть точки относительно определенного происхождения?

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; 

}

Кроме того, вот скриншоты, показывающие, что я имею в виду. Извините, это немного мало. На левой стороне отображается форма, созданная в начале программы, причем зеленая точка является источником. Правая сторона показывает форму после того, как вызывается поворот для петли, причем красные точки показывают, где форма фактически вращается (определенно не на 10 градусов) по сравнению с синими точками, которые примерно, где я ожидал, что фигура будет, около 10 градусов.

tl; dr: Используя вращающуюся матрицу, вращающиеся точки сохраняют свои пропорции, но количество, на которое они вращаются, абсолютно произвольно. Любые предложения/улучшения?

enter image description here

ответ

1

Использование SFML, необходимо сначала создать преобразование:

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

Затем применить это преобразование в положение каждой вершины:

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

Источники: sf::Transform::rotate и sf::Transform::transformPoint ,

+0

О, какая полезная функция библиотеки. Это то, что я пытаюсь изобрести колесо. Но что случилось с моей математикой выше? – jburn7