Here is the first entry to get things started.
rem Challenge: Inverse Kinematics
rem Author: AceLepage
rem Date: May 28, 2009
set display mode 1024,768,32
backdrop on
color backdrop 0
Oarm as integer rem object Arm
global OarmA as float rem arm angle
global LarmAx as float rem limb angles
LarmAy as float
LarmAz as float
global LhandAx as float rem limb angles
LhandAy as float
LhandAz as float
global handX as float rem hand position
global handY as float
global handZ as float
LarmAxLower as float rem limb rotation limits
LarmAxUpper as float
LhandAxLower as float
LhandAxUpper as float
global armL as integer rem length of arm segment
global distance as float
global dtt as float rem distance to travel
global camA as float rem camera angle
global camD as float rem camera distance
global camR as float rem camera rotation speed
camY as integer rem camera height
swing as float rem arm swing speed
numobj as integer
numobj=20
dim obj(numobj) as integer
dim leg(numobj) as integer
global nextobj as integer
pick as integer rem object selected for pickup
global speed as integer
nextobj=0
pick=0
Oarm=get_nextobj()
LarmAxLower=-40.0
LarmAxUpper=90.0
LhandAxLower=0.0
LhandAxUpper=165.0
OarmA=0.0
Larm=1
Lelbow=2
Lhand=3
Lfing1=4
Lfing2=5
Lfing3=6
Lfing4=7
Marm=1
Melbow=2
Mfinger=3
LarmAx=0.0
LarmAy=0.0
LarmAz=0.0
LhandAx=LhandAxUpper
LhandAy=0.0
LhandAz=0.0
armL=20
camA=50.0
camD=60.0
camR=0.1
camY=20
swing=0.04
rem Make robot arm
make_texture()
make object sphere Oarm,7
make object cube 2,armL
offset limb 2,0,0,armL/2,0
scale object 2,10,100,10
make mesh from object Marm,2
delete object 2
make object sphere 2,3
make mesh from object Melbow,2
delete object 2
make object triangle 2,0,0,0,armL/10,0,0,armL/20,armL/10,0
offset limb 2,0,-armL/20,0,0
make mesh from object Mfinger,2
delete object 2
add limb Oarm,Larm,Marm
link limb Oarm,0,Larm
add limb Oarm,Lelbow,Melbow
link limb Oarm,Larm,Lelbow
add limb Oarm,Lhand,Marm
add limb Oarm,Lfing1,Mfinger
link limb Oarm,Lhand,Lfing1
add limb Oarm,Lfing2,Mfinger
link limb Oarm,Lhand,Lfing2
add limb Oarm,Lfing3,Mfinger
link limb Oarm,Lhand,Lfing3
add limb Oarm,Lfing4,Mfinger
link limb Oarm,Lhand,Lfing4
link limb Oarm,Larm,Lhand
offset limb Oarm,Lelbow,0,armL,0
offset limb Oarm,Lhand,0,armL,0
offset limb Oarm,Lfing1,1,armL,0
offset limb Oarm,Lfing2,0,armL,1
offset limb Oarm,Lfing3,-1,armL,0
offset limb Oarm,Lfing4,0,armL,-1
rotate limb Oarm,Lfing1,-30,90,0
rotate limb Oarm,Lfing2,-30,0,0
rotate limb Oarm,Lfing3,-30,270,0
rotate limb Oarm,Lfing4,-30,180,0
position object Oarm,0,0,0
texture object Oarm,1
rem Make objects to pick
for x=1 to numobj
leg(x)=get_nextobj()
if x=1
make object cylinder leg(x),1
else
instance object leg(x),leg(1)
endif
next x
for x=1 to numobj
obj(x)=get_nextobj()
if x=1
make object cube obj(x),3
texture object obj(x),2
startobj=obj(x)
else
clone object obj(x),obj(1)
endif
if x=numobj
endobj=obj(x)
endif
d=rnd(30)+10
a=x*360/numobj
h=int(d/10)
scale object leg(x),100,h*100,100
position object obj(x),sin(a)*d,h,cos(a)*d
position object leg(x),sin(a)*d,h/2-0.5,cos(a)*d
next x
rem Make background
make matrix 1,1000,1000,50,50
prepare matrix texture 1,3,1,1
position matrix 1,-500,-1.0,-500
update matrix 1
instructions()
sprite 1,0,0,4
ink rgb(255,255,255),0
while not escapekey()
speed=timer()-set
set=timer()
if not mouseclick()
click=0
endif
if mouseclick() and click=0
click=1
pick=pick object(mousex(),mousey(),startobj,endobj)
if pick
get_hand_position()
endif
endif
control_camera()
if pick
get_hand_position()
rem Calculate distance to object to pick up
diffX#=handX-object position x(pick)
diffY#=handY-object position y(pick)-object size(pick)
diffZ#=handZ-object position z(pick)
pickDist#=sqrt(object position x(pick)^2+object position z(pick)^2)-object size(pick)
pickA#=atanfull(object position x(pick),object position z(pick))
diffA#=OarmA-wrapvalue(pickA#)
diffD#=distance-pickDist#
travelDist#=sqrt((handX-object position x(pick))^2+(handZ-object position z(pick))^2)
rem Calculate arm movement
hit=0
if (abs(diffA#)>swing*2)
if OarmA>180 then OarmA=OarmA-360
diff#=OarmA-pickA#
OarmA=wrapvalue(OarmA-swing*sgn(diff#)*speed)
hit=1
endif
contactD#=sqrt(diffX#^2+diffY#^2+diffZ#^2)
if ( contactD# > object size(pick)*1.5 )
diffY#=handY-object position y(pick)-object size(pick)*2
endif
if (abs(diffY#)>swing*2)
LarmAx=LarmAx+swing*sgn(diffY#)*speed
if (LarmAx>LarmAxUpper)
LarmAx=LarmAxUpper
else
if (LarmAx<LarmAxLower)
LarmAx=LarmAxLower
else
hit=2
endif
endif
endif
if (abs(diffD#)>swing*2)
LhandAx=LhandAx+swing*sgn(diffD#)*speed
if (LhandAx>LhandAxUpper)
LhandAx=LhandAxUpper
else
if (LhandAx<LhandAxLower)
LhandAx=LhandAxLower
else
hit=3
endif
endif
endif
if hit=0
pick=0
endif
endif
yrotate object Oarm,OarmA
rotate limb Oarm,Larm,LarmAx,LarmAy,LarmAz
rotate limb Oarm,Lhand,LhandAx,LhandAy,LhandAz
position camera sin(camA)*camD,camY,cos(camA)*camD
point camera 0,0,0
endwhile
end
function get_hand_position()
a1#=90-LarmAx
a2#=180-LhandAx
X1#=armL*cos(a1#)
Y1#=armL*sin(a1#)
A#=a2#+a1#-90
X2#=armL*sin(A#)
Y2#=armL*cos(A#)
distance=X1#+X2#
handY=Y1#-Y2#
handZ=distance*cos(OarmA)
handX=distance*sin(OarmA)
endfunction
function sgn(num#)
if (num#<0.0)
sign=-1
else
if (num#>0.0)
sign=1
else
sign=0
endif
endif
endfunction sign
function get_nextobj()
inc nextobj
endfunction nextobj
function control_camera()
if leftkey()
camA=camA+camR*speed
endif
if rightkey()
camA=camA-camR*speed
endif
if upkey()
camD=camD-camr*speed
endif
if downkey()
camD=camD+camR*speed
endif
endfunction
function make_texture()
create bitmap 1,256,256
ink rgb(192,192,255),0
box 0,0,255,255
ink rgb(128,128,128),0
for x=0 to 255 step 8
line x,0,x,255
line 0,x,255,x
next x
get image 1,0,0,255,255
ink rgb(128,128,128),0
box 0,0,255,255
ink 0,0
for x=1 to 50
circle 128,128,x
next x
get image 2,0,0,255,255
ink rgb(0,48,0),0
box 0,0,255,255
ink rgb(32,192,32),0
for x=1 to 100
circle rnd(245)+5,rnd(245)+5,rnd(5)+5
next x
get image 3,0,0,255,255
delete bitmap 1
set current bitmap 0
endfunction
function instructions()
create bitmap 1,300,75
ink rgb(192,192,192),0
box 0,0,299,74
ink rgb(255,255,255),0
for x=0 to 4
line x,x,299-x,x
line x,x,x,74-x
next x
ink rgb(128,128,128),0
for x=0 to 4
line 299-x,x,299-x,74-x
line x,74-x,299-x,74-x
next x
ink 0,0
set cursor 0,0
text 5,5,"Inverse Kinematics Challenge"
text 5,25,"Click on a box to activate the arm"
text 5,45,"Control camera with arrow keys"
get image 4,0,0,299,74,1
delete bitmap 1
set current bitmap 0
endfunction
( 2b || !2b ), that is the question. The answer: true