ベクトル間の時計回りの角度を効率的に計算する
従来、2 つのベクトル間の角度を計算するには、内積を利用して内角を決定する必要がありました。 0 ~ 180 度の範囲。ただし、このアプローチでは、角度とその補数の間の適切な結果を決定する際に課題が生じます。時計回りの角度を計算するためのより直接的な方法はありますか?2D ケース
内積が角度の余弦にどのように関係するのと同様に、行列式はその正弦に比例します。この関係を組み込むことで、次のように角度を計算できます。dot = x1 * x2 + y1 * y2 # Dot product between [x1, y1] and [x2, y2] det = x1 * y2 - y1 * x2 # Determinant angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)
3D の場合
3 次元では、任意のベクトルが独自の軸を定義します。両方に垂直な回転。この軸には固定された向きがないため、回転角度の方向を一意に決定することはできません。一般的な規則は、正の角度を割り当て、この規則に合わせて軸を揃えることです。このコンテキストでは、角度の計算には正規化されたベクトルのドット積で十分です。dot = x1 * x2 + y1 * y2 + z1 * z2 # Between [x1, y1, z1] and [x2, y2, z2] lenSq1 = x1 * x1 + y1 * y1 + z1 * z1 lenSq2 = x2 * x2 + y2 * y2 + z2 * z2 angle = acos(dot / sqrt(lenSq1 * lenSq2))
3D に埋め込まれた平面
既知の法線を持つ平面内に拘束されたベクトルの場合ベクトル n については、考慮すべき特定のケースがあります。回転軸は n と一致し、n の向きによって軸の向きが固定されます。このシナリオでは、行列式に n を含めるように上記の 2D 計算を変更し、それを 3x3 行列に変換できます。dot = x1 * x2 + y1 * y2 + z1 * z2 det = x1 * y2 * zn + x2 * yn * z1 + xn * y1 * z2 - z1 * y2 * xn - z2 * yn * x1 - zn * y1 * x2 angle = atan2(det, dot)
det = n · (v1 × v2)
範囲 0 – 360°
ほとんどの atan2 実装は、範囲内の角度を返します。ラジアン単位の [-π, π] または度単位の [-180°, 180°]。 [0, 2π] または [0°, 360°] 以内の正の角度を取得するには、次の変換を適用できます。dot = x1 * x2 + y1 * y2 # Dot product between [x1, y1] and [x2, y2] det = x1 * y2 - y1 * x2 # Determinant angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)
代わりに、次の式は大文字と小文字の区別を回避します。
dot = x1 * x2 + y1 * y2 + z1 * z2 # Between [x1, y1, z1] and [x2, y2, z2] lenSq1 = x1 * x1 + y1 * y1 + z1 * z1 lenSq2 = x2 * x2 + y2 * y2 + z2 * z2 angle = acos(dot / sqrt(lenSq1 * lenSq2))
この修正手法は、この特定の問題に限定されず、atan2 が関係するあらゆるシナリオに適用できます。
以上が2D 空間と 3D 空間の両方で 2 つのベクトル間の時計回りの角度を効率的に計算するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。