5.1 図形の変換
著者:梅谷 武
語句:行列, オイラー角, 四元数
語句:行列, オイラー角, 四元数
行列, オイラー角, 四元数を使って図形を変換する例を示す。
作成:2010-07-26
更新:2011-03-08
更新:2011-03-08
MultMatrix命令により行列で回転を記述する方法と同等なRotate命令を示す。
package.path = "std/?.lua" require( "Geometry" ) PI_180 = 3.14159265358979 / 180.0 function cube() PushMatrix() Translate( 0.0, 0.0,-0.5 ); RotateX( -90.0 ); RotateY( 45.0 ) dxSetColorHSV( 0.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0,-0.5, 0.0 ); RotateX( 180.0 ); RotateY( 45.0 ) dxSetColorHSV( 60.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0, 0.0, 0.5 ); RotateX( 90.0 ); RotateY( 45.0 ) dxSetColorHSV( 120.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0, 0.5, 0.0 ); RotateY( 45.0 ) dxSetColorHSV( 180.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate(-0.5, 0.0, 0.0 ); RotateZ( 90.0 ); RotateY( 45.0 ) dxSetColorHSV( 240.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.5, 0.0, 0.0 ); RotateZ( -90.0 ); RotateY( 45.0 ) dxSetColorHSV( 300.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() end Rect = Figure.new( function() PushMatrix() Scale( 0.6, 1.0, 0.4 ) cube() PopMatrix() end ) E = Transformation.new( function() MultMatrix( Matrix3x3.new( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ) ) end ) sn = math.sin( 60.0 * PI_180 ) cn = math.cos( 60.0 * PI_180 ) RX = Transformation.new( function() MultMatrix( Matrix3x3.new( 1.0, 0.0, 0.0, 0.0, cn, -sn, 0.0, sn, cn ) ) end ) RX1 = Transformation.new( function() Rotate( 60.0, 1.0, 0.0, 0.0 ) end ) RY = Transformation.new( function() MultMatrix( Matrix3x3.new( cn, 0.0, sn, 0.0, 1.0, 0.0, -sn, 0.0, cn ) ) end ) RY1 = Transformation.new( function() Rotate( 60.0, 0.0, 1.0, 0.0 ) end ) RZ = Transformation.new( function() MultMatrix( Matrix3x3.new( cn, -sn, 0.0, sn, cn, 0.0, 0.0, 0.0, 1.0 ) ) end ) RZ1 = Transformation.new( function() Rotate( 60.0, 0.0, 0.0, 1.0 ) end ) TX = Transformation.new( function() Translate( 3.0, 0.0, 0.0 ) end ) TY = Transformation.new( function() Translate( 0.0, 3.0, 0.0 ) end ) TZ = Transformation.new( function() Translate( 0.0, 0.0, 3.0 ) end ) -- Drawing draw = E * Rect draw = ( TX * RX ) * Rect draw = ( TY * RY ) * Rect draw = ( TZ * RZ ) * Rect draw = ( TX^2 * RX1 ) * Rect draw = ( TY^2 * RY1 ) * Rect draw = ( TZ^2 * RZ1 ) * Rect tnNewObject()
オイラー角表現におけるX, Y, Z軸の組み合わせにはさまざまな種類がある。Lua拡張命令ではヨー・ピッチ・ロールと呼ばれる特に宇宙航空分野でよく使われる表現法のクラスが用意されている。
package.path = "std/?.lua" require( "Geometry" ) PI_180 = 3.14159265358979 / 180.0 function cube() PushMatrix() Translate( 0.0, 0.0,-0.5 ); RotateX( -90.0 ); RotateY( 45.0 ) dxSetColorHSV( 0.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0,-0.5, 0.0 ); RotateX( 180.0 ); RotateY( 45.0 ) dxSetColorHSV( 60.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0, 0.0, 0.5 ); RotateX( 90.0 ); RotateY( 45.0 ) dxSetColorHSV( 120.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0, 0.5, 0.0 ); RotateY( 45.0 ) dxSetColorHSV( 180.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate(-0.5, 0.0, 0.0 ); RotateZ( 90.0 ); RotateY( 45.0 ) dxSetColorHSV( 240.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.5, 0.0, 0.0 ); RotateZ( -90.0 ); RotateY( 45.0 ) dxSetColorHSV( 300.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() end Rect = Figure.new( function() PushMatrix() Scale( 0.6, 1.0, 0.4 ) cube() PopMatrix() end ) E = Transformation.new( function() MultMatrix( Matrix3x3.new( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ) ) end ) m = Matrix3x3.new( EulerAngles.new( 60.0*PI_180, 0.0, 0.0 ) ) RM = Transformation.new( function() MultMatrix( Matrix3x3.new( m.m11,m.m12,m.m13, m.m21,m.m22,m.m23, m.m31,m.m32,m.m33 ) ) end ) TX = Transformation.new( function() Translate( 3.0, 0.0, 0.0 ) end ) TY = Transformation.new( function() Translate( 0.0, 3.0, 0.0 ) end ) TZ = Transformation.new( function() Translate( 0.0, 0.0, 3.0 ) end ) -- Drawing draw = E * Rect draw = ( TZ * RM ) * Rect m = Matrix3x3.new( EulerAngles.new( 0.0, 60.0*PI_180, 0.0 ) ) draw = ( TX * RM ) * Rect m = Matrix3x3.new( EulerAngles.new( 0.0, 0.0, 60.0*PI_180 ) ) draw = ( TY * RM ) * Rect tnNewObject()
四元数による空間の回転を行なう場合、回転角は四元数の角の2倍になることに注意する。
package.path = "std/?.lua" require( "Geometry" ) PI_180 = 3.14159265358979 / 180.0 function cube() PushMatrix() Translate( 0.0, 0.0,-0.5 ); RotateX( -90.0 ); RotateY( 45.0 ) dxSetColorHSV( 0.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0,-0.5, 0.0 ); RotateX( 180.0 ); RotateY( 45.0 ) dxSetColorHSV( 60.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0, 0.0, 0.5 ); RotateX( 90.0 ); RotateY( 45.0 ) dxSetColorHSV( 120.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.0, 0.5, 0.0 ); RotateY( 45.0 ) dxSetColorHSV( 180.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate(-0.5, 0.0, 0.0 ); RotateZ( 90.0 ); RotateY( 45.0 ) dxSetColorHSV( 240.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() PushMatrix() Translate( 0.5, 0.0, 0.0 ); RotateZ( -90.0 ); RotateY( 45.0 ) dxSetColorHSV( 300.0, 0.8, 1.0 ); dxPolygon( 1.0, 4 ) PopMatrix() end Rect = Figure.new( function() PushMatrix() Scale( 0.6, 1.0, 0.4 ) cube() PopMatrix() end ) E = Transformation.new( function() MultMatrix( Matrix3x3.new( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ) ) end ) AX = Vector3.new( 1.0, 0.0, 0.0 ) AY = Vector3.new( 0.0, 1.0, 0.0 ) AZ = Vector3.new( 0.0, 0.0, 1.0 ) m = Matrix3x3.new( Quaternion.new( 30.0*PI_180, Axis(AY/AX) ) ) RM = Transformation.new( function() MultMatrix( Matrix3x3.new( m.m11,m.m12,m.m13, m.m21,m.m22,m.m23, m.m31,m.m32,m.m33 ) ) end ) TX = Transformation.new( function() Translate( 3.0, 0.0, 0.0 ) end ) TY = Transformation.new( function() Translate( 0.0, 3.0, 0.0 ) end ) TZ = Transformation.new( function() Translate( 0.0, 0.0, 3.0 ) end ) -- Drawing draw = E * Rect draw = ( TZ * RM ) * Rect m = Matrix3x3.new( Quaternion.new( 30.0*PI_180, Axis(AX/AZ) ) ) draw = ( TY * RM ) * Rect m = Matrix3x3.new( Quaternion.new( 30.0*PI_180, Axis(AZ/AY) ) ) draw = ( TX * RM ) * Rect tnNewObject()
Published by SANENSYA Co.,Ltd.