1
+ /**********************************************************************************************
2
+ *
3
+ * raylib-extras, closest point on a line to another point
4
+ *
5
+ * LICENSE: MIT
6
+ *
7
+ * Copyright (c) 2024 Jeffery Myers
8
+ *
9
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ * of this software and associated documentation files (the "Software"), to deal
11
+ * in the Software without restriction, including without limitation the rights
12
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the Software is
14
+ * furnished to do so, subject to the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be included in all
17
+ * copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *
27
+ **********************************************************************************************/
28
+
29
+ #include "raylib.h"
30
+ #include "raymath.h"
31
+
32
+
33
+ // the line we want to test against
34
+ Vector2 LineSP = { 100 , 100 };
35
+ Vector2 LineEP = { 500 , 500 };
36
+
37
+ // the point that is on the line that is closest to the mouse
38
+ Vector2 NearestPoint = { 0 };
39
+
40
+ // is the nearest point actualy on the line, or outside it's SP/EP
41
+ bool OnLine = false;
42
+
43
+ void GameInit ()
44
+ {
45
+ LineEP .x = GetScreenWidth () - LineSP .x ;
46
+ LineEP .y = GetScreenHeight () - LineSP .y ;
47
+ }
48
+
49
+ bool GameUpdate ()
50
+ {
51
+ if (IsMouseButtonPressed (MOUSE_BUTTON_LEFT ))
52
+ {
53
+ LineSP = GetMousePosition ();
54
+ }
55
+
56
+ if (IsMouseButtonDown (MOUSE_BUTTON_LEFT ))
57
+ {
58
+ LineEP = GetMousePosition ();
59
+ }
60
+ else
61
+ {
62
+ // compute the vector for the line
63
+ Vector2 lineVec = Vector2Subtract (LineEP , LineSP );
64
+
65
+ // see how long the line is
66
+ float magnatude = Vector2Length (lineVec );
67
+
68
+ // normalize the vector so it's just a direction
69
+ lineVec = Vector2Normalize (lineVec );
70
+
71
+ // compute the vector from a point on the line to the mouse
72
+ Vector2 vecToMouse = Vector2Subtract (GetMousePosition (), LineSP );
73
+
74
+ // the dot product is the distance along the vector from the point to the 'leg' of the triangle made
75
+ // between the vector to the mouse and the vector of the line, thus this is the distance from
76
+ // the start point to the nearest point on the line to the mouse
77
+ float dot = Vector2DotProduct (vecToMouse , lineVec );
78
+
79
+ // compute the actual point relative to the start point
80
+ NearestPoint = Vector2Add (LineSP , Vector2Scale (lineVec , dot ));
81
+
82
+ // if the distance is less than 0, then the nearest point is behind the start point
83
+ // if the distance is larger than the line length, then it's off the end
84
+ OnLine = dot >= 0 && dot <= magnatude ;
85
+ }
86
+
87
+ return true;
88
+ }
89
+
90
+ void Draw2D ()
91
+ {
92
+ // draw our line
93
+ DrawLineV (LineSP , LineEP , WHITE );
94
+
95
+ // draw the nearest point if we are not dragging a line
96
+ if (!IsMouseButtonDown (MOUSE_BUTTON_LEFT ))
97
+ DrawCircleV (NearestPoint , 10 , OnLine ? YELLOW : RED );
98
+
99
+ DrawText ("Drag to draw new line" , 0 , 0 , 20 , WHITE );
100
+ }
101
+
102
+ void GameDraw ()
103
+ {
104
+ BeginDrawing ();
105
+ ClearBackground (DARKGRAY );
106
+ Draw2D ();
107
+ DrawFPS (0 , GetScreenHeight () - 20 );
108
+ EndDrawing ();
109
+ }
110
+
111
+ int main ()
112
+ {
113
+ SetConfigFlags (FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE );
114
+ InitWindow (1280 , 800 , "Point on line nearest another point" );
115
+ SetTargetFPS (300 );
116
+
117
+ GameInit ();
118
+
119
+ while (!WindowShouldClose ())
120
+ {
121
+ if (!GameUpdate ())
122
+ break ;
123
+
124
+ GameDraw ();
125
+ }
126
+
127
+ CloseWindow ();
128
+ return 0 ;
129
+ }
0 commit comments