我正在编写类似行星绕太阳运动的程序,而要移动行星,我正在使用一个函数
CGPointMake(object.center.x + 1, sqrt(75*75*150*150 - 75*75*(object.center.x - 300)*(object.center.x - 300))/150 + 150)
使用椭圆方程,其中a = 150,b = 75,p = 300,q = 150,但是当对象接近x = 450左右时,其速度会上升,我想这是由于pitagora所致,因为其经过的路径是c = sqrt( (x-x0)^ 2 *(y-y0)^ 2)
我注意到我的c总是在0.5左右,但是当它到达x域的末端时,它会上升到0.8,所以我需要一个程序或数学的解决方案来使对象绕椭圆曲线以相同的速度移动
谢谢!
如果你想要真实的东西
那么靠近主要焦点(恒星系统的质量中心...非常靠近恒星)的行星运动得更快,因此请在此处使用开普勒方程式:我的C ++实现。不要忘记查看该答案中的所有子链接,您可以在其中找到所需的一切。
如果要恒定速度
然后使用参数椭圆方程
x(a)=x0+rx*cos(a)
y(a)=y0+ry*sin(a)
其中a
angle<0,2.0*PI>
(x0,y0)
是椭圆中心,(rx,ry)
是椭圆半轴(半径)。
如果a
以恒定速度增加,则面积增加是恒定的,因此a
,平均圆角不是椭圆上的可见角!!!有关更多信息,请参见此处:
[edit1]正如MartinR所指出的,速度不是恒定的
所以这是他的速度公式的近似值。椭圆是由x0,y0,rx,ry
(rx>=ry)
周边近似值定义的轴对齐方式l
:
h=(rx-ry)/(rx+ry); h*=3.0*h; l=M_PI*(rx+ry)*(1.0+(h/(10.0+sqrt(4.0-h))));
如果您希望n
沿周长有相等大小的台阶,那么
l/=n;
初始计算:
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
首先是缓慢的蛮力攻击(黑色):
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));
}
现在近似值(蓝色):
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));
}
这是干净的椭圆形步骤(不进行调试绘制)
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);
这里是比较蛮力和逼近的输出:
[edit2]精度提升不大
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);
近似半步角导致更接近蛮力攻击的结果
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句