web-dev-qa-db-ja.com

長方形の点から回転角を計算する方法は?

私は4つのポイントを持っています1234長方形を閉じます。

ポイントは次のように配列になっています:x1y1x2y2x3y3x4y4

私が抱えている問題は、長方形をある角度で回転できることです。

元の点(灰色の輪郭)と角度を計算するにはどうすればよいですか?

enter image description here

この効果をjavascript + css3-transformで再現しようとしているので、最初に直線の寸法を知ってから、cssで回転する必要があります。

ポイントを比較することで、長方形がまっすぐかどうかがわかります。 y1==y2

if(x1==x4 && x2==x3 && y1==y2 && y4==y3){

    rectangle.style.top = y1;
    rectangle.style.left = x1;
    rectangle.style.width = x2-x1;
    rectangle.style.height = y4-y1;
    rectangle.style.transform = "rotate(?deg)";

}
22
Vitim.us

同じ側​​の任意の座標ペアを使用して、回転角を計算できます。数学的な角度は通常、+ ve X軸の長さで0を想定し、反時計回りに回転することで増加します(したがって、+ ve Y軸に沿って90°、-ve X軸は180°など)。

また、javascript三角関数は、CSS変換で使用する前に度に変換する必要があるラジアン単位の値を返します。

形状が90°を超えて回転しない場合、寿命はかなり単純であり、直角三角形の接線比を使用できます。

tan(angle) = length of opposite side / length of adjacent side

OPの場合、使用するのに最適なコーナーは1と4であるため、回転は第1象限で時計回りに維持されます( ドラフトCSS3仕様 に従って)。 JavaScriptの用語で:

var rotationRadians = Math.atan((x1 - x4) / (y1 - y4));

度に変換するには:

var RAD2DEG = 180 / Math.PI;
var rotationDegrees = rotationRadians * RAD2DEG;

回転が90°を超える場合は、角度を調整する必要があります。例えば角度が90°より大きく180°未満の場合、上記の結果が得られ、180°を追加する必要があります。

  rotationDegrees += 180;

また、ページの寸法を使用している場合、y座標はページを下に行くにつれて増加します。これは通常の数学的な意味とは逆であるため、上記のy1 - y4の意味を逆にする必要があります。

編集

OP内のポイントの方向に基づいて、以下は長方形の中心と時計回りの回転を度単位で返す一般的な関数です。必要なのはこれだけですが、必要に応じてコーナーを回転させて「水平」にすることもできます。三角関数を適用して新しいコーナーを計算したり、いくつかの平均を実行したりできます(Ianの回答と同様)。

/*  General case solution for a rectangle
 *
 *  Given coordinages of [x1, y1, x2, y2, x3, y3, x4, y4]
 *  where the corners are:
 *            top left    : x1, y1
 *            top right   : x2, y2
 *            bottom right: x3, y3
 *            bottom left : x4, y4
 *
 *  The centre is the average top left and bottom right coords:
 *  center: (x1 + x3) / 2 and (y1 + y3) / 2
 *
 *  Clockwise rotation: Math.atan((x1 - x4)/(y1 - y4)) with
 *  adjustment for the quadrant the angle is in.
 *
 *  Note that if using page coordinates, y is +ve down the page which
 *  is the reverse of the mathematic sense so y page coordinages
 *  should be multiplied by -1 before being given to the function.
 *  (e.g. a page y of 400 should be -400).
 */
function getRotation(coords) {
    // Get center as average of top left and bottom right
    var center = [(coords[0] + coords[4]) / 2,
                  (coords[1] + coords[5]) / 2];

    // Get differences top left minus bottom left
    var diffs = [coords[0] - coords[6], coords[1] - coords[7]];

    // Get rotation in degrees
    var rotation = Math.atan(diffs[0]/diffs[1]) * 180 / Math.PI;

    // Adjust for 2nd & 3rd quadrants, i.e. diff y is -ve.
    if (diffs[1] < 0) {
        rotation += 180;

    // Adjust for 4th quadrant
    // i.e. diff x is -ve, diff y is +ve
    } else if (diffs[0] < 0) {
        rotation += 360;
    }
    // return array of [[centerX, centerY], rotation];
    return [center, rotation];
}
19
RobG

長方形の中心は、2つの反対側の角の間にあります。

cx = (x1 + x3) / 2
cy = (y1 + y3) / 2

長方形のサイズは、2点間の距離です。

w = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2))
h = sqrt(pow(x3-x2, 2) + pow(y3-y2, 2))

灰色の長方形の角は、中心とサイズから計算できます(例:左上の角)。

x = cx - w / 2
y = cy - h / 2

角度は、正方形の一辺の逆正接です。

a = arctan2(y4 - y1, x4 - x1)

(どの角度が返されるのか、またはその問題にどの角度が期待されるのか正確にはわからないので、少しテストする必要があります。)

9
Guffa