Search code examples
algorithmpathgeometrycoordinate

Point given 2 other points, an angle, and a distance


I'm in need of a general algorithm to calculate the (x,y) coordinates of a point (b), when I have two other points (origin and a), an angle (angle), and a distance (distance).

They will be used like this, to form a solid-filled radial progress indicator:

  • origin is placed at the center of a GUI view
  • a is placed just beyond one of the edges of the view
  • angle is the angle formed from a to origin to b
  • b will be placed somewhere else beyond the edges of the view, such that when the path from a to origin to b is closed and filled, they form a shape with one point at the center and two lines extending to the sides.
  • distance can be considered functionally infinite. For ease of calculation, it can be considered to be equal to the perimeter of the view's bounding box.
Example:
Where `o` is the origin and `A` is the angle:

     a
     .  ------+
     |        |
+----|----+   |
|    |    |   | I can draw more shapes as
|    .A   | --+ necessary to fill other
|   o \   |   | quadrants. I just need `A`
|      \  |   |
+-------\-+   |
         \    |
          \   |
           \  |
            \
             .b

This way, by changing the value of angle and repainting the view, I can have a countdown-clock-style shape.

How do I find the coordinates of b in a generalized algorithm? (I'll be implementing this in more than one language)


Solution

  • If a is directly right of the origin and only b moves: This assumes b is 'leading' a, remember angles are always measured counter-clockwise. In your example A would be the big outer angle, not the small inner one. If you want a to lead b, just use -A instead.

    b = (dist x cos(A), dist x sin(A))
    

    If a is anywhere else than directly right, you have to add the 'starting angle' (between the line formed by going from the origin to the right and the line from the origin to a) to alpha like this:

    beta = angle(right, origin, a)
    b = (dist x cos(A + beta), dist x sin(A + beta))
    

    If origin is not at (0, 0), you will have to add these coordinates to b.

    b = (origin_x + (dist x cos(A + beta)), origin_y + (dist x sin(A + beta)))