Jos*_*dan 1 math objective-c swift
我正在编写类似行星绕太阳运动的程序,为了移动行星,我正在使用一个函数
CGPointMake(object.center.x + 1, sqrt(75*75*150*150 - 75*75*(object.center.x - 300)*(object.center.x - 300))/150 + 150)
Run Code Online (Sandbox Code Playgroud)
使用椭圆方程,其中 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)
Run Code Online (Sandbox Code Playgroud)
其中a角度<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))));
Run Code Online (Sandbox Code Playgroud)
如果你想n沿着周边有相同大小的台阶块,那么
l/=n;
Run Code Online (Sandbox Code Playgroud)
初始计算:
x(a)=x0+rx*cos(a)
y(a)=y0+ry*sin(a)
Run Code Online (Sandbox Code Playgroud)
首先是慢速暴力攻击(黑色):
h=(rx-ry)/(rx+ry); h*=3.0*h; l=M_PI*(rx+ry)*(1.0+(h/(10.0+sqrt(4.0-h))));
Run Code Online (Sandbox Code Playgroud)
现在的近似值(蓝色):
l/=n;
Run Code Online (Sandbox Code Playgroud)
这是干净的椭圆步骤(无调试绘制)
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
Run Code Online (Sandbox Code Playgroud)
这里比较蛮力和近似的输出:

[edit2] 小精度提升
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));
}
Run Code Online (Sandbox Code Playgroud)

近似的半步角导致更接近暴力攻击的结果
| 归档时间: |
|
| 查看次数: |
1893 次 |
| 最近记录: |