5.1 図形の変換
著者:梅谷 武
語句:行列, オイラー角, 四元数
行列, オイラー角, 四元数を使って図形を変換する例を示す。
作成:2010-07-26
更新: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.