如何围绕特定原点旋转点?

How to rotate points about a specific origin?

我正在围绕位于对象上的一个点旋转我的对象的顶点,该点不一定是其中心。我非常密切地关注 this tutorial 并让顶点保持相同的比例,即它们创建的形状确实围绕给定点旋转,但是它旋转的量似乎是任意的。我将在代码和屏幕截图中进行解释。我正在使用 SFML,但我会在注释中解释 sf:: 命名空间,它们供需要它的人使用。不管怎样,这是我显示问题的主要文件:

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:使用旋转矩阵,旋转的点保持它们的比例,但是它们旋转的量是完全任意的。任何 suggestions/improvements?

使用 SFML,您首先创建一个转换:

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

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

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

来源:sf::Transform::rotate and sf::Transform::transformPoint.