1

I have the x,y position of a body that makes roughly circular orbits around a known point. Is there an algorithm that will give me the number of orbits this body makes over time if I feed it a vector of x,y positions? I don't care about variations in the distance of the body from the "origin" of the orbit.

EDIT 1:

My solution so far:

  1. shift the x,y coords of the body by the x,y position of the orbit origin (i.e. make origin of orbit [0,0])
  2. compute atan2 of body xy to get radians, then convert to degrees
  3. shift degrees so that 0 is start location of body
  4. find all turn points in degree vector (find 359->0 transitions)
  5. count orbits as number of turn points + remainder
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
Ryan Hope
  • 502
  • 2
  • 14
  • Is that vector of x,y positions in any particular order? – Jim Mischel Jun 14 '16 at 13:30
  • Yes it is ordered. – Ryan Hope Jun 14 '16 at 13:39
  • Yeah? *What order?* I'm trying to get you to be more specific in your question. A list of positions doesn't do me any good if it's sorted by increasing `x` value. I *assume* you mean that it's in chronological order, with `a[0]` being the earliest and `a[n]` being the most recent. But your question doesn't state that, so any solution you get might not be valid. – Jim Mischel Jun 14 '16 at 13:47
  • The vectors are the position of the body sampled at regular intervals, so yes chronological order. Sorry, I didn't there could be any other order ;) – Ryan Hope Jun 14 '16 at 14:44

1 Answers1

2

The following algorithm assumes that there are more than 2 positions stored per orbit, with a spacing of less than 180 degrees.

Basically you define a "finishing line" for the orbit using the first position and increment a count when the body crosses it, which you can detect when the sign of the dot product of the position vector with the line normal changes:

  • Take the vector from the known point the body is orbiting around to the first position in your series and find a vector perpendicular to it. In 2D you can do this just by subtracting the center point from the first position, then swapping the x and y components and negating one of them. This vector defines the normal to the "finishing line" of each orbit.
  • Take the vector from the center to second position in the series, and find the dot product with the normal calculated above by multiplying component-wise.
  • Initialize an orbit count to zero
  • For each remaining position in the series:
    • Compute the vector from the center to the position, and the dot product of it with the finishing line normal. If the sign of the dot product the same as that of the second position, and different to the previous position in the series, increase the count by one.

You can work out the fractional part by calculating the angle between the last position and the first.

samgak
  • 23,944
  • 4
  • 60
  • 82
  • The solution can be simplified by converting the x,y coordinates to the angle between the position and the center point by using the atan function. – Eyal Shulman Jun 14 '16 at 13:26
  • 1
    @EyalShulman it depends what you mean by "simplified"? Easier to understand, easier to implement or taking less operations for the CPU? In my opinion dot products are simpler by all 3 criteria (it's just two multiplies and an add), but the first two are admittedly subjective. – samgak Jun 14 '16 at 13:48
  • @EyalShulman Doing that conversion will likely be slower overall than just doing the dot product directly. – SirGuy Jun 14 '16 at 13:51
  • Will the solution be different depending on which direction (clockwise or anti-clockwise) you assume the object is orbiting? – Jim Mischel Jun 14 '16 at 13:52
  • 1
    @JimMischel this algorithm doesn't assume a clockwise or anti-clockwise direction, because it checks whether the sign changes and becomes the same as the the second position, rather than assuming a particular direction and checking if it changes to positive or negative. It will work for both – samgak Jun 14 '16 at 13:55