1

i am programing something like planets moving around the Sun, and to move planets i am using a function

CGPointMake(object.center.x + 1, sqrt(75*75*150*150 - 75*75*(object.center.x - 300)*(object.center.x - 300))/150 + 150)

using elliptic equation where a = 150, b = 75, p = 300, q = 150, but when object closes to x = around 450 its speed rises, i guess that is because of pithagoras because the path its passes is c = sqrt((x-x0)^2*(y-y0)^2)

i notice my c is always around 0.5, but when it gets on the end of x domain it rises up to 0.8 so i need either a programatic or mathematical solution to make object move at same speed around an elliptic curve.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Josip Bogdan
  • 578
  • 1
  • 5
  • 15
  • 6
    This is probably more a math or physics question. But as far as I know, planets to *not* move with constant speed on their elliptic orbit. – Martin R Nov 05 '14 at 21:42
  • i know that, but i either need a equation for real planet movement, or solution to the problem above, becouse like this it looks very unreal – Josip Bogdan Nov 05 '14 at 21:56
  • i can solve this by lowering x incerement when object is in x: 150 - 170 range, couse that is where c increases, but that is very bad programing i guess – Josip Bogdan Nov 05 '14 at 22:01
  • @JosipBogdan edited my answer. btw it looks like it works even if the `rx<=ry` (but not sure if in all circumstances ... the only thing that could go wrong is perimeter computation) – Spektre Nov 06 '14 at 21:18

3 Answers3

5

If you want the real thing

then the planets closer to the primary focus point (center of mass of stellar system ... very close to star) are moving faster so use Kepler's equation here: C++ implementation of mine. Do not forget to check out all the sub-links in that answer you can find there everything you need.

If you want constant speed instead

Then use parametric ellipse equation

x(a)=x0+rx*cos(a)
y(a)=y0+ry*sin(a)

where a is angle <0,2.0*PI> (x0,y0) is the ellipse center and (rx,ry) are the ellipse semi axises (radii).

if a is incremented with constant speed then the area increase is constant so the a is the mean circular angle not the visual on ellipse !!! For more info look here:

[edit1] as MartinR pointed out the speed is not constant

so here is approximation with his formula for speed. Ellipse is axis aligned defined by x0,y0,rx,ry (rx>=ry) the perimeter aproximation l:

h=(rx-ry)/(rx+ry); h*=3.0*h; l=M_PI*(rx+ry)*(1.0+(h/(10.0+sqrt(4.0-h))));

if you want to have n chunks of equal sized steps along the perimeter then

l/=n;

initial computations:

double x0,y0,rx,ry,n,l,h;
x0=Form1->ClientWidth>>1;  // center is centered on form
y0=Form1->ClientHeight>>1;
rx=200; // semiaxises rx>=ry !!!
ry=75;
n=40.0; // number of chunks per ellipse (1/speed)
//l=2.0*M_PI*sqrt(0.5*((rx*rx)+(ry*ry)));  // not accurate enough
h=(rx-ry)/(rx+ry); h*=3.0*h; l=M_PI*(rx+ry)*(1.0+(h/(10.0+sqrt(4.0-h)))); // this is more precise
l/=n; // single step size in units,pixels,or whatever

first the slow bruteforce attack (black):

int i;
double a,da,x,y,xx,yy,ll;
a=0.0;
x=x0+rx*cos(a);
y=y0+ry*sin(a);
for (i=n;i>0;i--)
    {
    xx=x; yy=y;
    for (da=a;;)
        {
        a+=0.001;
        x=x0+rx*cos(a);
        y=y0+ry*sin(a);
        ll=sqrt(((xx-x)*(xx-x))+((yy-y)*(yy-y)));
        if (ll>=l) break;
        } da=a-da;
    scr->MoveTo(5.0+50.0*a,5.0);
    scr->LineTo(5.0+50.0*a,5.0+300.0*da);

    scr->MoveTo(x0,y0);
    scr->LineTo(xx,yy);
    scr->LineTo(x ,y );
    ll=sqrt(((xx-x)*(xx-x))+((yy-y)*(yy-y)));
    scr->TextOutA(0.5*(x+xx)+20.0*cos(a),0.5*(y+yy)+20.0*sin(a),floor(ll));
    }

Now the approximation (Blue):

a=0.0; da=0;
x=x0+rx*cos(a);
y=y0+ry*sin(a);
for (i=n;i>0;i--)
    {
    scr->MoveTo(5.0+50.0*a,5.0+300.0*da);
    xx=rx*sin(a);
    yy=ry*cos(a);
    da=l/sqrt((xx*xx)+(yy*yy)); a+=da;
    scr->LineTo(5.0+50.0*a,5.0+300.0*da);

    xx=x; yy=y;
    x=x0+rx*cos(a);
    y=y0+ry*sin(a);

    scr->MoveTo(x0,y0);
    scr->LineTo(xx,yy);
    scr->LineTo(x ,y );
    ll=sqrt(((xx-x)*(xx-x))+((yy-y)*(yy-y)));
    scr->TextOutA(0.5*(x+xx)+40.0*cos(a),0.5*(y+yy)+40.0*sin(a),floor(ll));
    }

This is clean ellipse step (no debug draws)

a=???; // some initial angle
// point on ellipse 
x=x0+rx*cos(a);
y=y0+ry*sin(a);
// next angle by almost constant speed
xx=rx*sin(a);
yy=ry*cos(a);
da=l/sqrt((xx*xx)+(yy*yy)); a+=da;
// next point on ellipse ...
x=x0+rx*cos(a);
y=y0+ry*sin(a);

Here the output of comparison bruteforce and approximation:

this is how the result looks like

[edit2] little precision boost

 a,da=???; // some initial angle and step (last)
 x=x0+rx*cos(a);
 y=y0+ry*sin(a);
 // next angle by almost constant speed
 xx=rx*sin(a+0.5*da); // use half step angle for aproximation ....
 yy=ry*cos(a+0.5*da);
 da=l/sqrt((xx*xx)+(yy*yy)); a+=da;
 // next point on ellipse ...
 x=x0+rx*cos(a);
 y=y0+ry*sin(a);

much closer to bruteforce attack

the half step angle in approximation lead to much closer result to bruteforce attack

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Is your statement about the constant speed really true? The speed is `sqrt(rx^2 * sin^2(a(t)) + ry^2 * cos^2(a(t))) * a'(t)`, and that is not constant even if `a'(t)` is constant (only for the special case of a circle). – Martin R Nov 06 '14 at 17:09
  • @MartinR ow youre right it is the area that is constant not the arclength – Spektre Nov 06 '14 at 18:58
  • @MartinR your equation works added [edit1] to my answer ... the precision of perimeter computation affects this greatly so for high eccentricity is this not very precise. – Spektre Nov 06 '14 at 21:15
  • this looks great, sry for not checking it sooner, thank u so much, ive been working on this for a week myself but this solutin is what I needed, real deal, id very much like to buy u a beer – Josip Bogdan Nov 15 '14 at 15:26
1

Hmm...

You could fake something like this very easily with SpriteKit. N.B. your entire app doesn't have to use SpriteKit. You can fairly easily put an SKView into a non-SpriteKit app.

Anyway...

Create your planet...

SKSpritNode *planet = [SKSpritNode spriteNodeWithImageNamed:@"mars"];
[solarSystemView addChild:planet];

Create your elliptical path...

UIBezierPath *ellipse = [UIBezierPath bezierPathWithOvalInRect:/*your rect*/]; //or create it any other way.

Create an action...

SKAction *singleOrbit = [SKAction followPath:ellipse.CGPath speed:10];
SKAction *orbit = [SKAction repeatActionForever:singleOrbit];

Run the action...

[planet runAction:orbit];
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
-2

In the article "Kinematics of an ellipse", formulas for the movement of a point along an ellipse are presented: 1. uniform, 2. uniformly accelerated, 3. elliptical (Keplerian). It is shown that only when moving 3 Kepler's laws are satisfied https://www.academia.edu/94295697/Ellipse_kinematics