想象一下,在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