web-dev-qa-db-ja.com

JavaScriptで2Dで回転を計算する方法

私はあまり馴染みのない三角法ですが、2Dで回転するポイントは2つしかありません。

                    *nx, ny
               .     -
          .           -
     .  angle          -
*cx,cy.................*x,y

cx、cy =回転中心
x、y =現在のx、y
nx、ny =新しい座標

特定の角度で新しいポイントを計算する方法は?

32
Digerkam
_function rotate(cx, cy, x, y, angle) {
    var radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return [nx, ny];
}
_

最初の2つのパラメータは、中心点(2番目の点が回転する原点)のX座標とY座標です。次の2つのパラメーターは、回転するポイントの座標です。最後のパラメーターは、度単位の角度です。

例として、ポイント(2、1)を取り、ポイント(1、1)を中心に時計回りに90度回転させます。

_rotate(1, 1, 2, 1, 90);
// > [1, 0]
_

この関数に関する3つの注意事項:

  1. 時計回りの回転では、最後のパラメーターangleは正でなければなりません。反時計回りの回転(指定した図のように)の場合、負の値でなければなりません。

  2. 座標が整数であるポイントを生成する引数を指定した場合でも、つまり、原点(0、0)を中心にポイント(5、0)を90度回転すると、(0、-5)が生成されます- -JavaScriptの丸め動作は、どちらの座標も期待される整数にイライラするほど近い値である可能性があることを意味しますが、依然として浮動小数点です。例えば:

    _rotate(0, 0, 5, 0, 90);
    // > [3.061616997868383e-16, -5]
    _

    このため、結果の配列の両方の要素は浮動小数点数として期待されます。必要に応じて、Math.round()Math.ceil()、またはMath.floor()を使用して整数に変換できます。

  3. 最後に、この関数は デカルト座標系 を想定していることに注意してください。つまり、座標平面で「上」に行くほど、Y軸の値が高くなります。 HTML/CSSでは、Y軸が反転します。Y軸の値は、ページを下に移動すると高くなります

82
theftprevention
  1. まず、回転中心を原点に変換します
  2. 新しい座標(nx、ny)を計算します
  3. 元の回転中心に戻す

ステップ1

あなたの新しいポイントは

  1. 中心:(0,0)
  2. ポイント:(x-cx、y-cy)

ステップ2

  1. nx =(x-cx)* cos(theta) y-cy)* sin(theta)
  2. ny =(y-cy)* cos(theta)+(x-cx)* sin(theta)

ステップ3

元の回転中心に戻す:

  1. nx =(x-cx)* cos(theta)-(y-cy)* sin(theta)+ cx
  2. ny =(y-cy)* cos(theta)+(x-cx)* sin(theta)+ cy

より深い説明のために、いくつかの派手な図を使って、私は---(this を見ることをお勧めします。

6
jh314

上記の受け入れられた答えは私にとって正しく機能しません、回転が逆転します、ここで機能しています

/*
 CX @ Origin X  
 CY @ Origin Y
 X  @ Point X to be rotated
 Y  @ Point Y to be rotated  
 anticlock_wise @ to rotate point in clockwise direction or anticlockwise , default clockwise 
 return @ {x,y}  
*/
function rotate(cx, cy, x, y, angle,anticlock_wise = false) {
    if(angle == 0){
        return {x:parseInt(x), y:parseInt(y)};
    }if(anticlock_wise){
        var radians = (Math.PI / 180) * angle;
    }else{
        var radians = (Math.PI / -180) * angle;
    }
    var cos = Math.cos(radians);
    var sin = Math.sin(radians);
    var nx = (cos * (x - cx)) + (sin * (y - cy)) + cx;
    var ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return {x:nx, y:ny};
 }
1
user889030