Code archives/3D Graphics - Maths/Sphere-Box Intersection Routine
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This routine is a fast, accurate way of testing to see whether a solid sphere intersects a solid axis-aligned box. Useful to act as an activation zone in games - i.e. if sphere is in invisible zone then activate event. | |||||
; Sphere-Box Intersection Routine ; Blitz version by si@si-design.co.uk, based on code found at http://www.acm.org/tog/GraphicsGems/gems/BoxSphere.c ; See also http://www.realtimerendering.com/int/ and http://www.magic-software.com/Intersection.html for some more (non-Blitz flavoured) intersection routines ; This routine is a fast, accurate way of testing to see whether a solid sphere intersects a solid axis-aligned box. ; Useful to act as an activation zone in games - i.e. if sphere is in invisible zone then activate event. ; Use mouse to rotate camera, left and right mouse buttons to move camera forward/backward ; Move sphere by using cursor keys and r/f for rise/fall ; When the sphere touches the box, a 'collision' message should appear in the top-left hand corner of the screen ; Initialise width=640 height=480 Graphics3D width,height,0,2 SetBuffer BackBuffer() MoveMouse width/2,height/2 cam=CreateCamera() PositionEntity cam,0,100,-100 RotateEntity cam,30,0,0 light=CreateLight() ; Set dimensions for box/sphere, then create them using these dimensions bx#=0 ; box x by#=0 ; box y bz#=0 ; box z bw#=50 ; box width bh#=50 ; box height bd#=50 ; box depth sx#=0 ; sphere x sy#=0 ; sphere y sz#=0 ; sphere z sr#=5 ; sphere radius box=CreateCube() EntityColor box,255,255,0 FitMesh box,0,0,0,bw,bd,bh PositionEntity box,bx,by,bz sphere=CreateSphere() EntityColor sphere,255,0,0 ScaleEntity sphere,sr,sr,sr PositionEntity sphere,sx#,sy#,sz# While Not KeyDown(1) ; Move camera mxs=mxs+MouseXSpeed() mys=mys+MouseYSpeed() RotateEntity cam,mys,-mxs,0 MoveEntity cam,0,0,MouseDown(1)-MouseDown(2) ; Move sphere If KeyDown(203) Then sx#=sx#-1 If KeyDown(205) Then sx#=sx#+1 If KeyDown(19) Then sy#=sy#+1 If KeyDown(33) Then sy#=sy#-1 If KeyDown(200) Then sz#=sz#+1 If KeyDown(208) Then sz#=sz#-1 sx#=sx#+mx# sy#=sy#+my# sz#=sz#+mz# PositionEntity sphere,sx#,sy#,sz# RenderWorld ; Test to see if sphere intersects box If SphereBoxIntersection(sx#,sy#,sz#,sr#,bx#,by#,bz#,bw#,bh#,bd#)=True Then Text 0,0,"Collision" Flip Wend Function SphereBoxIntersection(sx#,sy#,sz#,sr#,bx#,by#,bz#,bw#,bh#,bd#) ; sx#,sy#,sz# = sphere x,y,z centre co-ordinates ; sr# = sphere radius ; bx#,by#,bz# = box x,y,z corner co-ordinates ; bw#,bh#,bd# = box width,height,depth Local dmin#=0 Local sr2#=sr*sr ; x axis If sx < bx dmin=dmin+((sx-bx)*(sx-bx)) Else If sx>(bx+bw) dmin=dmin+(((sx-(bx+bw)))*((sx-(bx+bw)))) EndIf ; y axis If sy < by dmin=dmin+((sy-by)*(sy-by)) Else If sy>(by+bh) dmin=dmin+(((sy-(by+bh)))*((sy-(by+bh)))) EndIf ; z axis If sz < bz dmin=dmin+((sz-bz)*(sz-bz)) Else If sz>(bz+bd) dmin=dmin+(((sz-(bz+bd)))*((sz-(bz+bd)))) EndIf If dmin#<=sr2# Then Return True Else Return False End Function |
Comments
None.
Code Archives Forum