I'm developing an android game and have essentially a grid. The user can drag a line between two points however the line will only ever be vertical, horizontal or diagonal (y=x). So I need to work out given two points which type of line is the best match.
-
1\$\begingroup\$ Well if two points have the same x use vertical, same y use horizontal, different x and y use diagonal, right? \$\endgroup\$– DanielSep 26, 2015 at 11:20
-
\$\begingroup\$ I don't think that will work because even if the x is diff it still might be closer to the vertical point than the diagonal so it should use vertical. \$\endgroup\$– Sutty1000Sep 26, 2015 at 11:50
-
\$\begingroup\$ I think I understand more of what you're going for. For vertical you could compare the horizontal distance from the mouse pointer to the vertical line. Compare that distance to the horizontal distance to the y=x diagonal line for the current mouse y position. Then just pick which ever distance is smaller. For horizontal just do the same thing except compare the vertical distance. \$\endgroup\$– DanielSep 26, 2015 at 12:09
2 Answers
Using vector calculations, you can calculate the angle between the two points, relative to an axis and then based on that angle, choose on how to draw the line.
If you have 2 vectors A and B, you subtract A from B, to get the vector that lies inbetween. You then normalize the result and compare it with a given axis, e.g. y-axis = (0,1). To get the angle between those two, you can use the acos of the dot product of both vectors.
The resulting formula would then be, for an input vector A and B, and the axis C:
angle = acos(dot(normalize(B - A), C))
If you are not familiar with vectors, these are the step-by-step calculations:
AB = B - A = (B.x - A.x | B.y - A.y)
#divide AB by its length, to get a vector of length 1
ABn = normalize(AB) = AB / square root of(AB.x² + AB.y²)
d = dot(ABn, C) = ABn.x * C.x + ABn.y * C.y
angle = acos(d)
The angle will always be between 0° and 180°, no matter on which side of the compared axis it lies. If you compared your vector with the y-axis, you can simply check if
- angle < 30°? -> vertical
- angle < 60°? -> diagonal
- angle < 120°? -> horizontal
- angle < 150°? -> diagonal
- otherwise (between 150-180°) -> vertical
I'm not sure I understood your question, but from what I got, you want the best representation for such line. A simple line containing both points would be the best.
If you want to test if something is inside the line, you want something similar:
Think of it in terms of a line that passes between the two.
It will have a initial point (your first point) and a direction. This direction, once multiplied by a given scalar t, will give you your p1.
Any other point you want to test will be given by that t. If you can't find a valid t, it's not in the line.
If t is negative, then you got something that lies on the infinite line, but not on the p0-p1 segment. If you got a t value bigger than the t that gives you your p1, than such point also lies out of the p0-p1 segment.
Hope it helps