News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Line Intersect Circle (Ray intersection)

Started by kevin, July 29, 2005, 12:51:48 PM

Previous topic - Next topic

kevin


In previous versions of PlayBASIC prior to PlayBASIC V1.083 (beta at this point) the LineIntersectCircle function would produce some rather odd results.  Anyway while fixing that, i've also expanded it to solve the number of intersections the ray has with the circle.

You can customize the type of intersection you want too.   Currently it can either return then First intersection point, or both (if two exist)  as well as selectively returning the normals at the point of intersection.

it's important to note the it only returns the intersection point.  So the ray has to hit the circle. IF the ray is totally inside the circle, then no impact will register.


PlayBASIC Code: [Select]
ScreenWidth=GetScreenWidth()
ScreenHeight=GetScreenHeight()

` =================================
` Create A screen full of Ranodom Circles
` =================================

Max_of_Circles=100

Dim Max_numb_of_wall_Segments(1)
Max_numb_of_wall_Segments(1)=Max_of_Circles

Dim Circles_Xpos#(Max_of_Circles)
Dim Circles_Ypos#(Max_of_Circles)
Dim Circles_Radius#(Max_of_Circles)

For lp =0 To Max_of_Circles
; Set this circles X position
Circles_Xpos#(lp) =Rnd(ScreenWidth)
; Set this circles Y position
Circles_Ypos#(lp) =Rnd(ScreenHeight)
; Set this circles Radius
Circles_Radius#(lp) =RndRange(20,30)
Next lp


` --------------------------------------
` Create the Players Variables
` --------------------------------------

PlayerDir# =90
PlayerX# =500
PlayerY# =200
PlayerRadius# =20
PlayerSpeed =5


Do
Cls 0
Text 0,0,FPS()

` --------------------------------------
` Handle the PLayers/Object Movement
` --------------------------------------

move#=0
If UpKey() Then move#=playerspeed
If DownKey() Then move#=-playerspeed
If LeftKey() Then playerdir#=WrapAngle(playerdir#,-3)
If RightKey() Then playerdir#=WrapAngle(playerdir#,3)

If move#<>0
` Clip PLayers position to screen limits
If playerx#<0 Then playerx#=screenwidth
If playerx#>screenwidth Then playerx#=0
If playery#<0 Then playery#=screenHeight
If playery#>screenheight Then playery#=0
playerx#=playerx#+CosRadius(playerdir#,move#)
playery#=playery#+SinRadius(playerdir#,move#)
EndIf


` --------------------------------------
` Render the Player/Object
` --------------------------------------

LockBuffer
CircleC playerx#,playerY#,playerRadius#,0,$ffffff

playerx2#=CosNewValue(PLayerx#,playerdir#,200)
playery2#=SinNewValue(PLayery#,playerdir#,200)
LineC playerx#,playery#,playerx2#,playery2#,RGB(255,0,0)

` -----------------------------------------------------
` Render Lines and Check For Intersections with player
` -----------------------------------------------------

For lp =0 To Max_of_Circles
x#=Circles_Xpos#(lp)
y#=Circles_Ypos#(lp)
R#=Circles_Radius#(lp)

; =========================================================================
; Check for an intersection between our ray (from the player) and this circle.
; The intersection mode is set to return 2 points (if it intersects twice)
; as well as the normals at each intersection point.
; =========================================================================
result= LineIntersectCircle(Playerx#,playery#,playerx2#,playery2#,x#,y#,R#,2+4)

if result
CircleC x#,y#,r#,0,RGB(255,0,0)
For IMpacts=0 to result-1
ix#=GetIntersectX#(impacts)
iy#=GetIntersectY#(impacts)
Circle ix#,iy#,5,1
nx#=GetNormalX#(impacts)
ny#=GetNormalY#(impacts)
linec ix#,iy#,ix#+(nx#*50),iy#+(ny#*50),rgb(0,255,0)
next
Else
CircleC x#,y#,r#,0,RGB(255,255,255)
EndIf
Next lp
UnLockBuffer

Sync
Loop