角度と寸法を指定して、長方形の周囲に沿った座標を見つけます
-
06-07-2019 - |
質問
特定のピボット(または原点)を中心にアイコンが回転するスクリプトを書いています。楕円の周りでアイコンを回転させるためにこの作業を行うことができましたが、特定の幅、高さ、原点の長方形の周囲を移動させたいと思います。
現在のコードでは、各角度整数をキーとして配列にすべての座標を格納しているため、このようにしています。このコードを再利用すると、作業がはるかに簡単になります。
100x150の長方形の例を教えていただければ、それは素晴らしいことです。
編集:明確にするために、周りを回転させるとは、シェイプの周囲を移動する(または周回する)ことを意味します。
解決
長方形のサイズがわかっていて、角度間隔全体を4つの異なる領域に分割する必要があるため、長方形の中心からの光線が長方形の右、上、左、または下と交差するかどうかがわかります。
角度が次の場合:-atan(d / w)<!> lt;アルファ<!> lt; atan(d / w)光線は長方形の右側と交差します。長方形の中心から右側へのx変位がd / 2であることがわかっているため、変位dyをd / 2で除算するとtan(alfa)になるため、
dy = d / 2 * tan(alfa)
これを他の3つの角度間隔と同様に処理します。
わかりました、ここに行きます。幅w、深さdの長方形があります。中央に中心点cpがあります。角度アルファのさまざまな値について、Pを計算すると仮定します。
四角形を4つの異なる領域、または角度間隔(1〜4)に分割しました。上記の間隔は、最初の右側です。これがあなたにとって意味があることを願っています。
まず角度間隔を計算する必要があり、これらはwとdによって完全に決定されます。アルファの値に応じて、Pを計算します。つまり、<!> quot; ray <! > quot; CPからPへは、長方形の上部、下部、右側または左側と交差します。
乾杯
他のヒント
これはPebbleスマートウォッチで動作するように作成および検証されましたが、擬似コードに変更されました。
struct GPoint {
int x;
int y;
}
// Return point on rectangle edge. Rectangle is centered on (0,0) and has a width of w and height of h
GPoint getPointOnRect(int angle, int w, int h) {
var sine = sin(angle), cosine = cos(angle); // Calculate once and store, to make quicker and cleaner
var dy = sin>0 ? h/2 : h/-2; // Distance to top or bottom edge (from center)
var dx = cos>0 ? w/2 : w/-2; // Distance to left or right edge (from center)
if(abs(dx*sine) < abs(dy*cosine)) { // if (distance to vertical line) < (distance to horizontal line)
dy = (dx * sine) / cosine; // calculate distance to vertical line
} else { // else: (distance to top or bottom edge) < (distance to left or right edge)
dx = (dy * cosine) / sine; // move to top or bottom line
}
return GPoint(dx, dy); // Return point on rectangle edge
}
Use:
rectangle_width = 100;
rectangle_height = 150;
rectangle_center_x = 300;
rectangle_center_y = 300;
draw_rect(rectangle_center_x - (rectangle_width/2), rectangle_center_y - (rectangle_center_h/2), rectangle_width, rectangle_height);
GPoint point = getPointOnRect(angle, rectangle_width, rectangle_height);
point.x += rectangle_center_x;
point.y += rectangle_center_y;
draw_line(rectangle_center_x, rectangle_center_y, point.x, point.y);
角度をパラメーターとして使用してこれを行う簡単な方法の1つは、四角形の境界を使用してX値とY値をクリップすることです。つまり、アイコンが円形または楕円形のパスを中心に回転するように位置を計算し、これを適用します。
(X軸の長さがXAxis、Y軸の長さがYAxisで、(0,0)を中心とする軸に合わせた長方形を想定):
if (X > XAxis/2)
X = XAxis/2;
if (X < 0 - XAxis/2)
X = 0 - XAxis/2;
if (Y > YAxis/2)
Y = YAxis/2;
if (Y < 0 - YAxis/2)
Y = 0 - YAxis/2;
このアプローチの問題は、角度が完全に正確ではなく、長方形の周囲に沿った速度が一定ではないことです。角を長方形にした楕円をモデリングすると、効果を最小限に抑えることができますが、滑らかで一定速度の<!> quot; orbit、<!> quotを探している場合は、この方法は適切ではありません。
地球が太陽の周りを回転するように回転するという場合(自己回転ではありません...では、長方形の端に沿ってスライドする方法についての質問ですか?)
もしそうなら、これを試してみることができます:
# pseudo coode
for i = 0 to 499
if i < 100: x++
else if i < 250: y--
else if i < 350: x--
else y++
drawTheIcon(x, y)
更新:(下記のコメントをご覧ください)
角度を使用する場合、1行になります
y / x = tan(th) # th is the angle
他の行は水平または垂直であるため単純です。たとえば、x = 50であり、それを上の行に入力してyを取得できます。水平線と垂直線の交点に対してこれを行います(たとえば、角度は60度で、<!> quot; NorthEast <!> quot; ...になります。2つのポイントがあります。次に、最も近いポイント原点は、最初に長方形に当たるものです)。
2D変換マトリックスを使用します。多くの言語(Javaなど)はこれをネイティブにサポートしています(AffineTransformationを参照)。それ以外の場合は、自分でローテーションを実行するルーチンを1回書き、それを適切にデバッグし、永久に使用します。 5つの異なる言語で書かれている必要があります。
簡単に回転できるようになったら、 line-lineを実行して、四角形の位置を見つけます。交差点。 2本の線を交差させて、軌道アイコンの中心を見つけます:
- 希望する角度の回転中心からの光線
- 希望する角度(4つの象限)で区切られた4つの側面の1つ。
長方形と回転中心を持つ紙にスケッチを描きます。まず、座標系の原点を中心に長方形を平行移動します(平行移動パラメーターを覚えておいてください。後で平行移動を逆にする必要があります)。四角形を回転して、辺が座標軸に平行になるようにします(同じ理由)。
原点に既知の角度を持つ三角形ができたので、反対側の長さは既知の長さ(長方形の1辺の長さの半分)になりました。
-三角形を解く
-回転を元に戻します
-翻訳を元に戻す