LlRotBetween/ja

From Second Life Wiki
Jump to navigation Jump to search

要約

関数: rotation llRotBetween( vector start, vector end );

start の方向と end の方向の間の最も短くなる回転を rotation で返します。

• vector start
• vector end

仕様

startend は原点 <0.0, 0.0, 0.0> からの相対的な方向です。異なる座標系を使用している場合、入力ベクトルからその座標系の原点を引き算しましょう。

警告

  • startend が両方同じ大きさで、且つ、両方とも大きさが 0 でない場合のみ、 start * llRotBetween(start, end) == end となります。 (回避策は 注意点 を参照して下さい。)
    • これはもちろん浮動小数点数の精度誤差を無視しています。
  • 回転はそれぞれの軸について、-PI から +PI までです。
All Issues ~ Search JIRA for related Bugs

サンプル

<lsl>llRotBetween(<1.0, 0.0, 0.0>, <0.0, -1.0, 0.0>) // <0.00000, 0.00000, -0.70711, 0.70711> を返します。 (Z 軸について -90° ということ)

llRotBetween(<0.0, 0.0, 0.0>, <0.0, -1.0, 0.0>) // <0.00000, 0.00000, 0.00000, 1.00000> を返します。 (全ての軸について角度 0 ということ)

// <0.0, 0.0, 0.0> は方向を与えないからです。</lsl>

便利なスニペット

この関数は四元数の大きさを調整し、どれかの大きさが 0 でない限りは start * llRotBetween(start, end) == end が成り立つようにします。同じ大きさでなくてもよいです。 <lsl>rotation RotBetween(vector start, vector end) //四元数の大きさを調整し、 (start * return == end) となるようにします {//Authors note: I have never had a use for this but it's good to know how to do it if I did.

   rotation rot = llRotBetween(start, end);
   if(start)
   {
       if(end)
       {
           float d = llSqrt(llVecMag(end) / llVecMag(start));
           return <rot.x * d, rot.y * d, rot.z * d, rot.s * d>;
       }
   }
   return rot;

}//Strife Onizuka</lsl>

注意点

ほぼ真反対を向くベクトル同士では、間違った結果が返ることもあります。 <lsl> // 最初のベクトルは真北にあり、 2 番目のベクトルは「ほとんど」真南を向いています。 rotation lRotation = llRotBetween( <0., 1., 0.>, <-0.001, -.1, 0.> ); llSay(0, lRotation ); // 結果は <1.00000, 0.00000, 0.00000, 0.00000> となります。 </lsl>

関連項目

関数

•  llAngleBetween

特記事項

<lsl>//SL のソースコードにだいたいならっています rotation llRotBetween(vector start, vector end) {

   vector v1 = llVecNorm(start);
   vector v2 = llVecNorm(end);
   float dot = v1 * v2;
   vector axis = v1 % v2;
   if (dot < -0.9999999) {
       // 180° かそのあたり
       vector ortho_axis = llVecNorm(<1.f, 0.f, 0.f> - (sn * (sn.x / (sn * sn))));
       if (ortho_axis)
           return < ortho_axis.x, ortho_axis.y, ortho_axis.z, 0.f>;
       return <0.0, 0.0, 1.0, 0.0>;
   }
   else if(dot > 0.9999999) {
       //平行
       return ZERO_ROTATION;
   }
   dot = dot + 1.0;
   float m = 1 / llSqrt((axis * axis) + (dot * dot));
   return <axis.x * m, axis.y * m, axis.z * m, dot * m>;

}</lsl>

All Issues

~ Search JIRA for related Issues
   llRotBetween sometimes gives erroneous results.

ソース

Signature

function rotation llRotBetween( vector start, vector end );
この翻訳は 原文 と比べて古いですか?間違いがありますか?読みにくいですか?みんなで 修正 していきましょう! (手順はこちら)
この項目はあなたにとって参考にならない項目ですか?もしかしたらLSL Wikiの関連した項目が参考になるかもしれません。