December 03, 2020, 07:18:50 PM

Author Topic: [bb] Sphere-Box Intersection Routine by simonh [ 1+ years ago ]  (Read 702 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Sphere-Box Intersection Routine
Author : simonh
Posted : 1+ years ago

Description : 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.

Code :
Code: BlitzBasic
  1. ; Sphere-Box Intersection Routine
  2.  
  3. ; Blitz version by si@si-design.co.uk, based on code found at http://www.acm.org/tog/GraphicsGems/gems/BoxSphere.c
  4. ; See also http://www.realtimerendering.com/int/ and http://www.magic-software.com/Intersection.html for some more (non-Blitz flavoured) intersection routines
  5.  
  6. ; This routine is a fast, accurate way of testing to see whether a solid sphere intersects a solid axis-aligned box.
  7. ; Useful to act as an activation zone in games - i.e. if sphere is in invisible zone then activate event.
  8.  
  9. ; Use mouse to rotate camera, left and right mouse buttons to move camera forward/backward
  10. ; Move sphere by using cursor keys and r/f for rise/fall
  11. ; When the sphere touches the box, a 'collision' message should appear in the top-left hand corner of the screen
  12.  
  13. ; Initialise
  14. width=640
  15. height=480
  16.  
  17. Graphics3D width,height,0,2
  18. SetBuffer BackBuffer()
  19.  
  20. MoveMouse width/2,height/2
  21.  
  22. cam=CreateCamera()
  23. PositionEntity cam,0,100,-100
  24. RotateEntity cam,30,0,0
  25.  
  26. light=CreateLight()
  27.  
  28. ; Set dimensions for box/sphere, then create them using these dimensions
  29. bx#=0 ; box x
  30. by#=0 ; box y
  31. bz#=0 ; box z
  32. bw#=50 ; box width
  33. bh#=50 ; box height
  34. bd#=50 ; box depth
  35. sx#=0 ; sphere x
  36. sy#=0 ; sphere y
  37. sz#=0 ; sphere z
  38. sr#=5 ; sphere radius
  39.  
  40. box=CreateCube()
  41. EntityColor box,255,255,0
  42. FitMesh box,0,0,0,bw,bd,bh
  43. PositionEntity box,bx,by,bz
  44.  
  45. sphere=CreateSphere()
  46. EntityColor sphere,255,0,0
  47. ScaleEntity sphere,sr,sr,sr
  48.  
  49. PositionEntity sphere,sx#,sy#,sz#
  50.  
  51. While Not KeyDown(1)
  52.  
  53.         ; Move camera
  54.         mxs=mxs+MouseXSpeed()
  55.         mys=mys+MouseYSpeed()
  56.  
  57.         RotateEntity cam,mys,-mxs,0
  58.         MoveEntity cam,0,0,MouseDown(1)-MouseDown(2)
  59.  
  60.         ; Move sphere
  61.         If KeyDown(203) Then sx#=sx#-1
  62.         If KeyDown(205) Then sx#=sx#+1
  63.         If KeyDown(19) Then sy#=sy#+1
  64.         If KeyDown(33) Then sy#=sy#-1
  65.         If KeyDown(200) Then sz#=sz#+1
  66.         If KeyDown(208) Then sz#=sz#-1
  67.  
  68.         sx#=sx#+mx#
  69.         sy#=sy#+my#
  70.         sz#=sz#+mz#
  71.  
  72.         PositionEntity sphere,sx#,sy#,sz#
  73.  
  74.         RenderWorld
  75.        
  76.         ; Test to see if sphere intersects box
  77.         If SphereBoxIntersection(sx#,sy#,sz#,sr#,bx#,by#,bz#,bw#,bh#,bd#)=True Then Text 0,0,"Collision"
  78.        
  79.         Flip
  80.  
  81. Wend
  82.  
  83.  
  84. Function SphereBoxIntersection(sx#,sy#,sz#,sr#,bx#,by#,bz#,bw#,bh#,bd#)
  85.  
  86.         ; sx#,sy#,sz# = sphere x,y,z centre co-ordinates
  87.         ; sr# = sphere radius
  88.         ; bx#,by#,bz# = box x,y,z corner co-ordinates
  89.         ; bw#,bh#,bd# = box width,height,depth
  90.  
  91.         Local dmin#=0
  92.         Local sr2#=sr*sr
  93.        
  94.         ; x axis
  95.         If sx < bx
  96.  
  97.                 dmin=dmin+((sx-bx)*(sx-bx))
  98.                
  99.         Else If sx>(bx+bw)
  100.  
  101.                 dmin=dmin+(((sx-(bx+bw)))*((sx-(bx+bw))))
  102.  
  103.         EndIf
  104.  
  105.         ; y axis
  106.         If sy < by
  107.  
  108.                 dmin=dmin+((sy-by)*(sy-by))
  109.                
  110.         Else If sy>(by+bh)
  111.  
  112.                 dmin=dmin+(((sy-(by+bh)))*((sy-(by+bh))))
  113.  
  114.         EndIf
  115.  
  116.         ; z axis
  117.         If sz < bz
  118.  
  119.                 dmin=dmin+((sz-bz)*(sz-bz))
  120.  
  121.         Else If sz>(bz+bd)
  122.  
  123.                 dmin=dmin+(((sz-(bz+bd)))*((sz-(bz+bd))))
  124.  
  125.         EndIf
  126.  
  127.         If dmin#<=sr2# Then Return True Else Return False
  128.  
  129. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal