Calculating point on line
Monkey Forums/Monkey Programming/Calculating point on line
| ||
![]() I know the positions of points A, B and C. Know I want to calculate the position of point X (the y coordinate). I know how to get Distance and Angle between those points but what I need is the specific point X. |
| ||
More likely a few ways of doing this. One method would be to use "line intersect" algorithm using points A(xy) to B(xy) and C(xy) to D(xy). D being C with the y flipped. Line intersect code easily found on the Blitz forums, or to save time here's a link to one GfK wrote : http://www.blitzmax.com/codearcs/codearcs.php?code=2597 |
| ||
you can do it with vector math projection. Give me a few and I will post some code for you. |
| ||
I have some line intersect code over on bb.com - its blitzmax code, but maths is maths. |
| ||
I hope you understand it:Strict Import Mojo Class Point Field x:Float Field y:Float End Class Class Vector Field p1:Point Field p2:Point Field vx:Float Field vy:Float Field dx:Float Field dy:Float Field length:Float Method New() p1 = New Point p2 = New Point End Method Method display:Void() DrawLine p1.x,p1.y,p2.x,p2.y End Method End Class Function Main:Int() New game Return 0 End Function Class game Extends App Field ac:Vector Field ab:Vector Field tvx:Float Field tvy:Float Method OnCreate:Int() ac = New Vector ac.p1.x = 100 ac.p1.y = 100 ac.p2.x = 150 ac.p2.y = 0 'calculate vector components ac.vx = ac.p2.x - ac.p1.x ac.vy = ac.p2.y - ac.p1.y 'calculate length of vector ac.length = Sqrt(ac.vx*ac.vx+ac.vy*ac.vy) 'calculate normals ac.dx = ac.vx/ac.length ac.dy = ac.vy/ac.length ab = New Vector ab.p1.x = 100 ab.p1.y = 100 ab.p2.x = 200 ab.p2.y = 100 'calculate vector components ab.vx = ab.p2.x - ab.p1.x ab.vy = ab.p2.y - ab.p1.y 'calculate length of vector ab.length = Sqrt(ab.vx*ab.vx+ab.vy*ab.vy) 'calculate normas ab.dx = ab.vx/ab.length ab.dy = ab.vy/ab.length 'projection of ac onto ab '************************************************************* Local dotproduct:Float = ac.vx*ab.dx+ac.vy*ab.dy tvx = dotproduct*ab.dx tvy = dotproduct*ab.dy '************************************************************** SetUpdateRate(60) Return 0 End Method Method OnUpdate:Int() Return 0 End Method Method OnRender:Int() Cls() ac.display() ab.display() SetColor 255,0,0 DrawLine ab.p1.x,ab.p1.y,ab.p1.x+tvx,ab.p1.y+tvy Return 0 End Method End Class tvx and tvy is the point on the line relative to point a. [edited] corrected an error in the first vector component math |
| ||
@Jesse Great, only one problem. When the line from a to b is not a straight line the results are not correct (so when ab.p2.y <> ac.p1.y) What I want to do is to check if the player(Point C) is below A to B (which represents the ground). |
| ||
sorry, small miss calculation in the first vector component math. Corrected post. |
| ||
What I want to do is to check if the player(Point C) is below A to B (which represents the ground). that is also possible with the dot product of the left normal: dp = ac.vy*ab.dx- ac.vx*ab.dy if dp > 0 point b is above the line(on the left hand side of the line) if dp < 0 point b is below the line ( on the right hand side of the line) if dp = 0 point b is on the line |
| ||
Thanks a lot, I should definitely learn some vector math. Here is Jesse's example updated how I intended it (just a few lines) Strict 'buildopt: run 'buildopt: html5 'buildopt: debug Import Mojo Class Point Field x:Float Field y:Float End Class Class Vector Field p1:Point Field p2:Point Field vx:Float Field vy:Float Field dx:Float Field dy:Float Field length:Float Method New() p1 = New Point p2 = New Point End Method Method display:Void() DrawLine p1.x,p1.y,p2.x,p2.y End Method End Class Function Main:Int() New game Return 0 End Function Class game Extends App Field ac:Vector Field ab:Vector Field tvx:Float Field tvy:Float Field dp:Float 'for checking if point is below line (if dp > 0) Method OnCreate:Int() ac = New Vector ac.p1.x = 100 ac.p1.y = 100 ac.p2.x = 150 ac.p2.y = 0 'calculate vector components ac.vx = ac.p2.x - ac.p1.x ac.vy = ac.p2.y - ac.p1.y 'calculate length of vector ac.length = Sqrt(ac.vx*ac.vx+ac.vy*ac.vy) 'calculate normals ac.dx = ac.vx/ac.length ac.dy = ac.vy/ac.length ab = New Vector ab.p1.x = 100 ab.p1.y = 100 ab.p2.x = 200 ab.p2.y = 120 'calculate vector components ab.vx = ab.p2.x - ab.p1.x ab.vy = ab.p2.y - ab.p1.y 'calculate length of vector ab.length = Sqrt(ab.vx*ab.vx+ab.vy*ab.vy) 'calculate normas ab.dx = ab.vx/ab.length ab.dy = ab.vy/ab.length 'projection of ac onto ab '************************************************************* Local dotproduct:Float = ac.vx*ab.dx+ac.vy*ab.dy tvx = dotproduct*ab.dx tvy = dotproduct*ab.dy '************************************************************** SetUpdateRate(60) Return 0 End Method Method OnUpdate:Int() ac.p2.x = MouseX() ac.p2.y = MouseY() 'Updating vector components ac.vx = ac.p2.x - ac.p1.x ac.vy = ac.p2.y - ac.p1.y ac.length = Sqrt(ac.vx*ac.vx+ac.vy*ac.vy) ac.dx = ac.vx/ac.length ac.dy = ac.vy/ac.length 'update dp dp = ac.vy*ab.dx- ac.vx*ab.dy Return 0 End Method Method OnRender:Int() Cls() Print dp If dp > 0 SetColor 255,0,0 Else SetColor 255, 255, 255 End ac.display() ab.display() Return 1 End Method End |