如何旋转特定原点的点?

时间:2015-03-05 03:25:12

标签: c++ matrix rotation sfml points

我正在努力将对象的顶点围绕位于对象上的点旋转,该点不一定是其中心。我非常仔细地跟着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;

}

此外,这里有截图显示我的意思。对不起,它有点小。左侧显示在程序开始时创建的形状,绿色点是原点。右侧显示旋转for循环后的形状,红色点显示形状实际旋转到的位置(绝对不是10度),而蓝色点是粗略我预期的位置形状在10度左右。

tl; dr:使用旋转矩阵,旋转的点保持其比例,但它们旋转的量完全是任意的。有什么建议/改进吗?

enter image description here

1 个答案:

答案 0 :(得分:2)

使用SFML,首先创建转换:

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

然后将此变换应用于每个顶点的位置:

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

来源:sf::Transform::rotatesf::Transform::transformPoint