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. image graph

  • 1
    \$\begingroup\$ Well if two points have the same x use vertical, same y use horizontal, different x and y use diagonal, right? \$\endgroup\$ – Daniel Sep 26 '15 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\$ – Sutty1000 Sep 26 '15 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\$ – Daniel Sep 26 '15 at 12:09

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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.