我需要一个等式来沿着椭圆运动

乔西普·博格丹(Josip Bogdan)

我正在编写类似行星绕太阳运动的程序,而要移动行星,我正在使用一个函数

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)

其中aangle<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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我需要帮助来理解一个公式

需要选择一个容器来存储我的数据

画一个带边框的椭圆来显示图像

mysqli:为什么我需要一个“ if”语句来创建一个表?

我需要一个main来创建一个静态库吗?

我想用箭头将一个椭圆形的css形状变成椭圆形

我需要一个文档准备工具来记录我的jersey rest网络服务

我是否需要创建一个对象来按我的“数字”元素排序?

我需要一个查询来显示标记表,这里是我的表

为什么我们需要两个接口来枚举一个集合?

我需要帮助来制作一个Java程序,该程序需要一个1到12的数字并输出一个月

我是否需要创建一个 Angular 库来发布一个引用 Angular 类的简单 TS 类

c ++ udp广播。我需要一个套接字来读取和另一个发送吗?

我需要什么环境来运行一个vasturiano 3D-Force Graph?

Java脚本,我需要帮助来解决一个任务

我需要创建一个新列来汇总特定观察发生的实例数量

我需要一个意图来选择特定格式的视频

为什么我们需要另一个模式来进行模式缝合?

我需要一个Mysql查询来执行计算以输出以下代码

为什么我需要一个ToList()来避免处置上下文错误?

我是否需要一个Apple Developer Account来避免Gatekeeper警告?

我需要一个附加属性来监视INotifyDataErrrorInfo的父级

我需要帮助来构建一个返回数组的方法

为什么我需要一个HttpSession来获取ServletContext?

为什么我们需要一个Runnable来启动线程?

替换QuickTest Professional(QTP)-我需要一个工具来测试Java应用程序

我需要一个工具来解析Lua表,最好是在Ruby或Java中

Spring框架,我需要一个变量来依赖于会话

需要一个命令行解析器来满足我的要求