[delphi-users:3376] CreateRotationMatrix3Dについて

98 views
Skip to first unread message

dev

unread,
Sep 12, 2013, 5:07:08 AM9/12/13
to delphi...@freeml.com
いつもお世話になっています。devです。

3次元座標を管理するソフトを組む事になり、ネットを徘徊して情報を集めつつ
XE4 + Win7 Pro 64bitにてテストしています。

あるベクトルAを基準にベクトルBをX度回転させるという事で、
RotateVectorというメソッドを使おうと考えました。

Aを基準にBが回転するまでは良いのですが、X度の指定がどうも
上手くいきませんでした。
引数のangleをDegreeにしても、Radianにしても駄目です。

ソースをじっくり追っていくと
CreateRotationMatrixで回転行列を求めているのですが、
その最初のSTEPで
SinCos( DegNormalize( angle ), Sin, Cos );
が呼ばれています。

ふと、思ったのですが。
RotateVectorの引数angleはDegreeを期待していて、
SinCosの第一引数はRadianを期待していると思われるのに、
上手くわたっていないような気がします。

実験で
SinCos( DegNormalize( angle ), Sin, Cos );

SinCos( DegToRad( DegNormalize( angle ) ), Sin, Cos );
に変更すると、思ったような値が取得できました。

これは、ライブラリの不具合でしょうか?

最初に書きましたように、座標とか回転とか行列とか勉強中なので
確信が持てません。

どなたか詳しい方おられますでしょうか?

よろしくお願いします。


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
夫婦でゆったり≪温泉≫箱根・軽井沢・京都などの人気温泉リゾー
トに格安で宿泊できる「体験宿泊」の情報をお届け致します。
■大感謝プラン1:【平日】 ¥500~ 
■大感謝プラン2:【土・祝前日】 ¥1,500~ 
http://ad.freeml.com/cgi-bin/sa.cgi?id=kucrI
------------------------------------------------------[freeml byGMO]--

luxidea

unread,
Sep 17, 2013, 1:52:49 AM9/17/13
to delphi...@freeml.com
これはまさしくバグですね。(^_^;)遅レスですみません。

DegNormalize は入力を 0 <= θ < 360 の範囲へ周期的にマッピングする関数ですが、
おっしゃるとおり SinCos はラジアンを入力とする関数ですし、
どんな値を入れようとも周期的な回転角として解釈されるので、
そもそも予め正規化する意味がない。

もっとも、DegToRad を入れる対処でも構いませんが、
やはり座標変換系はすべてラジアンに統一した方が効率的だと思うので、
ただ単に DegNormalize を削除してしまった方がいいと思います。

 SinCos( angle, Sin, Cos );

ちなみに XE5 では、Types3D にあった座標変換系の関数がゴソッとなくなり、
各構造体のメソッドして統合されました。

・FMX.Types3D @ XE4
 http://docwiki.embarcadero.com/Libraries/XE4/ja/FMX.Types3D
・FMX.Types3D @ XE5
 http://docwiki.embarcadero.com/Libraries/XE5/ja/FMX.Types3D

・System.Types.TMatrix3D @ XE4
 http://docwiki.embarcadero.com/Libraries/XE4/ja/System.Types.TMatrix3D
・System.Types.TMatrix3D @ XE5
 http://docwiki.embarcadero.com/Libraries/XE5/ja/System.Types.TMatrix3D

・System.Types.TVector3D @ XE4
 http://docwiki.embarcadero.com/Libraries/XE4/ja/System.Types.TVector3D
・System.Types.TVector3D @ XE5
 http://docwiki.embarcadero.com/Libraries/XE5/ja/System.Types.TVector3D

RotateVector は Rotate というメソッドになり、バグも直っているようです。

 ▼ System.Types @ XE5

 > function TVector3D.Rotate(const AAxis: TPoint3D; const AAngle: Single): TVector3D;
 > begin
 > Result := Self * TMatrix3D.CreateRotation(AAxis, AAngle);
 > end;

 > class function TMatrix3D.CreateRotation(const AAxis: TPoint3D; const AAngle: Single): TMatrix3D;
 > var
 > NormAxis: TPoint3D;
 > Cosine, Sine, OneMinusCos: Single;
 > begin
 > SinCosSingle(AAngle, Sine, Cosine);
 > OneMinusCos := 1 - Cosine;
 > NormAxis := AAxis.Normalize;
 >
 > Result := Identity;
 > Result.m11 := (OneMinusCos * NormAxis.X * NormAxis.X) + Cosine;
 > Result.m12 := (OneMinusCos * NormAxis.X * NormAxis.Y) - (NormAxis.Z * Sine);
 > Result.m13 := (OneMinusCos * NormAxis.Z * NormAxis.X) + (NormAxis.Y * Sine);
 > Result.m21 := (OneMinusCos * NormAxis.X * NormAxis.Y) + (NormAxis.Z * Sine);
 > Result.m22 := (OneMinusCos * NormAxis.Y * NormAxis.Y) + Cosine;
 > Result.m23 := (OneMinusCos * NormAxis.Y * NormAxis.Z) - (NormAxis.X * Sine);
 > Result.m31 := (OneMinusCos * NormAxis.Z * NormAxis.X) - (NormAxis.Y * Sine);
 > Result.m32 := (OneMinusCos * NormAxis.Y * NormAxis.Z) + (NormAxis.X * Sine);
 > Result.m33 := (OneMinusCos * NormAxis.Z * NormAxis.Z) + Cosine;
 > end;

 > procedure SinCosSingle(const Theta: Single; var Sin, Cos: Single);
 > var
 > {$IF SizeOf(Extended) = 10}
 > S, C: Extended;
 > {$ELSE}
 > S, C: Double;
 > {$ENDIF}
 > begin
 > System.SineCosine(Theta, S, C);
 > Sin := S;
 > Cos := C;
 > end;

+───────────────────────+
│■ 中山雅紀 ( Nakayama Masanori ) │
│・mail: con...@luxidea.net   │
│▽ 慶應義塾大学大学院 理工学研究科 藤代研究室 │
│・site: http://www.fj.ics.keio.ac.jp/
│・mail: naka...@fj.ics.keio.ac.jp
+───────────────────────+

--------------------------------------------------------------------------------
http://ad.freeml.com/cgi-bin/sa.cgi?id=kvgEe
------------------------------------------------------[freeml byGMO]--

dev

unread,
Sep 19, 2013, 9:30:27 AM9/19/13
to delphi...@freeml.com
luxideaさん。すみません、返信遅れました。ちょっと出張続きでして。

私が思っていた事、全て正しかったと認識できました。
書いた通り、ラジアンとデグリーの関係とか、
なんで、0-360に直さなきゃいけないのかなぁ?とか、

あ、あと、
測量とかで使うので、出来ればDouble対応にして欲しかったですね。
全て、自分のユニットにコピーしてDouble対応にしましたけど。

有難うございました。
■大感謝プラン<1>:【平日】 ¥500~ 
■大感謝プラン<2>:【土・祝前日】 ¥1,500~ 
http://ad.freeml.com/cgi-bin/sa.cgi?id=kvG1L
------------------------------------------------------[freeml byGMO]--

luxidea

unread,
Sep 20, 2013, 5:20:09 AM9/20/13
to delphi...@freeml.com
> luxideaさん。すみません、返信遅れました。ちょっと出張続きでして。

いえいえ、お気になさらず。(^ ^)


> 私が思っていた事、全て正しかったと認識できました。
> 書いた通り、ラジアンとデグリーの関係とか、
> なんで、0-360に直さなきゃいけないのかなぁ?とか、

RotationAngle プロパティなども強制的に正規化されちゃてますよね。
無駄なお節介はやめてほしいw


> あ、あと、
> 測量とかで使うので、出来ればDouble対応にして欲しかったですね。
> 全て、自分のユニットにコピーしてDouble対応にしましたけど。

リアルタイムに 3DCG を描くためだけのライブラリなので、
頂点座標や法線ベクトルを Double 精度で扱うのは、
メモリ消費から言ってもオーパースペックなのですよね。

座標系の右手/左手もありますし、自分の中で統一して扱うためにも、
FireMonkey に頼るのは描画の部分だけと割り切って、
座標変換系ライブラリは、独自に構築していった方がいいでしょうね。

 http://edn.embarcadero.com/jp/print/images/43102/C4.pdf


+───────────────────────+
│■ 中山雅紀 ( Nakayama Masanori ) │
│・mail: con...@luxidea.net   │
│▽ 慶應義塾大学大学院 理工学研究科 藤代研究室 │
│・site: http://www.fj.ics.keio.ac.jp/
│・mail: naka...@fj.ics.keio.ac.jp
+───────────────────────+


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
人気の温泉リゾートが≪1泊2食500~!≫たまには家族でゆっ
たり♪箱根・軽井沢・伊豆高原・京都など。組数限定!早い者勝ち
■大感謝プラン<1>:【平日】 ¥500~ 
■大感謝プラン<2>:【土・祝前日】 ¥1,500~ 
http://ad.freeml.com/cgi-bin/sa.cgi?id=kvSMx
------------------------------------------------------[freeml byGMO]--

dev

unread,
Sep 20, 2013, 9:29:36 AM9/20/13
to delphi...@freeml.com
luxideaさん。重ね重ね有難うございます。

> 座標系の右手/左手もありますし、自分の中で統一して扱うためにも、
> FireMonkey に頼るのは描画の部分だけと割り切って、
> 座標変換系ライブラリは、独自に構築していった方がいいでしょうね。

はい、実際コンピュータのXYZ軸と測量のXYZ軸とは違いますしね。
現場によって、XYZとかYZXとかありますので、ライブラリー化して
例えば、内部では固定でABC軸にして、標記などの部分だけXYZやYZXに
対応できればいいかなぁ、と考えています。

kmからmmまでの精度を求められると、大変ですよね。
まぁ、kmとか捨てちゃうんですけどね。

まだ、出張の身でして。
来週はインドに行かなきゃ行けないらしいし、、、
ちょっと、いじれませんが頭で考えます。。。(^^;

有難うございました。
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
≪温泉≫1泊2食付500~!箱根・京都・軽井沢・伊豆高原・富
士。人気のリゾート体験宿泊が組数限定の格安価格でご案内!
■大感謝プラン<1>:【平日】 ¥500~ 
■大感謝プラン<2>:【土・祝前日】 ¥1,500~ 
http://ad.freeml.com/cgi-bin/sa.cgi?id=kvW8z
------------------------------------------------------[freeml byGMO]--

Reply all
Reply to author
Forward
0 new messages