Main Menu

ClosestPointOnLine Function

Started by kevin, January 03, 2025, 07:58:13 AM

Previous topic - Next topic

kevin


ClosestPointOnLine  Function

    This function will return the coordinates that are closest to the provided line fragment. 


PlayBASIC Code: [Select]
//  Slow program down to a max of 30 frames per second 
SetFPS 30

// Ball properties
BallRadius# = 20

// Moving Ball
Ball1X# = 200
Ball1Y# = 300

// Stationary Ball
Ball2X# = 500
Ball2Y# = 300

// Main Loop
Do
Cls

// Attached ball #1 to the mouse for this demo
Ball1X#=mousex()
Ball1Y#=mousey()

// Draw stationary ball
Ink RGB(0, 255, 0)
Circle Ball2X#, Ball2Y#, BallRadius#, 1

Ink RGB(255, 0, 0)
Circle Ball1X#, Ball1Y#, BallRadius#, 1



// DRaw a line from the Ball #1 200 unit froms the balls
// current line
dx#= cos(angle#)*200
dy#= sin(angle#)*200

x2#= Ball1X# + dx#
y2#= Ball1Y# + dy#

// Draw movement vector
Ink RGB(255, 255, 0)
Line Ball1X#, Ball1Y#, x2#,y2#

// Compute the closest point alone the line to the target ball #2
cx#,cy#=ClosestPointOnLine(Ball1X#, Ball1Y#, x2#,y2#, Ball2X#, Ball2Y#)

// draw the closest point to the line segment
circle cx#,cy#,10,true

// bump the angle to make the test line turn
angle#=wrapangle(angle#,1.5)

Sync
Loop


Function ClosestPointOnLine(X1#, Y1#, X2#, Y2#, PX#, PY#)

// Vector from line start to end
LineDX# = X2# - X1#
LineDY# = Y2# - Y1#

// Vector from line start to point
PointDX# = PX# - X1#
PointDY# = PY# - Y1#

// Calculate the length squared of the line
LineLengthSquared# = (LineDX# * LineDX#) + (LineDY# *LineDY#)
If LineLengthSquared# = 0
// Line start and end are the same point
ExitFunction X1#,Y1#
EndIf

// Calculate projection factor (dot product normalized by line length squared)
Projection# = (PointDX# * LineDX# + PointDY# * LineDY#) / LineLengthSquared#

// Clamp the projection factor between 0 and 1 to ensure it's on the segment
Projection#=cliprange#(Projection#,0,1)

// Find the closest point
ClosestX# = X1# + Projection# * LineDX#
ClosestY# = Y1# + Projection# * LineDY#
EndFunction ClosestX#, ClosestY#