C++ 围绕另一个点旋转一个点 (2D)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2259476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rotating a point about another point (2D)
提问by jmasterx
I'm trying to make a card game where the cards fan out. Right now to display it Im using the Allegro API which has a function:
我正在尝试制作一个纸牌散开的纸牌游戏。现在使用具有功能的 Allegro API 来显示它:
al_draw_rotated_bitmap(OBJECT_TO_ROTATE,CENTER_X,CENTER_Y,X
,Y,DEGREES_TO_ROTATE_IN_RADIANS);
so with this I can make my fan effect easily. The problem is then knowing which card is under the mouse. To do this I thought of doing a polygon collision test. I'm just not sure how to rotate the 4 points on the card to make up the polygon. I basically need to do the same operation as Allegro.
所以有了这个我可以很容易地制作我的粉丝效果。问题是知道哪张卡在鼠标下面。为此,我想到了进行多边形碰撞测试。我只是不确定如何旋转卡片上的 4 个点来组成多边形。我基本上需要做与 Allegro 相同的操作。
for example, the 4 points of the card are:
比如卡的4点是:
card.x
card.y
card.x + card.width
card.y + card.height
I would need a function like:
我需要一个类似的功能:
POINT rotate_point(float cx,float cy,float angle,POINT p)
{
}
Thanks
谢谢
回答by Nils Pipenbrinck
First subtract the pivot point (cx,cy)
, then rotate it, then add the point again.
首先减去枢轴点(cx,cy)
,然后旋转它,然后再次添加该点。
Untested:
未经测试:
POINT rotate_point(float cx,float cy,float angle,POINT p)
{
float s = sin(angle);
float c = cos(angle);
// translate point back to origin:
p.x -= cx;
p.y -= cy;
// rotate point
float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;
// translate point back:
p.x = xnew + cx;
p.y = ynew + cy;
return p;
}
回答by six face
If you rotate point (px, py)
around point (ox, oy)
by angle theta you'll get:
如果您(px, py)
围绕点(ox, oy)
按角度 theta旋转点,您将得到:
p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
this is an easy way to rotate a point in 2D.
这是一种在 2D 中旋转点的简单方法。
回答by Ziezi
The coordinate system on the screen is left-handed, i.e. the xcoordinate increases from left to right and the ycoordinate increases from top to bottom. The origin, O(0, 0) is at the upper left corner of the screen.
屏幕上的坐标系是左手的,即x坐标从左到右增加,y坐标从上到下增加。原点 O(0, 0) 位于屏幕的左上角。
A clockwiserotation around the originof a point with coordinates (x, y) is given by the following equations:
甲顺时针旋转围绕原点与坐标(x,y)被由下式给定的一个点的:
where (x', y') are the coordinates of the point after rotation and angle theta, the angle of rotation (needs to be in radians, i.e. multiplied by: PI / 180).
其中 (x', y') 是旋转后点的坐标和角度 theta,旋转的角度(需要以弧度表示,即乘以:PI / 180)。
To perform rotation around a point different from the origin O(0,0), let's say point A(a, b) (pivot point). Firstly we translate the point to be rotated, i.e. (x, y) back to the origin, by subtracting the coordinates of the pivot point, (x - a, y - b). Then we perform the rotation and get the new coordinates (x', y') and finally we translate the point back, by adding the coordinates of the pivot point to the new coordinates (x' + a, y' + b).
要围绕与原点 O(0,0) 不同的点执行旋转,假设点 A(a, b)(枢轴点)。首先,我们通过减去枢轴点的坐标 (x - a, y - b) 将要旋转的点,即 (x, y) 平移回原点。然后我们执行旋转并获得新坐标 (x', y'),最后通过将枢轴点的坐标添加到新坐标 (x' + a, y' + b) 将点平移回来。
Following the above description:
按照上面的描述:
a 2D clockwise theta degreesrotation of point (x, y)around point (a, b)is:
点(x, y)围绕点(a, b)的 2D 顺时针theta 度旋转是:
Using your function prototype: (x, y) -> (p.x, p.y); (a, b) -> (cx, cy); theta -> angle:
使用你的函数原型:(x, y) -> (px, py); (a, b) -> (cx, cy); θ -> 角度:
POINT rotate_point(float cx, float cy, float angle, POINT p){
return POINT(cos(angle) * (p.x - cx) - sin(angle) * (p.y - cy) + cx,
sin(angle) * (p.x - cx) + cos(angle) * (p.y - cy) + cy);
}
回答by vinay kumar sahu
float s = sin(angle); // angle is in radians
float c = cos(angle); // angle is in radians
For clockwise rotation :
对于顺时针旋转:
float xnew = p.x * c + p.y * s;
float ynew = -p.x * s + p.y * c;
For counter clockwise rotation :
对于逆时针旋转:
float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;
回答by generic-user
This is the answer by Nils Pipenbrinck, but implemented in c# fiddle.
这是 Nils Pipenbrinck 的答案,但在 c# fiddle 中实现。
https://dotnetfiddle.net/btmjlG
https://dotnetfiddle.net/btmjlG
using System;
public class Program
{
public static void Main()
{
var angle = 180 * Math.PI/180;
Console.WriteLine(rotate_point(0,0,angle,new Point{X=10, Y=10}).Print());
}
static Point rotate_point(double cx, double cy, double angle, Point p)
{
double s = Math.Sin(angle);
double c = Math.Cos(angle);
// translate point back to origin:
p.X -= cx;
p.Y -= cy;
// rotate point
double Xnew = p.X * c - p.Y * s;
double Ynew = p.X * s + p.Y * c;
// translate point back:
p.X = Xnew + cx;
p.Y = Ynew + cy;
return p;
}
class Point
{
public double X;
public double Y;
public string Print(){
return $"{X},{Y}";
}
}
}
Ps: Apparently I can't comment, so I'm obligated to post it as an answer ...
Ps:显然我无法发表评论,所以我有义务将其发布为答案......