Post by tsh73 on Mar 30, 2024 14:02:21 GMT -5
Pair to
libertybasiccom.proboards.com/thread/2413/line-clipping-alogorithm
Clip line segment against circle.
libertybasiccom.proboards.com/thread/2413/line-clipping-alogorithm
Clip line segment against circle.
'clip line segment by circle
'based by parts of
'JB Advanced Collision Tutorial by AndyAmaya
'open GUI
open "Line 2 circle" for graphics_nsb_nf as #gr
#gr "home; down; posxy cx cy"
#gr "trapclose [quit]"
'register mid rectangle
R=int(2*cx/3)
print "Circle at ";cx; " ";cy
print "Radius ";R
#gr "place ";cx;" ";cy
#gr "circle ";R
#gr "when leftButtonDown [down]"
#gr "when leftButtonUp [up]"
wait
'then mouseDown startDraw
[down]
p1.X=MouseX
p1.Y=MouseY
wait
'then mouseUp draw line
[up]
p2.X=MouseX
p2.Y=MouseY
print "Line "
print p1.X,p1.Y,p2.X,p2.Y
#gr "color black"
#gr "line ";p1.X;" ";p1.Y; " ";p2.X;" ";p2.Y
lin2$=ClipSegmentCrcl$(p1.X,p1.Y,p2.X,p2.Y, cx, cy, R)
'res=c2L(p1.X,p1.Y,p2.X,p2.Y, cx, cy, R)
if lin2$="" then
'if not(res) then
print ,"No intersect"
else
print ,"Clipped segment"
print lin2$
#gr "color red"
#gr "line ";lin2$
'#gr "line ";p1.X;" ";p1.Y; " ";p2.X;" ";p2.Y
end if
wait
[quit]
timer 0
close #gr
end
'from 'JB Advanced Collision Tutorial by AndyAmaya
'=======================================================================
Function c2L(x1, y1, x2, y2, cx, cy, cr)
'=====================================================================
' Circle To Line Function
'
' This function checks if a circle has collided with a line
'=====================================================================
' x1, y1, x2, y2 are the two coordinates defining the line to check
'
' cx, cy are the coordinates of the center of the circle
' cr is the radius of the circle
'=====================================================================
' c2L returns a 1 if the circle has collided with the line
'
' c2L returns a 0 (zero) if no collsion has occurred
'=====================================================================
d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)
If d <> 0 Then d = ((cx-x1)*(x2-x1) + (cy-y1)*(y2-y1))/ d
'Clip To the line segments legal bounds
If d < 0.0 Then d = 0
If d > 1.0 Then d = 1
dx = cx - ( (x2-x1)*d + x1)
dy = cy - ( (y2-y1)*d + y1)
' #gr "place ";(x2-x1)*d + x1;" ";(y2-y1)*d + y1
' #gr "circle ";8
''that's nearest point on a line to center
c2L = ( dx*dx + dy*dy <= cr * cr )
end function
function ClipSegmentCrcl$(x1, y1, x2, y2, cx, cy, cr)
if not(c2L(x1, y1, x2, y2, cx, cy, cr)) then exit function
'else go and get that intersection points
'to square equation
'x(t)=(x2-x1)*t + x1
'y(t)=(y2-y1)*t + y1
'(cx-x)^2+(cy-y)^2=R^2
'=>at^2+bt+c=0
dx=x2-x1
dy=y2-y1
a=dx^2+dy^2
cxx=cx-x1
cyy=cy-y1
b=-2*(cxx*dx+cyy*dy)
c=cxx^2+cyy^2-cr^2
D=b^2-4*a*c
if D<0 then exit function 'should not actually be
'our segment has t 0..1, so has to clip by t
t=(0-b+sqr(D))/2/a
if t< 0 then t = 0
if t> 1 then t = 1
p1.X=(x2-x1)*t + x1
p1.Y=(y2-y1)*t + y1
'#gr "place ";(x2-x1)*t + x1;" ";(y2-y1)*t + y1
'#gr "circle ";5
t=(0-b-sqr(D))/2/a
if t< 0 then t = 0
if t> 1 then t = 1
p2.X=(x2-x1)*t + x1
p2.Y=(y2-y1)*t + y1
' #gr "place ";(x2-x1)*t + x1;" ";(y2-y1)*t + y1
' #gr "circle ";5
ClipSegmentCrcl$ = int(p1.X);" ";int(p1.Y) ;" "; int(p2.X);" ";int(p2.Y)
End Function