UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on January 03, 2025, 07:58:13 AM

Title: ClosestPointOnLine Function
Post by: kevin on January 03, 2025, 07:58:13 AM

ClosestPointOnLine  Function

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


[pbcode]


//  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#


[/pbcode]