如何围绕特定原点旋转点?
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);
我正在围绕位于对象上的一个点旋转我的对象的顶点,该点不一定是其中心。我非常密切地关注 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);