Well yeah, I mean the only situations in which the interpolated euler path will exactly follow the axis-angled one are when two of the euler angles are kept at zero. And, without proper measures taken to handle angle wrapping, only angles of less than 180* (of positive rotation) and that do not cross 360* will work properly. I've modified your code to demonstrate this, by only changing one angle randomly at a time (and adding WASD controls for ease):
hide mouse
global ret_x as float
global ret_y as float
global ret_z as float
set camera range .01,100
make object sphere 1,.1
make object sphere 2,.1
PxImg(1,rgb(0,255,0))
PxImg(2,rgb(0,0,255))
autocam off
texture object 1,1
texture object 2,2
make object box 3,.1,2,.1
make object box 4,.1,2,.1
global totalObject as integer
totalObject=20
type vect3
x as float
y as float
z as float
endtype
rotStart as vect3
rotEnd as vect3
eulInterp as vect3
T as float
null=make matrix4(1)
null=make vector3(2)
null=make vector3(3)
null=make vector3(4)
null=make vector4(5)
null=make matrix4(6)
redo:
rotStart.x=0.0
rotStart.y=0.0
rotStart.z=0.0
rotEnd.x=0.0
rotEnd.y=0.0
rotEnd.z=0.0
a=rnd(2)
if a=0 then rotStart.x=rnd(360)*0.0174532
if a=1 then rotStart.y=rnd(360)*0.0174532
if a=2 then rotStart.z=rnd(360)*0.0174532
if abs(rotStart.x)>0.00001 then rotEnd.x=rnd(360)*0.0174532
if abs(rotStart.y)>0.00001 then rotEnd.y=rnd(360)*0.0174532
if abs(rotStart.z)>0.00001 then rotEnd.z=rnd(360)*0.0174532
eulInterp=rotStart
angToMatrix(1,rotStart.x,rotStart.y,rotStart.z)
position object 1,m4Element(1,1,2),m4Element(1,2,2),m4Element(1,3,2)
set vector3 2,m4Element(1,1,2),m4Element(1,2,2),m4Element(1,3,2)
angToMatrix(1,rotEnd.x,rotEnd.y,rotEnd.z)
position object 2,m4Element(1,1,2),m4Element(1,2,2),m4Element(1,3,2)
set vector3 3,m4Element(1,1,2),m4Element(1,2,2),m4Element(1,3,2)
n#=acos(dot product vector3(2,3))*0.0174532
cross product vector3 4,2,3
normalize vector3 4,4
sync rate 60
T=0.0
marktime=0
do
rotate camera camera angle x()+mousemovey()*.1,camera angle y()+mousemovex()*.1,0
`move camera ((mouseclick()=1)-(mouseclick()=2))/10.0
if keystate(17) then move camera 0,0.1
if keystate(31) then move camera 0,-0.1
if keystate(30) then yrotate camera 0,camera angle y(0)-90 : move camera 0,0.1 : yrotate camera 0,camera angle y(0)+90
if keystate(32) then yrotate camera 0,camera angle y(0)+90 : move camera 0,0.1 : yrotate camera 0,camera angle y(0)-90
if T>=0.0 and T<1.0
T=T+.0055555
endif
inc marktime
angToMatrix(1,rotStart.x,rotStart.y,rotStart.z)
rotateAxis(6,1,4,T*n#)
MatrixToAng(6)
rotate object 4,ret_x,ret_y,ret_z
rotate object 3,((rotEnd.x-rotStart.x)*T+rotStart.x)*57.2957795,((rotEnd.y-rotStart.y)*T+rotStart.y)*57.2957795,((rotEnd.z-rotStart.z)*T+rotStart.z)*57.2957795
if marktime>5
angToMatrix(1,(rotEnd.x-rotStart.x)*T+rotStart.x,(rotEnd.y-rotStart.y)*T+rotStart.y,(rotEnd.z-rotStart.z)*T+rotStart.z)
marker(m4Element(1,1,2),m4Element(1,2,2),m4Element(1,3,2),rgb(255,0,0))
angToMatrix(1,ret_x*0.0174532,ret_y*0.0174532,ret_z*0.0174532)
marker(m4Element(1,1,2),m4Element(1,2,2),m4Element(1,3,2),rgb(0,255,0))
marktime=0
endif
if spacekey()
deleteMarkers()
wait 200
goto redo
endif
sync
loop
null=delete matrix4(1)
null=delete vector3(2)
null=delete vector3(3)
null=delete vector3(4)
null=delete vector4(5)
end
function PxImg(image as integer, color as dword)
n=findFreeMemblock()
make memblock n,16
write memblock dword n,0,1
write memblock dword n,4,1
write memblock dword n,8,32
write memblock dword n,12,color
make image from memblock image,n
delete memblock n
endfunction
function findFreeMemblock()
for i = 1 to 255
if memblock exist(i) = 0
exitfunction i
endif
next i
endfunction 0
function rotateAxis(result as integer,matrix4 as integer,axis3 as integer,angle as float)
null= make matrix4(1004)
null=make vector4(1005)
build rotation axis matrix4 1004,axis3,angle
multiply matrix4 result,matrix4,1004
null=delete vector4(1005)
null=delete matrix4(1004)
endfunction
function angToMatrix(retMatrix,x as float, y as float, z as float)
null=make matrix4(1000)
null=make matrix4(1001)
null=make matrix4(1002)
null=make matrix4(1003)
rotate x matrix4 1000,x
rotate y matrix4 1001,y
rotate z matrix4 1002,z
multiply matrix4 1003,1000,1001
multiply matrix4 retMatrix,1003,1002
null=delete matrix4(1000)
null=delete matrix4(1001)
null=delete matrix4(1002)
null=delete matrix4(1003)
endfunction
function matrixToAng(C)
C31 as float
C32 as float
C33 as float
C21 as float
C11 as float
C31=M4Element(C,3,1)
C32=M4Element(C,3,2)
C33=M4Element(C,3,3)
C21=M4Element(C,2,1)
C11=M4Element(C,1,1)
if absolut(C31)<>1
ret_y=-asin(C31)
ret_x=atanfull(C32/cos(ret_y),C33/cos(ret_y))
ret_z=atanfull(C21/cos(ret_y),C11/cos(ret_y))
else
ret_z=0
ret_y=posneg(C31,90)
ret_x=atanfull(posneg(C31,C13),posneg(C31,C13))
endif
endfunction
function posneg(a#,num#)
if a#<0 then exitfunction -num#
if a#>0 then exitfunction num#
endfunction 0.0
function m4Element(m4,row,column)
n#=get matrix4 element(m4,(column-1)*4+row-1)
endfunction n#
function absolut(a#)
if a#>0 then exitfunction a#
a#=-a#
endfunction a#
function marker(x as float, y as float, z as float, color as dword)
make object sphere totalObject,.05
color object totalObject,color
position object totalObject,x,y,z
inc totalObject
endfunction
function deleteMarkers()
for n=20 to totalObject-1
delete object n
next
endfunction
Basically, all this goes to say that linear interpolation of euler angles should never be used for a direct route because really, it's just not how euler angles were meant to be used. When you simply add to a euler angle, it just pushes the point around one of three, although orthogonal to each other, arbitrarily oriented axes, which could very well (and often does) do absolutely nothing to help you reach point B. If you generate the appropriate quaternion on the other hand, adding or subtracting to the W value
does push you along the most direct route to point B. It's kinda like cutting down a tree with a paperclip. You
could use the paperclip (which was intended to keep papers neat and organized) to whittle away at the tree until it falls, but why would you do that when you can use a chainsaw?