1

I need to calculate which side of a point another point is on and I've been googling around but I have absolutely no idea what all those math equations mean or how they translate into code or JavaScript more specifically.

I have the following information:

  • Point A: x, y and angle (direction which the point is going to, north clockwise)
  • Point B: x and y

Now how do I know whether point B is on the left or the right side of point A? Answers in JavaScript highly appreciated.

jimmone
  • 446
  • 1
  • 6
  • 15
  • A point in itself does not have an angle. What does the angle represent? – orithena Sep 21 '21 at 15:22
  • What is "angle" for a point ? – Tarik Merabet Sep 21 '21 at 15:22
  • Angle represents the direction in degrees (0-360) in which the point is moving – jimmone Sep 21 '21 at 15:24
  • @jimmone And you need the "left or right" info in relation to that movement vector? Then your Point A is not a Point, it represents a Line by specifying a Point and Direction. – orithena Sep 21 '21 at 15:26
  • Correct and thanks for the correction. As you can probably tell I'm very bad at math. – jimmone Sep 21 '21 at 15:27
  • What's the convention for the angle? The point is moving in a direction; how do you calculate the angle for that direction? From North clockwise, from East counterclockwise, something else? – Stef Sep 21 '21 at 15:27
  • 1
    North clockwise – jimmone Sep 21 '21 at 15:29
  • Related: [How to know if point is on the right side or on the left side of line](https://stackoverflow.com/questions/68592435/how-to-know-if-point-is-on-the-right-side-or-on-the-left-side-of-line) – Stef Sep 21 '21 at 15:46

4 Answers4

2

You have:

  • a point A(A.x, A.y);
  • a moving direction for A given as an angle A.angle;
  • a point B(B.x, B.y).

You want to compare the moving direction of A with the direction of vector AB.

Coordinates of vector AB can be computed with a simple subtraction:

AB.x = B.x - A.x
AB.y = B.y - A.y

You can compute the angle corresponding to direction vector AB using atan2. Conveniently, that function is part of most programming languages' standard math library.

When using atan2, we have to be careful about the convention. In the comments, you specified that you wanted the north-clockwise convention. For other conventions, see Wikipedia: atan2 and conventions. We also have to convert from radians to degrees, which can be done easily with the conversion factor 180 / pi.

AB.angle = atan2(AB.x, AB.y) * 180 / pi
if AB.angle < 0:
    AB.angle = AB.angle + 360

Then all we have to do is check whether AB.angle is in interval [A.angle - 180°, A.angle] (left), or in interval [A.angle, A.angle + 180°] (right), while being careful because all calculations are modulo 180°.

// assuming A.angle > 0 && A.angle < 360
if A.angle > 180:
    if AB.angle > A.angle - 180 && AB.angle < A.angle:
        return "Left"
    else:
        return "Right"
else: // A.angle < 180
    if AB.angle > A.angle && AB.angle < A.angle + 180:
        return "Right"
    else:
        return "Left"
Stef
  • 13,242
  • 2
  • 17
  • 28
  • I tried this with following: A.x = 10, A.y = 10, A.angle = 270 and B.x = 5, B.y = 5 but I get "Left" as a result but I think it should be "Right"? – jimmone Sep 22 '21 at 09:48
  • @jimmone A.angle = 270 with north-clockwise convention means A is moving west. B(5,5) and A(10,10) means B is southwest of A. If you're facing west, then a point to your southwest is on your left, not on your right. – Stef Sep 22 '21 at 10:56
  • 1
    @jimmone Unless you are using a different convention for x and y? I forgot to ask. I never use anything else than x->east and y->north and din't realise you might be using another convention. – Stef Sep 22 '21 at 10:56
  • 1
    Oh right thats a good point. I was thinking that y->south. That probably explains why everything I've tried has given me unexpected results. I'm dealing with geo coordinates (latitude, longitude) so I think the convention should be y->north. – jimmone Sep 22 '21 at 11:05
2

Consider sign of expression (if angle is in degrees, multiply it by Math.PI/180 to get radians)

cross = (B.x - A.x)*Math.sin(angle)-(B.y - A.y)*Math.cos(angle)

Edit: for coordinate system OX north, clockwise it is necessary to exchange cos and sin

cross = (B.x - A.x)*Math.cos(angle)-(B.y - A.y)*Math.sin(angle)

Positive value for right side, negative value for left side (or vice versa depending on your coordinate system orientation)

MBo
  • 77,366
  • 5
  • 53
  • 86
  • I tried this with following: A.x = 10, A.y = 10, A.angle = 180 and B.x = 5, B.y = 5 I get cross = -5, which is left. If i change B.y = 15 I get cross = 5, which is right but I don't think that is correct. If angle is 180 then B.y should not affect which side B is, right? – jimmone Sep 22 '21 at 09:37
  • When I draw these data using standard mathematical system - CCW, OX axis right, then, as you wrote, with `B.y = 5` point `B` is left, with `B'.y = 15` it is right, both cases are correct. [Picture](https://i.stack.imgur.com/I5tvH.png) – MBo Sep 22 '21 at 09:45
  • Oh okay so I think there is a problem with the angle convention. I mentioned in the comments that the convention is north clockwise, so if the angle is 180 shouldn't the arrow be pointing down in your picture? – jimmone Sep 22 '21 at 09:53
  • In case `north clockwise` we must exchange cos and sin (rule `cos(90-alpha)=sin(alpha)` and vice versa), so both results will have the same sign – MBo Sep 22 '21 at 09:57
  • Thanks a lot! This is working for me now. – jimmone Sep 22 '21 at 10:02
0

Let's break this up.

  • We've got a directed line L, going through point A in direction a (for angle).
  • We've got a point B.
  • And the question is: Is B left or right of L?

What we need is the angle of the line (against 'north', a.k.a. positive y-axis) that goes through A and B. This allows us to compare those angles:

  • if the difference is in -180°..0° or 180°..360° (-pi..0 or pi..2pi in radians), B is to the left of L,
  • if the difference is in -360°..-180° or 0°..180° (-2pi..-pi or 0..pi in radians), B is to the right of L.

It would be easier to find the right math if your 0°-angle would be 'east, counterclockwise' (as is mathematical convention), but we'll just swap x and y and we're good to go (they're already swapped in the following lines!).

We get that angle (let's call it b) from the points alone, but at first, it'll be in radians (not in degrees):

b_rad = Math.atan((A.x - B.x) / (A.y - B.y));

You did not specify whether the angle is in degrees or radians. Assuming degrees, the result needs to be converted from radians:

b_deg = b_rad * (180 / Math.PI);

Now you only need to take the difference:

delta = a_deg - b_deg;

and use that delta in the comparison I outlined above.

(If I didn't think right, this math gives the opposite results of what is needed -- in this case, you need to swap a_deg and b_deg in the delta calculation)

orithena
  • 1,455
  • 1
  • 10
  • 24
  • I tried this with following: A.x = 10, A.y = 10, A.angle = 180 and B.x = 5, B.y = 5 I get delta = -135, which is left. If i change B.y = 15 I get delta = -255, which is right but I don't think that is correct. If angle is 180 then B.y should not affect which side B is, right? – jimmone Sep 22 '21 at 09:32
  • @jimmone if delta angle is exactly 0° or 180°, "left" and "right" don't make sense, you'd need a third state "on the line" for that -- unless you define it to resolve to either left or right. But that's application-dependent. – orithena Sep 22 '21 at 10:41
-1

if pointB.x < pointA.x it's on the left side.

if pointB.x > pointA.x it's on the right side.

if they are equal, you can't really say who's on the left or on the right.

(that is, of course assuming your coordinate space goes left to right on the x axis)

Luan Nico
  • 5,376
  • 2
  • 30
  • 60
  • Thanks for the answer but I need to take the angle into consideration as well, so for example if the angle is 270 degrees I need to know if point B is on the "north" side of A. – jimmone Sep 21 '21 at 15:23