Selection Detection with Vector Math
I am currently working on making my own whiteboard program using Dear ImGui, and one of the features I had to implement was the ability to select objects on the whiteboard. Since ImGui does not offer click detections for custom shapes, I had to implement my own selection detection algorithm. With the help of some vector math and the Internet, it was actually quite straightforward.
Framing the Problem
Whether an object should be selected can be framed as asking how close a mouse click is to an object. If the distance is below a threshold, then we can consider the object to be selected.
Let’s reframe this question again in math. Consider a line (segment) with two points, and , and point , where the mouse click happened. The problem is to find a point on that is closest to . Intuitively, that point can be found by drawing a perpendicular line from to , and the intersection point will be the closest point on to . The distance between the two points then becomes the closest distance between and . Below is an illustration of the problem:
where:
- is the point where the mouse click occurred;
- is the line that can be selected; and
- is the shortest distance between and .
Applying Vector Math
Notice how the letter is bolded. This means that the line is treated as a vector. Now, we introduce another vector from the beginning of to . Observe that the projection of onto points to the shortest point on from .
The projection is written as:
where
- is the magnitude of
- is the unit vector of
Recall that the magnitude of a vector is defined as:
and its unit vector as:
for any finite n-dimensional vector .
Substituting into the projection formula, we get
Finding and
To find , we treat and as two vectors:
Then, we subtract from using vector subtraction:
can be found in a similar fashion.
Finding the Intersection Point
Once the projection vector is found, we add it to to obtain the coordinates of the intersection point:
Computing the Shortest Distance
Finally, to find the shortest distance between and , we now have two choices:
- Find the euclidean distance between and the intersection point
- Perform vector subtraction between the two points, then find its magnitude.
In either case, we have successfully found the shortest distance between a point and a line segment!
Special Cases
There are two special cases that we have not considered:
- The projection of the point falls outside of to the left of it
- The projection of the point falls outside of to the right of it
In the first case, the dot product is less than zero. Therefore, if we find that the dot product is less than zero, we know that the closest point from to is the starting point of .
In the second case, the projection of onto is longer than . We can write this relation as:
Therefore, when is greater than , we know that we are in the second case, and we can infer that the end point of is the closest to .
Implementation Note
At the final step of finding the distance between a point and the intersection point, a square root is involved using either method. Since we only care about whether the distance meets a threshold and not the actual number, we can skip the square root calculation and compare it with the square of the threshold we want. For example, if we want the threshold to be 5px for an object to be considered selected, we compare the computation with .