想象一下,在2d空间中有两个点,并且需要将这些点中的一个旋转X度,而另一个点作为中心。如何旋转某个点的顶点?
float distX = Math.abs(centerX -point2X);
float distY = Math.abs(centerY -point2Y);
float dist = FloatMath.sqrt(distX*distX + distY*distY);
到目前为止,我只是找到两点之间的距离......任何想法,我应该从哪里去?
想象一下,在2d空间中有两个点,并且需要将这些点中的一个旋转X度,而另一个点作为中心。如何旋转某个点的顶点?
float distX = Math.abs(centerX -point2X);
float distY = Math.abs(centerY -point2Y);
float dist = FloatMath.sqrt(distX*distX + distY*distY);
到目前为止,我只是找到两点之间的距离......任何想法,我应该从哪里去?
最简单的方法是组成三个转变:
当你工作出这一切,你结束了以下转变:
newX = centerX + (point2x-centerX)*Math.cos(x) - (point2y-centerY)*Math.sin(x);
newY = centerY + (point2x-centerX)*Math.sin(x) + (point2y-centerY)*Math.cos(x);
注意,这使得假设角度x
为负顺时针旋转(所谓standard or right-hand orientation的坐标系)。如果情况并非如此,那么您需要对涉及sin(x)
的条款进行反向标记。
听起来像一个OpenGL答案 –
@CoreyOgburn - 这是一个基本的平面几何的答案。我很久以前就知道这是一个OpenGL :) –
当然,你需要考虑到顺时针角度? – mathematician1975
翻译 “1” 为0,0
旋转
X = SIN(角)* R; y = cos(角度)* r;
翻译回
不准确。 OP想要围绕特定点旋转。正如@Ted Hopp所说,必须对原点进行翻译,应用旋转,然后再翻译成原始位置。 (没有翻译,旋转将在屏幕的0,0附近) – giorashc
公平地说,OP确实张贴了一张巨大的图片,指出原点的点1。 –
如您所知,要旋转某个特定点周围的东西,您可以将该点转换为“零”,旋转,然后将其转回... – Tutankhamen
你需要一个2-d旋转矩阵http://en.wikipedia.org/wiki/Rotation_matrix
你的新点将
newX = centerX + (cosX * (point2X-centerX) + sinX * (point2Y -centerY))
newY = centerY + (-sinX * (point2X-centerX) + cosX * (point2Y -centerY))
,因为你按顺时针方向旋转,而不是逆时针
谢谢,似乎工作很棒! :) –
假设您正在使用Java G raphics2D API,请尝试此代码 -
Point2D result = new Point2D.Double();
AffineTransform rotation = new AffineTransform();
double angleInRadians = (angle * Math.PI/180);
rotation.rotate(angleInRadians, pivot.getX(), pivot.getY());
rotation.transform(point, result);
return result;
其中pivot是您旋转的点。
Java中还有'Math.toRadians()';-) – Betlista
这是一种在2D中旋转任何其他点的任意点的方法。请注意,在3D中,这可以用作围绕z轴的旋转,因为它不会更改,因此该点的z坐标将被加入。围绕x轴和y轴的3D旋转也可以轻松实现。
该代码是用JavaScript编写的。开头的注释行是该函数的测试集。它们也可以作为使用的一个例子。
//A = new Array(0,0)
//S = new Array(-1,0)
//fi = 90
//alert("rotujBod: " + rotatePoint(A, S, fi))
function rotatePoint(A, S, fi) {
/** IN points A - rotated point, S - centre, fi - angle of rotation (rad)
* points in format [Ax, Ay, Az], angle fi (float)
* OUT point B
*/
r = Math.sqrt((A[0] - S[0])*(A[0] - S[0]) + (A[1] - S[1])*(A[1] - S[1]))
originOfRotation = new Array(S[0] + r, S[1])
if (A[1] < S[1]) {
A2 = new Array(A[0], -1*A[1])
originalAngle = -1*sizeOfAngle(originOfRotation, S, A2)
} else {
originalAngle = sizeOfAngle(originOfRotation, S, A)
}
x = S[0] + r*Math.cos(fi + originalAngle)
y = S[1] + r*Math.sin(fi + originalAngle)
B = new Array(x, y)
return(B)
}
function sizeOfAngle(A, S, B) {
ux = A[0] - S[0]
uy = A[1] - S[1]
vx = B[0] - S[0]
vy = B[1] - S[1]
if((Math.sqrt(ux*ux + uy*uy)*Math.sqrt(vx*vx + vy*vy)) == 0) {return 0}
return Math.acos((ux*vx + uy*vy)/(Math.sqrt(ux*ux + uy*uy)*Math.sqrt(vx*vx + vy*vy)))
}
这里有一个关心旋转方向的版本。右(顺时针)为负,左(逆时针)为正。您可以发送一个点或一个2D矢量,并在此方法中设置其基元(最后一行)以避免为性能分配内存。您可能需要将vector2和mathutils替换为您使用的库或Java的内置点类,并且可以使用math.toradians()而不是mathutils。
/**
* rotates the point around a center and returns the new point
* @param cx x coordinate of the center
* @param cy y coordinate of the center
* @param angle in degrees (sign determines the direction + is counter-clockwise - is clockwise)
* @param px x coordinate of point to rotate
* @param py y coordinate of point to rotate
* */
public static Vector2 rotate_point(float cx,float cy,float angle,float px,float py){
float absangl=Math.abs(angle);
float s = MathUtils.sin(absangl * MathUtils.degreesToRadians);
float c = MathUtils.cos(absangl * MathUtils.degreesToRadians);
// translate point back to origin:
px -= cx;
py -= cy;
// rotate point
float xnew;
float ynew;
if (angle > 0) {
xnew = px * c - py * s;
ynew = px * s + py * c;
}
else {
xnew = px * c + py * s;
ynew = -px * s + py * c;
}
// translate point back:
px = xnew + cx;
py = ynew + cy;
return new Vector2(px, py);
}
请注意,这种方式比您在帖子中尝试的方式具有更多的性能。因为你使用的sqrt代价非常高,所以如果你想知道的话,用这种方法将度数转换为用查找表管理的弧度。因此它具有非常高的性能。
看看这个..它可能有助于清理:http://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions – Sednus