I feel bad for ruining your work a little, but LowerLogic once coded these rotation functions:
(fully copied from the .dba he provided)
remstart
Lowerlogic's Rotation/Angle Commands
Notes:
angle-distance means it will get the absolute value of the angle (because
there is no axis to indicate direction)
Rotation Functions:
Global/World Axis Rotation Functions:
Rotates the object along the global X axis the given amount
Rotate_GX(object number, angle)
Rotates the object along the global Y axis the given amount
Rotate_GY(object number, angle)
Rotates the object along the global Z axis the given amount
Rotate_GZ(object number, angle)
Local/Relative Axis Rotation Functions:
Rotates the object along its local X axis the given amount
Rotate_LX(object number, angle)
Rotates the object along its local Y axis the given amount
Rotate_LY(object number, angle)
Rotates the object along its local Z axis the given amount
Rotate_LZ(object number, angle)
Arbitrary Axis Rotation:
Rotates the object around the given axis the given amount
Rotate_Axis(object number, axis_x, axis_y, axis_z, angle)
Rotates the object so that the given local axis is aligned with the
given global axis
Align_Axes(object number, local_axis_x, local_axis_y, local_axis_z, global_axis_x, global_axis_y, global_axis_z)
Rotates the object so that the given local axis is aligned with the
given global axis. However, it will not rotate more than the gien
amount.
Smooth_Align_Axes(object number, local_axis_x, local_axis_y, local_axis_z, global_axis_x, global_axis_y, global_axis_z,max_angle_turn_amount)
Rotates the object so that the given local axis has an angle to the
global axis that is either less than, equal to, or greater than the
given angle. The relation it determined by the flag like so:
Flag Usage:
If flag=0, the rotation will occur.
If flag<0, the rotation will occur if the angle between the axes
is less than the given angle.
If flag>0, the rotation will occur if the angle between the axes
is greater than the given angle.
Angle_Axes(object number, local_axis_x, local_axis_y, local_axis_z, global_axis_x, global_axis_y, global_axis_z,desired_angle,flag)
Rotates the object so that the given local axis has an angle to the
global axis that is either less than, equal to, or greater than the
given angle. The relation it determined by the flag like so:
Flag Usage:
If flag=0, the rotation will occur.
If flag<0, the rotation will occur if the angle between the axes
is less than the given angle.
If flag>0, the rotation will occur if the angle between the axes
is greater than the given angle.
The object will not rotate more than the maximum turn amount
Smooth_Angle_Axes(object number, local_axis_x, local_axis_y, local_axis_z, global_axis_x, global_axis_y, global_axis_z,desired_angle,flag,max_angle_turn_amount)
Rotates and positions the object so that it rotates about a given point and axis.
Orbit(object number,point_x,point_y,point_z, axis_x, axis_y, axis_z, angle)
Axis-Angle Rotation Functions
RotateAxisAngleY(object number, up_vector_x, up_vector_y, up_vector_z, angle)
RotateAxisAngleX(object number, up_vector_x, up_vector_y, up_vector_z, angle)
RotateAxisAngleZ(object number, up_vector_x, up_vector_y, up_vector_z, angle)
Get Angle Functions:
Get Axis-Angle Functions:
Axis_Angle_X(object number, up_vector_x, up_vector_y, up_vector_z)
Axis_Angle_Y(object number, up_vector_x, up_vector_y, up_vector_z)
Axis_Angle_Z(object number, up_vector_x, up_vector_y, up_vector_z)
FindAxisAngleYtoPoint(object number, up_vector_x, up_vector_y, up_vector_z, point_x, point_y, point_z)
FindAxisAngleXtoPoint(object number, up_vector_x, up_vector_y, up_vector_z, point_x, point_y, point_z)
Other:
Returns the angle-distance between 2 points through the origin point
AngleBetweenPoints(originX#, originY#, originZ#, point1X#, point1Y#,
point1Z#, point2X#, point2Y#, point2Z#)
Returns the angle-distance between 2 axes (either both global or both
local)
AngleBetweenAxes(axis_x, axis_y, axis_z, axis_x, axis_y, axis_z)
Get Global Angle:
Returns the global X angle between the object's local Y axis and the global Y axis
Angle_GX_Y(object number)
Returns the global X angle between the object's local Z axis and the global Z axis
Angle_GX_Z(object number)
Returns the global Y angle between the object's local X axis and the global X axis
Angle_GY_X(object number)
Returns the global Y angle between the object's local Z axis and the global Z axis
Angle_GY_Z(object number)
Returns the global Z angle between the object's local X axis and the global X axis
Angle_GZ_X(object number)
Returns the global Z angle between the object's local Y axis and the global Y axis
Angle_GZ_Y(object number)
Get Local Angle to Arbitrary Axis Around a Defined Local Axis:
Returns the local X angle between the object's local Y axis and the
given global axis
Angle_LX_Y(object number, global_axis_x, global_axis_y, global_axis_z)
Returns the local X angle between the object's local Z axis and the
given global axis
Angle_LX_Z(object number, global_axis_x, global_axis_y, global_axis_z)
Returns the local Y angle between the object's local X axis and the
given global axis
Angle_LY_X(object number, global_axis_x, global_axis_y, global_axis_z)
Returns the local Y angle between the object's local Z axis and the
given global axis
Angle_LY_Z(object number, global_axis_x, global_axis_y, global_axis_z)
Returns the local Z angle between the object's local X axis and the
given global axis
Angle_LZ_X(object number, global_axis_x, global_axis_y, global_axis_z)
Returns the local Z angle between the object's local Y axis and the
given global axis
Angle_LZ_Y(object number, global_axis_x, global_axis_y, global_axis_z)
Arbitrary Axis Angles:
The function takes 3 axes:
1) A rotation axis
2) An initial axis
3) A final axis
The function will return the angle the initial axis would have to
rotate around the rotation axis to reach the destination axis.
Note that the axes do not have to be orthogonal.
Angle_Axis(rotation_axis_x, rotation_axis_y,
rotation_axis_z, base_axis_x, base_axis_y, base_axis_z, dest_axis_x,
dest_axis_y, dest_axis_z)
Returns the angle from the local axis to the global axis around the
given global rotation axis. The function will return an angle with
direction. Since this function is really complicated, it can be
hard to use correctly. I recommend you use one of the simpler
angle functions if you can.
Angle_Axis_GL(object number, rotation_axis_x, rotation_axis_y,
rotation_axis_z, global_axis_x, global_axis_y, global_axis_z,
local_axis_x, local_axis_y, local_axis_z)
Returns the angle from the 2nd global axis to the 1st global axis around the
given local rotation axis. The function will return an angle with
direction. Since this function is really complicated, it can be
hard to use correctly. I recommend you use one of the simpler
angle functions if you can.
Angle_Axis_LG(object number, local_rotation_axis_x, local_rotation_axis_y,
local_rotation_axis_z, global_axis_x, global_axis_y, global_axis_z,
axis_x, axis_y, laxis_z)
Returns the angle from the local axis to the global axis around the
given local rotation axis. The function will return an angle with
direction. Since this function is really complicated, it can be
hard to use correctly. I recommend you use one of the simpler
angle functions if you can.
Angle_Axis_LL(object number, local_rotation_axis_x, local_rotation_axis_y,
local_rotation_axis_z, global_axis_x, global_axis_y, global_axis_z,
local_axis_x, local_axis_y, local_axis_z)
Note these equalities to understand how this functions work:
Angle_GX_Y(1)=Angle_Axis_GL(1,1,0,0,0,1,0,0,1,0)
Angle_GX_Z(1)=Angle_Axis_GL(1,1,0,0,0,0,1,0,0,1)
Angle_GY_X(1)=Angle_Axis_GL(1,0,1,0,1,0,0,1,0,0)
Angle_GY_Z(1)=Angle_Axis_GL(1,0,1,0,0,0,1,0,0,1)
Angle_GZ_X(1)=Angle_Axis_GL(1,0,0,1,1,0,0,1,0,0)
Angle_GZ_Y(1)=Angle_Axis_GL(1,0,0,1,0,1,0,0,1,0)
Angle_LX_Y(1,ax#,ay#,az#)=Angle_Axis_LL(1,1,0,0,ax#,ay#,az#,0,1,0)
Angle_LX_Z(1,ax#,ay#,az#)=Angle_Axis_LL(1,1,0,0,ax#,ay#,az#,0,0,1)
Angle_LY_X(1,ax#,ay#,az#)=Angle_Axis_LL(1,0,1,0,ax#,ay#,az#,1,0,0)
Angle_LY_Z(1,ax#,ay#,az#)=Angle_Axis_LL(1,0,1,0,ax#,ay#,az#,0,0,1)
Angle_LZ_X(1,ax#,ay#,az#)=Angle_Axis_LL(1,0,0,1,ax#,ay#,az#,1,0,0)
Angle_LZ_Y(1,ax#,ay#,az#)=Angle_Axis_LL(1,0,0,1,ax#,ay#,az#,0,1,0)
remend
sync on
sync rate 0
cls
hide mouse
set display mode 1024,768,32
autocam off
rem make object to rotate
make object box 1,2,1,4
make object box 11,1,1,1
position object 11,0,1,-1
glue object to limb 11,1,0
rem make 3 boxes to show x/y/z world axes
make object box 2,1000,0.1,0.1
make object box 3,0.1,1000,0.1
make object box 4,0.1,0.1,1000
rem main loop
do
set cursor 0,0
rem camera
position camera 0,0,0
rotate camera cx1#,cy1#,0
move camera -6
mmx=mousemovex()
mmy=mousemovey()
if mouseclick()=0
cx1#=cx1#+mmy
cy1#=cy1#+mmx
else
cx2#=cx2#+mmy
cy2#=cy2#+mmx
endif
turn camera right cy2#
pitch camera down cx2#
` rotate object 1,object angle x(1)+(keystate(16)-keystate(30))*0.5,object angle y(1)+(keystate(17)-keystate(31))*0.5,object angle z(1)+(keystate(18)-keystate(32))*0.5
rem global rotation
rotate_GX(1,(keystate(16)-keystate(30))*0.5)
rotate_GY(1,(keystate(17)-keystate(31))*0.5)
rotate_GZ(1,(keystate(18)-keystate(32))*0.5)
rem arbitrary axis rotation
x#=camera position x():y#=camera position y():z#=camera position z()
move camera 1
nx#=camera position x()-x#:ny#=camera position y()-y#:nz#=camera position z()-z#
move camera -1
rotate_axis(1,nx#,ny#,nz#,(keystate(19)-keystate(33))*0.5)
dx#=camera position x()-object position x(1)
dy#=camera position y()-object position y(1)
dz#=camera position z()-object position z(1)
rem local axis rotation
rotate_LX(1,(keystate(20)-keystate(34))*0.5)
rotate_LY(1,(keystate(21)-keystate(35))*0.5)
rotate_LZ(1,(keystate(22)-keystate(36))*0.5)
orbit(1,x#,y#,z#,nx#,ny#,nz#,(keystate(23)-keystate(37))*0.5)
rem display
print "Rotation Controls:"
print "Global X Axis:Q/A"
print "Global Y Axis:W/S"
print "Global Z Axis:E/D"
print "Arbitrary Axis (The camera's view direction): R/F"
print "Local X Axis:T/G"
print "Local Y Axis:Y/H"
print "Local Z Axis:U/J"
print "Object angle X:",object angle x(1)
print "Object angle Y:",object angle y(1)
print "Object angle Z:",object angle z(1)
x#=object position x(1):y#=object position y(1):z#=object position z(1)
move object up 1,1
yx#=object position x(1)-x#:yy#=object position y(1)-y#:yz#=object position z(1)-z#
move object down 1,1:move object 1,1
zx#=object position x(1)-x#:zy#=object position y(1)-y#:zz#=object position z(1)-z#
move object 1,-1
print "Angle between local y axis and global y axis:",AngleBetweenPoints(0,0,0,0,1,0,yx#,yy#,yz#)
print "Axis angle y(1,0,1,0):",Axis_Angle_Y(1,0,1,0)
print "Axis angle x(1,0,1,0):",Axis_Angle_X(1,0,1,0)
print "Axis angle z(1,0,1,0):",Axis_Angle_Z(1,0,1,0)
cx#=camera position x():cy#=camera position y():cz#=camera position z()
print "Axis angle y to camera(1,0,1,0):",FindAxisAngleYtoPoint(1,0,1,0,dx#,dy#,dz#)
print "Axis angle x to camera(1,0,1,0):",FindAxisAngleXtoPoint(1,0,1,0,dx#,dy#,dz#)
print "Angle_GX_Y:",Angle_GX_Y(1)
print "Angle_GX_Z:",Angle_GX_Z(1)
print "Angle_GY_X:",Angle_GY_X(1)
print "Angle_GY_Z:",Angle_GY_Z(1)
print "Angle_GZ_X:",Angle_GZ_X(1)
print "Angle_GZ_Y:",Angle_GZ_Y(1)
print "Angle_LX_Y to camera:",Angle_LX_Y(1,dx#,dy#,dz#)
print "Angle_LX_Z to camera:",Angle_LX_Z(1,dx#,dy#,dz#)
print "Angle_LY_X to camera:",Angle_LY_X(1,dx#,dy#,dz#)
print "Angle_LY_Z to camera:",Angle_LY_Z(1,dx#,dy#,dz#)
print "Angle_LZ_X to camera:",Angle_LZ_X(1,dx#,dy#,dz#)
print "Angle_LZ_Y to camera:",Angle_LZ_Y(1,dx#,dy#,dz#)
print "Angle between local z axis and global y axis about the camera axis:",Angle_Axis(dx#,dy#,dz#,0,1,0,zx#,zy#,zz#)
`print "Using Angle_Axis_GL():"
print "Angle_GX_Y:",Angle_Axis_GL(1,1,0,0,0,1,0,0,1,0)
print "Angle_GX_Z:",Angle_Axis_GL(1,1,0,0,0,0,1,0,0,1)
print "Angle_GY_X:",Angle_Axis_GL(1,0,1,0,1,0,0,1,0,0)
print "Angle_GY_Z:",Angle_Axis_GL(1,0,1,0,0,0,1,0,0,1)
print "Angle_GZ_X:",Angle_Axis_GL(1,0,0,1,1,0,0,1,0,0)
print "Angle_GZ_Y:",Angle_Axis_GL(1,0,0,1,0,1,0,0,1,0)
`print "Using Angle_Axis_LL():"
print "Angle_LX_Y to camera:",Angle_Axis_LL(1,1,0,0,dx#,dy#,dz#,0,1,0)
print "Angle_LX_Z to camera:",Angle_Axis_LL(1,1,0,0,dx#,dy#,dz#,0,0,1)
print "Angle_LY_X to camera:",Angle_Axis_LL(1,0,1,0,dx#,dy#,dz#,1,0,0)
print "Angle_LY_Z to camera:",Angle_Axis_LL(1,0,1,0,dx#,dy#,dz#,0,0,1)
print "Angle_LZ_X to camera:",Angle_Axis_LL(1,0,0,1,dx#,dy#,dz#,1,0,0)
print "Angle_LZ_Y to camera:",Angle_Axis_LL(1,0,0,1,dx#,dy#,dz#,0,1,0)
print "Angle restriction modes:"
print "1 - No Restrictions"
print "2 - Align Local Y Axis to Global Y Axis"
print "3 - FPS-like rotation"
print "4 - Turn to camera"
print "5 - Turn to camera with loose fps rotation restrictions"
print "6 - Turn to camera using AxisAngle (turret) commands"
for n=2 to 8
if keystate(n)=1
mode=n-2
endif
next n
if mode=1
Align_Axes(1,0,1,0,0,1,0)
endif
if mode=2
Rem if angle between local y axis and global y axis > 85 degrees, then rotate object such that it is 85 degrees
rem keeps the object from flipping at poles
Angle_Axes(1,0,1,0,0,1,0,85,1)
Rem always keep local x axis and global y axis perpendicular (no local z axis rotation)
Angle_Axes(1,1,0,0,0,1,0,90,0)
endif
if mode=3
Rem point the object at the camera
rem limit rotation to a max of 0.5 degrees.
Smooth_Align_Axes(1,0,0,1,dx#,dy#,dz#,0.5)
endif
if mode=4
Rem point the object at the camera
rem limit rotation to a max of 0.5 degrees.
Smooth_Align_Axes(1,0,0,1,dx#,dy#,dz#,0.5)
Rem if angle between local y axis and global y axis > 85 degrees, then try to rotate object such that it is 85 degrees
Smooth_Angle_Axes(1,0,1,0,0,1,0,85,1,0.2)
Rem try keep local x axis and global y axis perpendicular
Smooth_Angle_Axes(1,1,0,0,0,1,0,90,0,0.1)
endif
if mode=5
targ_y#=FindAxisAngleYtoPoint(1,0,1,0,cx#,cy#,cz#)
RotateAxisAngleY(1,0,1,0,curveangle(targ_y#,Axis_Angle_Y(1,0,1,0),30))
targ_x#=FindAxisAngleXtoPoint(1,0,1,0,cx#,cy#,cz#)
RotateAxisAngleX(1,0,1,0,curveangle(targ_x#,Axis_Angle_X(1,0,1,0),30))
if spacekey()=1
targ_z#=targ_z#+1
RotateAxisAngleZ(1,0,1,0,targ_z#)
else
RotateAxisAngleZ(1,0,1,0,0)
endif
endif
print "Mode:",mode+1
sync
loop
remstart Rotate_GX
This function rotates the given object around the global (world) x axis by
the given amount.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_GX(obj as integer,amount# as float)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
xx1#=xx#
xy1#=xy#*cos(amount#)-xz#*sin(amount#)
xz1#=xz#*cos(amount#)+xy#*sin(amount#)
zx1#=zx#
zy1#=zy#*cos(amount#)-zz#*sin(amount#)
zz1#=zz#*cos(amount#)+zy#*sin(amount#)
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
remstart Rotate_GY
This function rotates the given object around the global (world) y axis by
the given amount.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_GY(obj,amount#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
xx1#=xx#*cos(amount#)+xz#*sin(amount#)
xy1#=xy#
xz1#=xz#*cos(amount#)-xx#*sin(amount#)
zx1#=zx#*cos(amount#)+zz#*sin(amount#)
zy1#=zy#
zz1#=zz#*cos(amount#)-zx#*sin(amount#)
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
remstart Rotate_GZ
This function rotates the given object around the global (world) z axis by
the given amount.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_GZ(obj,amount#)
rem Rotating around the global Z axis is trivial
rem as it is the first rotation anyway in the default ZYX rotation order
rotate object obj,object angle x(obj),object angle y(obj),object angle z(obj)+amount#
endfunction
remstart Rotate_axis
This function rotates the given object around the given axis by the given
amount. This function is called by many other functions.
Param obj The object to rotate
Param ax#,ay#,az# The x,y and z components of the rotation axis
Param amount# The angle to rotate the object by
remend
function rotate_axis(obj,ax#,ay#,az#,amount#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the x axis so that the rotation axis lies in the xz plane
xangle#=atanfull(ay#,az#)
xx1#=xx#
xy1#=xy#*cos(xangle#)-xz#*sin(xangle#)
xz1#=xz#*cos(xangle#)+xy#*sin(xangle#)
zx1#=zx#
zy1#=zy#*cos(xangle#)-zz#*sin(xangle#)
zz1#=zz#*cos(xangle#)+zy#*sin(xangle#)
ax1#=ax#
ay1#=ay#*cos(xangle#)-az#*sin(xangle#)
az1#=az#*cos(xangle#)+ay#*sin(xangle#)
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
yangle#=-atanfull(ax1#,az1#)
xx2#=xx1#*cos(yangle#)+xz1#*sin(yangle#)
xy2#=xy1#
xz2#=xz1#*cos(yangle#)-xx1#*sin(yangle#)
zx2#=zx1#*cos(yangle#)+zz1#*sin(yangle#)
zy2#=zy1#
zz2#=zz1#*cos(yangle#)-zx1#*sin(yangle#)
ax2#=ax1#*cos(yangle#)+az1#*sin(yangle#)
ay2#=ay1#
az2#=az1#*cos(yangle#)-ax1#*sin(yangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
rem 4) Inverse of step 2
xx4#=xx3#*cos(-yangle#)+xz3#*sin(-yangle#)
xy4#=xy3#
xz4#=xz3#*cos(-yangle#)-xx3#*sin(-yangle#)
zx4#=zx3#*cos(-yangle#)+zz3#*sin(-yangle#)
zy4#=zy3#
zz4#=zz3#*cos(-yangle#)-zx3#*sin(-yangle#)
rem 5) Inverse of step 1
xx1#=xx4#
xy1#=xy4#*cos(-xangle#)-xz4#*sin(-xangle#)
xz1#=xz4#*cos(-xangle#)+xy4#*sin(-xangle#)
zx1#=zx4#
zy1#=zy4#*cos(-xangle#)-zz4#*sin(-xangle#)
zz1#=zz4#*cos(-xangle#)+zy4#*sin(-xangle#)
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
remstart Rotate_LX
This function rotates the given object around the object's local x axis by
the given amount. This function calls rotate_axis() to do the rotation.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_LX(obj as integer,amount# as float)
rem Rotating around the local X axis is trivial
rem as it is the last rotation anyway in the default ZYX rotation order
rotate object obj,object angle x(obj)+amount#,object angle y(obj),object angle z(obj)
endfunction
remstart Rotate_LY
This function rotates the given object around the object's local y axis by
the given amount. This function calls rotate_axis() to do the rotation.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_LY(obj as integer,amount# as float)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1
rotate_axis(obj,yx#,yy#,yz#,amount#)
endfunction
remstart Rotate_LZ
This function rotates the given object around the object's local z axis by
the given amount. This function calls rotate_axis() to do the rotation.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_LZ(obj as integer,amount# as float)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rotate_axis(obj,zx#,zy#,zz#,amount#)
endfunction
remstart AngleBetweenPoints
This function takes an origin and 2 points and finds the angle between them
through the given origin.
Param originX#,originY#,originX# The point that is to be the origin
Param point1X#,point1Y#,point1Z# The first point
Param point2X#,point2Y#,point2Z# The second point
Return angle# The angle between the 2 points.
The angle returned will be between 0 and 180 degrees
remend
function AngleBetweenPoints(originX#, originY#, originZ#, point1X#, point1Y#, point1Z#, point2X#, point2Y#, point2Z#)
v1x#=point1X#-originX#
v1y#=point1Y#-originY#
v1z#=point1Z#-originZ#
v2x#=point2X#-originX#
v2y#=point2Y#-originY#
v2z#=point2Z#-originZ#
angle#=AngleBetweenAxes(v1x#,v1y#,v1z#,v2x#,v2y#,v2z#)
endfunction angle#
remstart AngleBetweenAxes
This function takes 2 axes ang finds the angle between them
Param v1x#,v1y#,v1x# The first axes
Param v2x#,v2y#,v2z# The second axes
Return angle# The angle between the 2 points.
The angle returned will be between 0 and 180 degrees
remend
function AngleBetweenAxes(v1x#,v1y#,v1z#,v2x#,v2y#,v2z#)
v1#=sqrt(v1x#*v1x#+v1y#*v1y#+v1z#*v1z#)
v2#=sqrt(v2x#*v2x#+v2y#*v2y#+v2z#*v2z#)
angle#=acos((v1x#*v2x#+v1y#*v2y#+v1z#*v2z#)/(v1#*v2#))
endfunction angle#
remstart Align_Axes
This function aligns an arbitrary axis local to the object to an arbitrary
global axis. When called every frame, the function effectively "locks" the
object so that it can only rotate around the given global axis.
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
remend
function Align_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endfunction
remstart Smooth_Align_Axes
This function aligns an arbitrary axis local to the object to an arbitrary
global axis. The function will rotate no more than the given maximum angle
so that the alignment can be smoothed out over multiple frames.
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
Param max_angle# The maximum angle by which the object may be rotated
remend
function Smooth_Align_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#,max_angle#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
if angle#>max_angle#
angle#=max_angle#
endif
if angle#<-max_angle#
angle#=-max_angle#
endif
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endfunction
remstart Angle_Axes
This function rotates the object such that the given local axis has an angle
equal to the given angle with the global axis. Al
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
Param ang# The given angle to keep between the local and global
axes. Flag also uses it to provide more functionality.
Param flag Used to decide when to perform the actual rotation
Flag Usage:
If flag=0, the rotation will occur.
If flag<0, the rotation will occur if the angle between the axes is less
than the given angle.
If flag>0, the rotation will occur if the angle between the axes is
greater than the given angle.
remend
function Angle_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#,ang#,flag)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
angle#=angle#-ang#
if flag=0 or (flag<0 and angle#<0) or (flag>0 and angle#>0)
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endif
endfunction
remstart Smooth_Angle_Axes
This function rotates the object such that the given local axis has an angle
equal to the given angle with the global axis. The function will rotate no
more than the given maximum angle so that the alignment can be smoothed out
over multiple frames.
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
Param ang# The given angle to keep between the local and global
axes. Flag also uses it to provide more functionality.
Param flag Used to decide when to perform the actual rotation
Param max_angle# The maximum angle by which the object may be rotated
Flag Usage:
If flag=0, the rotation will occur.
If flag<0, the rotation will occur if the angle between the axes is less
than the given angle.
If flag>0, the rotation will occur if the angle between the axes is
greater than the given angle.
remend
function Smooth_Angle_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#,ang#,flag,max_angle#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
angle#=angle#-ang#
if flag=0 or (flag<0 and angle#<0) or (flag>0 and angle#>0)
if angle#>max_angle#
angle#=max_angle#
endif
if angle#<-max_angle#
angle#=-max_angle#
endif
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endif
endfunction
function Axis_Angle_Y(obj,ayx#,ayy#,ayz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
angle#=wrapvalue(atanfull(zx3#,-zy3#))
endfunction angle#
function Axis_Angle_X(obj,ayx#,ayy#,ayz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
angle#=wrapvalue(-atanfull(zz3#,sqrt(zx3#^2+zy3#^2)))
endfunction angle#
function Axis_Angle_Z(obj,ayx#,ayy#,ayz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
rem 1) rotate space about the z axis so that the rotation axis lies in the xz plane
zangle#=atanfull(zx2#,-zy2#)
xx3#=xx2#*cos(zangle#)+xy2#*sin(zangle#)
xy3#=xy2#*cos(zangle#)-xx2#*sin(zangle#)
xz3#=xz2#
zx3#=zx2#*cos(zangle#)+zy2#*sin(zangle#)
zy3#=zy2#*cos(zangle#)-zx2#*sin(zangle#)
zz3#=zz2#
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
xangle#=atanfull(zy3#,zz3#)
xx4#=xx3#
xy4#=xy3#*cos(xangle#)-xz3#*sin(xangle#)
xz4#=xz3#*cos(xangle#)+xy3#*sin(xangle#)
zx4#=zx3#
zy4#=zy3#*cos(xangle#)-zz3#*sin(xangle#)
zz4#=zz3#*cos(xangle#)+zy3#*sin(xangle#)
angle#=wrapvalue(atanfull(xy4#,xx4#))
endfunction angle#
function FindAxisAngleYtoPoint(obj,ayx#,ayy#,ayz#,px#,py#,pz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
dx#=px#-object position x(obj)
dy#=py#-object position y(obj)
dz#=pz#-object position z(obj)
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
dx1#=dx#*cos(yangle#)+dz#*sin(yangle#)
dy1#=dy#
dz1#=dz#*cos(yangle#)-dx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
dx2#=dx1#
dy2#=dy1#*cos(xangle#)-dz1#*sin(xangle#)
dz2#=dz1#*cos(xangle#)+dy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
angle#=wrapvalue(atanfull(dx2#,-dy2#))
endfunction angle#
function FindAxisAngleXtoPoint(obj,ayx#,ayy#,ayz#,px#,py#,pz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
dx#=px#-object position x(obj)
dy#=py#-object position y(obj)
dz#=pz#-object position z(obj)
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
dx1#=dx#*cos(yangle#)+dz#*sin(yangle#)
dy1#=dy#
dz1#=dz#*cos(yangle#)-dx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
dx2#=dx1#
dy2#=dy1#*cos(xangle#)-dz1#*sin(xangle#)
dz2#=dz1#*cos(xangle#)+dy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
angle#=wrapvalue(atanfull(-dz2#,sqrt(dx2#^2+dy2#^2)))
endfunction angle#
function RotateAxisAngleY(obj,ax#,ay#,az#,amount#)
rotate_axis(obj,ax#,ay#,az#,amount#-Axis_Angle_Y(obj,ax#,ay#,az#))
endfunction
function RotateAxisAngleX(obj,ax#,ay#,az#,amount#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
crosspx#=(ay# * zz# - az# * zy#)
crosspy#=(az# * zx# - ax# * zz#)
crosspz#=(ax# * zy# - ay# * zx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,amount#-Axis_Angle_X(obj,ax#,ay#,az#))
endfunction
function RotateAxisAngleZ(obj,ax#,ay#,az#,amount#)
Rotate_LZ(obj,amount#-Axis_Angle_Z(obj,ax#,ay#,az#))
endfunction
function Orbit(obj,px#,py#,pz#,ax#,ay#,az#,amount#)
dx#=object position x(obj)-px#
dy#=object position y(obj)-py#
dz#=object position z(obj)-pz#
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the x axis so that the rotation axis lies in the xz plane
xangle#=atanfull(ay#,az#)
xx1#=xx#
xy1#=xy#*cos(xangle#)-xz#*sin(xangle#)
xz1#=xz#*cos(xangle#)+xy#*sin(xangle#)
zx1#=zx#
zy1#=zy#*cos(xangle#)-zz#*sin(xangle#)
zz1#=zz#*cos(xangle#)+zy#*sin(xangle#)
dx1#=dx#
dy1#=dy#*cos(xangle#)-dz#*sin(xangle#)
dz1#=dz#*cos(xangle#)+dy#*sin(xangle#)
ax1#=ax#
ay1#=ay#*cos(xangle#)-az#*sin(xangle#)
az1#=az#*cos(xangle#)+ay#*sin(xangle#)
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
yangle#=-atanfull(ax1#,az1#)
xx2#=xx1#*cos(yangle#)+xz1#*sin(yangle#)
xy2#=xy1#
xz2#=xz1#*cos(yangle#)-xx1#*sin(yangle#)
zx2#=zx1#*cos(yangle#)+zz1#*sin(yangle#)
zy2#=zy1#
zz2#=zz1#*cos(yangle#)-zx1#*sin(yangle#)
dx2#=dx1#*cos(yangle#)+dz1#*sin(yangle#)
dy2#=dy1#
dz2#=dz1#*cos(yangle#)-dx1#*sin(yangle#)
ax2#=ax1#*cos(yangle#)+az1#*sin(yangle#)
ay2#=ay1#
az2#=az1#*cos(yangle#)-ax1#*sin(yangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
dx3#=dx2#*cos(amount#)-dy2#*sin(amount#)
dy3#=dy2#*cos(amount#)+dx2#*sin(amount#)
dz3#=dz2#
rem 4) Inverse of step 2
xx4#=xx3#*cos(-yangle#)+xz3#*sin(-yangle#)
xy4#=xy3#
xz4#=xz3#*cos(-yangle#)-xx3#*sin(-yangle#)
zx4#=zx3#*cos(-yangle#)+zz3#*sin(-yangle#)
zy4#=zy3#
zz4#=zz3#*cos(-yangle#)-zx3#*sin(-yangle#)
dx4#=dx3#*cos(-yangle#)+dz3#*sin(-yangle#)
dy4#=dy3#
dz4#=dz3#*cos(-yangle#)-dx3#*sin(-yangle#)
rem 5) Inverse of step 1
xx1#=xx4#
xy1#=xy4#*cos(-xangle#)-xz4#*sin(-xangle#)
xz1#=xz4#*cos(-xangle#)+xy4#*sin(-xangle#)
zx1#=zx4#
zy1#=zy4#*cos(-xangle#)-zz4#*sin(-xangle#)
zz1#=zz4#*cos(-xangle#)+zy4#*sin(-xangle#)
ndx#=dx4#
ndy#=dy4#*cos(-xangle#)-dz4#*sin(-xangle#)
ndz#=dz4#*cos(-xangle#)+dy4#*sin(-xangle#)
position object obj,px#+ndx#,py#+ndy#,pz#+ndz#
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
rem Returns the global X angle between the object's local Y axis and the global Y axis
function Angle_GX_Y(obj)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object up obj,1
yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1
angle#=wrapvalue(atanfull(yz#,yy#))
endfunction angle#
rem Returns the global X angle between the object's local Z axis and the global Z axis
function Angle_GX_Z(obj)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object obj,1
zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
angle#=wrapvalue(atanfull(-zy#,zz#))
endfunction angle#
rem Returns the global Y angle between the object's local X axis and the global X axis
function Angle_GY_X(obj)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xz#=object position z(obj)-z#
move object left obj,1
angle#=wrapvalue(atanfull(-xz#,xx#))
endfunction angle#
rem Returns the global Y angle between the object's local Z axis and the global Z axis
function Angle_GY_Z(obj)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object obj,1
zx#=object position x(obj)-x#:zz#=object position z(obj)-z#
move object obj,-1
angle#=wrapvalue(atanfull(zx#,zz#))
endfunction angle#
rem Returns the global Z angle between the object's local X axis and the global X axis
function Angle_GZ_X(obj)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#
move object left obj,1
angle#=wrapvalue(atanfull(xy#,xx#))
endfunction angle#
rem Returns the global Z angle between the object's local Y axis and the global Y axis
function Angle_GZ_Y(obj)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#
move object down obj,1
angle#=wrapvalue(atanfull(-yx#,yy#))
endfunction angle#
remstart
Returns the local X angle between the object's local Y axis and the given
arbitrary global axis
remend
function Angle_LX_Y(obj,ax#,ay#,az#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
nay#=ax#*yx#+ay#*yy#+az#*yz#
naz#=ax#*zx#+ay#*zy#+az#*zz#
angle#=wrapvalue(atanfull(-naz#,nay#))
endfunction angle#
remstart
Returns the local X angle between the object's local Z axis and the given
arbitrary global axis
remend
function Angle_LX_Z(obj,ax#,ay#,az#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
nay#=ax#*yx#+ay#*yy#+az#*yz#
naz#=ax#*zx#+ay#*zy#+az#*zz#
angle#=wrapvalue(atanfull(nay#,naz#))
endfunction angle#
remstart
Returns the local Y angle between the object's local X axis and the given
arbitrary global axis
remend
function Angle_LY_X(obj,ax#,ay#,az#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
nax#=ax#*xx#+ay#*xy#+az#*xz#
naz#=ax#*zx#+ay#*zy#+az#*zz#
angle#=wrapvalue(atanfull(naz#,nax#))
endfunction angle#
remstart
Returns the local Y angle between the object's local Z axis and the given
arbitrary global axis
remend
function Angle_LY_Z(obj,ax#,ay#,az#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
nax#=ax#*xx#+ay#*xy#+az#*xz#
naz#=ax#*zx#+ay#*zy#+az#*zz#
angle#=wrapvalue(atanfull(-nax#,naz#))
endfunction angle#
remstart
Returns the local Z angle between the object's local X axis and the given
arbitrary global axis
remend
function Angle_LZ_X(obj,ax#,ay#,az#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1
nax#=ax#*xx#+ay#*xy#+az#*xz#
nay#=ax#*yx#+ay#*yy#+az#*yz#
angle#=wrapvalue(atanfull(-nay#,nax#))
endfunction angle#
remstart
Returns the local Z angle between the object's local Y axis and the given
arbitrary global axis
remend
function Angle_LZ_Y(obj,ax#,ay#,az#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1
nax#=ax#*xx#+ay#*xy#+az#*xz#
nay#=ax#*yx#+ay#*yy#+az#*yz#
angle#=wrapvalue(atanfull(nax#,nay#))
endfunction angle#
function Angle_Axis(rax#,ray#,raz#,a1x#,a1y#,a1z#,a2x#,a2y#,a2z#)
rem rotate the vectors
rem 1) rotate space about the x axis so that the rotation axis lies in the xz plane
xangle#=atanfull(ray#,raz#)
a1x1#=a1x#
a1y1#=a1y#*cos(xangle#)-a1z#*sin(xangle#)
a1z1#=a1z#*cos(xangle#)+a1y#*sin(xangle#)
a2x1#=a2x#
a2y1#=a2y#*cos(xangle#)-a2z#*sin(xangle#)
a2z1#=a2z#*cos(xangle#)+a2y#*sin(xangle#)
rax1#=rax#
ray1#=ray#*cos(xangle#)-raz#*sin(xangle#)
raz1#=raz#*cos(xangle#)+ray#*sin(xangle#)
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
yangle#=-atanfull(rax1#,raz1#)
a1x2#=a1x1#*cos(yangle#)+a1z1#*sin(yangle#)
a1y2#=a1y1#
a1z2#=a1z1#*cos(yangle#)-a1x1#*sin(yangle#)
a2x2#=a2x1#*cos(yangle#)+a2z1#*sin(yangle#)
a2y2#=a2y1#
a2z2#=a2z1#*cos(yangle#)-a2x1#*sin(yangle#)
angle#=wrapvalue(atanfull(a1x2#,a1y2#)-atanfull(a2x2#,a2y2#))
endfunction angle#
function Angle_Axis_GL(obj,rax#,ray#,raz#,a1x#,a1y#,a1z#,a2x#,a2y#,a2z#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
a2x1#=a2x#*xx#+a2y#*yx#+a2z#*zx#
a2y1#=a2x#*xy#+a2y#*yy#+a2z#*zy#
a2z1#=a2x#*xz#+a2y#*yz#+a2z#*zz#
angle#=Angle_Axis(rax#,ray#,raz#,a1x#,a1y#,a1z#,a2x1#,a2y1#,a2z1#)
endfunction angle#
function Angle_Axis_LG(obj,rax#,ray#,raz#,a1x#,a1y#,a1z#,a2x#,a2y#,a2z#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rax1#=rax#*xx#+ray#*yx#+raz#*zx#
ray1#=rax#*xy#+ray#*yy#+raz#*zy#
raz1#=rax#*xz#+ray#*yz#+raz#*zz#
angle#=Angle_Axis(rax1#,ray1#,raz1#,a1x#,a1y#,a1z#,a2x#,a2y#,a2z#)
endfunction angle#
function Angle_Axis_LL(obj,rax#,ray#,raz#,a1x#,a1y#,a1z#,a2x#,a2y#,a2z#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
a2x1#=a2x#*xx#+a2y#*yx#+a2z#*zx#
a2y1#=a2x#*xy#+a2y#*yy#+a2z#*zy#
a2z1#=a2x#*xz#+a2y#*yz#+a2z#*zz#
rax1#=rax#*xx#+ray#*yx#+raz#*zx#
ray1#=rax#*xy#+ray#*yy#+raz#*zy#
raz1#=rax#*xz#+ray#*yz#+raz#*zz#
angle#=Angle_Axis(rax1#,ray1#,raz1#,a1x#,a1y#,a1z#,a2x1#,a2y1#,a2z1#)
endfunction angle#
function line3d(x#,y#,z#,x2#,y2#,z2#)
make object cube 1000,0
position object 1000,x#,y#,z#
x=object screen x(1000)
y=object screen y(1000)
position object 1000,x2#,y2#,z2#
line object screen x(1000),object screen y(1000),x,y
delete object 1000
endfunction
It includes local, global and custom axis rotations and uses the DBP Euler angles (no vertex magic).