计算给定速度的轨道截距。

2023-12-07

背景: 尝试编写一款“FTL”旅行不受重力影响并且加速度是即时的游戏。

给定行星的开普勒轨道和飞船的当前位置及其最大超光速 (FTL) 速度,如何计算行星的位置。 (单位:米/秒)

我可以获取给定日期时间的行星位置,但我正在努力弄清楚如何计算行星的位置以及将飞船发送到哪里,而不需要围绕轨道追逐行星。


我会重复...

  1. 计算行星与飞船当前位置之间的距离

    由此,您可以计算出如果目标是静态的(不移动),您的船需要多长时间才能达到目标。这次我们打电话吧t.

  2. 计算行星位置actual_time+t并计算t对于这个新职位

    记得最后t让我们称之为t0。然后计算新的t以同样的方式#1但对于之后行星的位置t.

  3. loop #2

    stop if fabs(t-t0)<accuracy.

这个迭代解决方案应该更接近发现t每次迭代除非你的星球移动太快和/或飞船真的太远或太慢(初始t是重要组成部分,甚至比行星回归年还要大)。在这种情况下,你通常会先跳到恒星系统,然后跳到行星(就像原来的《精英》一样)。

对于模糊的行星运动(例如太小的轨道周期),您将需要不同的方法,但要意识到这种情况意味着行星非常靠近恒星或非常重的系统中心质量(例如黑洞)......

在具有恒定 FTL 速度的代码中,它看起来像这样:

vec3 pp,ps=vec3(?,?,?); // planet and ship positions
double t,t0,time;

time=actual_time(); t=0.0;
for (int i=0;i<100;i++) // just avoiding infinite loop in case t/planet_orbit_period>=~0.5
 {
 t0=t;
 pp = planet_position(time+t);
 t=Length(pp-ps)/ship_FTL_speed;
 if (fabs(t-t0)*ship_FTL_speed<=ship_safe_FTL_distance) break;
 }

这应该会很快收敛(比如 5-10 次迭代就足够了)现在t应保留旅行所需的时间和pp应保持您的船应前往的位置。又如何如果i>=100没有找到解决方案,所以你首先需要靠近系统,或者使用更快的 FTL 或使用不同的方法,但这不应该是恒星系统 FTL 中常见的情况,因为行进时间应该远远小于目标轨道周期。 ..

顺便提一句。您可能对此感兴趣:

  • 是否有可能在尺寸和质量方面进行真实的 n 体太阳系模拟?

[Edit1] 比 FTL 翻译驱动器慢

我对其进行了一些教学并稍微改变了算法。首先,它按照某个步骤检查整个行星周期的所有位置(每个周期 100 点),并记住距离飞船最近的时间,无论旅行期间经过的行星周期如何。然后简单地以越来越小的角度步长“递归”检查最佳位置。这里是结果预览:

intercept

并更新了源代码(完整的 VCL 应用程序代码,因此只需使用/移植您需要的内容并忽略其余部分)

//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "win_main.h"
#include "GLSL_math.h"  // just for vec3
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMain *Main;
//---------------------------------------------------------------------------
// constants
const double deg=M_PI/180.0;
const double t_day=60.0*60.0*24.0;
// view
double view_x0=0.0;
double view_y0=0.0;
double zoom=1.0;
// simulation
double sim_t=0.0,sim_dt=0.01*t_day;
//---------------------------------------------------------------------------
void toscr(double &x,double &y)
    {
    x*=zoom; x+=view_x0;
    y*=zoom; y+=view_y0;
    }
//---------------------------------------------------------------------------
class planet                // Kepler body simplified to 2D axis aligned. For fully 3D orbit add mising orbital parameters and equations
    {
public:
    // input parameters
    double a,b,t0,T;        // major axis,minor axis, time where M=E=0.0 deg, orbital period
    // computet parameters
    double c1,c2,e;

    void ld(double _a,double _b,double _t0,double _T)
        {
        // copy input orbital parameters
        a=_a;
        b=_b;
        t0=_t0;
        T=_T;
        // prepare orbital constants
        e=1.0-((b*b)/(a*a));                // eccentricity
        if (e>=1.0) e=0;                    // wrong e
        c1=sqrt((1.0+e)/(1.0-e));           // some helper constants computation
        c2=a*(1-e*e);
        //b=a*sqrt(1.0-e);
        }
    vec3 position(double t) // actual position relative to center mass of the system
        {
        int q;
        vec3 p;
        double E,V,r,M;
        // compute mean orbital position M [rad] from time t
        M=(t-t0)/T;
        M-=floor(M);
        M*=2.0*M_PI;
        // compute real orbital position E [rad] from M
        for (E=M,q=0;q<20;q++) E=M+e*sin(E);// Kepler's equation
        // heliocentric ellipse
        V=2.0*atan(c1*tan(E/2.0));
        r=c2/(1.0+e*cos(V));
        p.x=r*cos(V);
        p.y=r*sin(V);
        p.z=0.0;
        return p;
        }
    void draw_orbit(TCanvas *scr)
        {
        int i;
        double ang,x,y,r,V,E;
        x=a; y=0; toscr(x,y);
        for (i=2,E=0.0;i;E+=3.6*deg)
            {
            if (E>=2.0*M_PI) { E=0.0; i=0; }
            V=2.0*atan(c1*tan(E/2.0));
            r=c2/(1.0+e*cos(V));
            x=r*cos(V);
            y=r*sin(V);
            toscr(x,y);
            if (i==2){ scr->MoveTo(x,y); i=1; }
             else      scr->LineTo(x,y);
            }
        }
    };
//---------------------------------------------------------------------------
class ship                          // Space ship with translation propulsion
    {
public:
    vec3 pos,dir;                   // position and translation direction
    double spd,tim;                 // translation speed and time to translate or 0.0 if no translation
    ship() { pos=vec3(0.0,0.0,0.0); dir=pos; spd=0.0; tim=0.0; }
    void update(double dt)          // simulate dt time step has passed
        {
        if (tim<=0.0) return;
        if (dt>tim) { dt=tim; tim=0.0; }
         else                 tim-=dt;
        pos+=spd*dt*dir;
        }
    void intercept(planet &pl)      // set course for planet pl intercept
        {
        if (spd<=0.0) { tim=0.0; return; }
        const double d=1000000.0;   // safe distance to target
/*
        // [Iteration]
        int i;
        vec3 p;
        double t0;
        for (tim=0.0,i=0;i<100;i++)
            {
            t0=tim;
            p=pl.position(sim_t+tim);
            tim=length(p-pos)/spd;
            if (fabs(tim-t0)*spd<=d) break;
            }
        dir=normalize(p-pos);
*/
        // [search]
        vec3 p;
        int i;
        double tt,t,dt,a0,a1,T;
        // find orbital position with min error (coarse)
        for (a1=-1.0,t=0.0,dt=0.01*pl.T;t<pl.T;t+=dt)
            {
            p=pl.position(sim_t+t);                     // try time t
            tt=length(p-pos)/spd;
            a0=tt-t; if (a0<0.0) continue;              // ignore overshoots
            a0/=pl.T;                                   // remove full periods from the difference
            a0-=floor(a0);
            a0*=pl.T;
            if ((a0<a1)||(a1<0.0)) { a1=a0; tim=tt; }   // remember best option
            }
        // find orbital position with min error (fine)
        for (i=0;i<3;i++)                               // recursive increase of accuracy
         for (a1=-1.0,t=tim-dt,T=tim+dt,dt*=0.1;t<T;t+=dt)
            {
            p=pl.position(sim_t+t);                     // try time t
            tt=length(p-pos)/spd;
            a0=tt-t; if (a0<0.0) continue;              // ignore overshoots
            a0/=pl.T;                                   // remove full periods from the difference
            a0-=floor(a0);
            a0*=pl.T;
            if ((a0<a1)||(a1<0.0)) { a1=a0; tim=tt; }   // remember best option
            }
        // direction
        p=pl.position(sim_t+tim);
        dir=normalize(p-pos);
        }
    };
//---------------------------------------------------------------------------
planet pl;
ship sh;
//---------------------------------------------------------------------------
void TMain::draw()
    {
    if (!_redraw) return;
    double x,y,r=3;
    vec3 p;

    // clear buffer
    bmp->Canvas->Brush->Color=clBlack;
    bmp->Canvas->FillRect(TRect(0,0,xs,ys));

    // Star
    bmp->Canvas->Pen->Color=clYellow;
    bmp->Canvas->Brush->Color=clYellow;
    x=0; y=0; toscr(x,y);
    bmp->Canvas->Ellipse(x-r,y-r,x+r,y+r);
    // planet
    bmp->Canvas->Pen->Color=clDkGray;
    pl.draw_orbit(bmp->Canvas);
    bmp->Canvas->Pen->Color=clAqua;
    bmp->Canvas->Brush->Color=clAqua;
    p=pl.position(sim_t);
    x=p.x; y=p.y; toscr(x,y);
    bmp->Canvas->Ellipse(x-r,y-r,x+r,y+r);
    // ship
    bmp->Canvas->Pen->Color=clRed;
    bmp->Canvas->Brush->Color=clRed;
    p=sh.pos;
    x=p.x; y=p.y; toscr(x,y);
    bmp->Canvas->Ellipse(x-r,y-r,x+r,y+r);

    // render backbuffer
    Main->Canvas->Draw(0,0,bmp);
    _redraw=false;
    }
//---------------------------------------------------------------------------
__fastcall TMain::TMain(TComponent* Owner) : TForm(Owner)
    {
    pl.ld(1000000000.0,350000000.0,0.0,50.0*t_day);
    sh.pos=vec3(-3500000000.0,-800000000.0,0.0);
    sh.spd=500.0;   // [m/s]
    sh.intercept(pl);

    bmp=new Graphics::TBitmap;
    bmp->HandleType=bmDIB;
    bmp->PixelFormat=pf32bit;
    pyx=NULL;
    _redraw=true;
    }
//---------------------------------------------------------------------------
void __fastcall TMain::FormDestroy(TObject *Sender)
    {
    if (pyx) delete[] pyx;
    delete bmp;
    }
//---------------------------------------------------------------------------
void __fastcall TMain::FormResize(TObject *Sender)
    {
    xs=ClientWidth;  xs2=xs>>1;
    ys=ClientHeight; ys2=ys>>1;
    bmp->Width=xs;
    bmp->Height=ys;
    if (pyx) delete[] pyx;
    pyx=new int*[ys];
    for (int y=0;y<ys;y++) pyx[y]=(int*) bmp->ScanLine[y];
    _redraw=true;

    view_x0=xs-(xs>>3);
    view_y0=ys2;
    zoom=double(xs2)/(2.5*pl.a);

    // draw(); Sleep(5000);
    }
//---------------------------------------------------------------------------
void __fastcall TMain::FormPaint(TObject *Sender)
    {
    _redraw=true;
    }
//---------------------------------------------------------------------------
void __fastcall TMain::tim_redrawTimer(TObject *Sender)
    {
    for (int i=0;i<10;i++)
        {
        sh.update(sim_dt);
        sim_t+=sim_dt;
        if (sh.tim<=0.0) sim_dt=0.0; // stop simulation when jump done
        }
    if (sim_dt>0.0) _redraw=true;
    draw();
    }
//---------------------------------------------------------------------------

重要的东西在两个类中planet,ship then sim_t是实际模拟时间,sim_dt是模拟的时间步长。在这种情况下,模拟在船舶到达目的地后停止。这ship::tim是在以下公式中计算出的剩余行程时间ship::intercept()以及预设速度的方向。应在每个模拟时间步调用更新......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算给定速度的轨道截距。 的相关文章

  • .NET 的符号数学

    我正在寻找 NET 框架的符号数学库 我看过Math net 但它还不是可用的 您知道是否还有其他图书馆存在吗 这可能有点过分了 但你可以和数学 http www wolfram com products mathematica index
  • 为 javascript 编写一个真正具有包容性的随机方法

    Javascript MATH 对象有一个随机方法 该方法从集合 0 1 返回 0 含 0 1 不包括 有没有办法返回一个真正随机的方法 其中包括 1 e g var rand MATH random 2 if rand gt 1 rand
  • 涉及数学的方法给出与计算器不同的答案

    我是java新手 所以请耐心等待 我试图从比赛总数中获得胜利的百分比 但我正在做的事情还很遥远 我获取百分比的方法如下 public double winPercentage int wins int total return wins t
  • 在unity3D中显示数学方程

    我想使用它的 GUI 系统统一显示数学方程 有办法吗 我正在使用 C 语言在 Unity 中进行编程 如果我还可以使用 C 代码显示数学符号 这对我来说会很有用 谢谢 自 2016 年起 您可以使用TEXDraw https assetst
  • 在两个点之间创建一条曲线,每个点都具有标准化向量

    因此 我需要一种写入方法来在两点之间创建一条曲线 每个点都有一个指向任意方向的归一化向量 我一直在尝试设计这样一种方法 但一直无法理解数学 在这里 由于一张图片胜过一千个文字 这就是我所需要的 在图中 矢量垂直于红线 我相信向量需要进行相同
  • RNG 技术的可移植性和可重复性

    我可以使用两种方法之一来创建一个伪随机数序列 该序列具有两个重要特征 1 它可以在不同的机器上重现 2 该序列永远不会重复范围内的数字 直到所有数字都被发出 我的问题是 这两种方法在可移植性 操作系统 Python 版本等 方面是否存在潜在
  • 将所有 BigDecimal 运算设置为特定精度?

    我的Java程序以高精度计算为中心 需要精确到至少120位小数 因此 程序中所有非整数都将由 BigDecimal 表示 显然 我需要指定 BigDecimal 的舍入精度 以避免无限小数表达式等 目前 我发现必须在 BigDecimal
  • Math.Sin、Math.Cos 和 Math.Tan 精度以及正确显示它们的方法

    我正在用 C 编写一个计算器 textBoxResult是一个文本框 我在其中显示数字 recount是以度为单位获取角度并以弧度为单位返回的函数 我的角度是从texBoxInput public double recount int nu
  • 在现代 x86-64 上计算 64 位整数的整数 Log10 的最快方法是什么?

    标题 我找到了大量 32 位示例 但没有找到完整的 64 位示例 使用这个帖子 https codegolf stackexchange com questions 47290 fastest way to compute order of
  • 使用两个经度/纬度点获取方向(指南针)

    我正在为移动设备开发 指南针 我有以下几点 point 1 current location Latitude 47 2246 Longitude 8 8257 point 2 target location Latitude 50 924
  • 为什么 Convert.ToInt32(1.0/0.00004) != (Int32)(1.0/0.00004)

    为什么这段代码http ideone com YRcICG http ideone com YRcICG void Main double a 0 00004 Int32 castToInt Int32 1 0 a Int32 conver
  • 如何在编程中表示sqrt(-1)?

    我想代表sqrt 1 在C 中 因为我正在尝试实现FFT算法 有没有好的方法来表示这一点 我猜你正在寻找 include
  • BODMAS系统的加法和减法

    我一直在构建一个简单的公式计算器 但一直被加法和减法困扰 正如您应该知道的 在计算方程时 您遵循优先级算术规则 即括号 顺序 幂函数 除法 乘法 加法和减法 问题是加法和减法具有相同的优先级 因此您可以从左到右阅读 到目前为止 这是我的代码
  • 限制纬度和经度值的模数

    我有代表纬度和经度的双精度数 我可以轻松地将经度限制为 180 0 180 0 具有以下功能 double limitLon double lon return fmod lon 180 0 360 0 180 0 这是有效的 因为一端是排
  • 为什么斐波那契堆被称为斐波那契堆?

    The 斐波那契堆 http en wikipedia org wiki Fibonacci heap数据结构的名称中有 斐波那契 一词 但数据结构中似乎没有任何内容使用斐波那契数 根据维基百科文章 斐波那契堆的名称来自于运行时间分析中使用
  • 为什么循环引导迭代算法的数组大小必须为 3^k+1?

    The 循环引导迭代算法 http www geeksforgeeks org an in place algorithm for string transformation 是一种通过将所有偶数项移至前面并将所有奇数项移至后面同时保留其相
  • 构建协同过滤/推荐系统

    我正在设计一个网站 该网站的概念是根据用户的口味向他们推荐各种商品 即他们评价过的项目 添加到收藏夹列表中的项目等 亚马逊 Movielens 和 Netflix 就是这样的例子 现在 我的问题是 我不知道从哪里开始了解这个系统的数学部分
  • 查找所有n位相邻数字为1的n位二进制数[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 让我用一个例子来解释一下 如果n 4
  • 如何在 C# 中计算 power-of?

    我不太擅长数学 而且 C 似乎没有提供幂函数 所以我想知道是否有人知道我将如何进行这样的计算 var dimensions 100 100 100 00 3 00 See Math Pow http msdn microsoft com e
  • 三个 JS Orbitcontrols 设置目标而不用 LookAt

    我正在尝试制作一个用于构建模型的 3D 查看器 我们已加载模型并尝试与模型进行某种交互 因此 我们使用 OrbiControls 来旋转 平移和缩放模型 我们希望在查看器中具有这样的行为 当用户单击并拖动 从而旋转 时 旋转中心位于用户单击

随机推荐

  • 我可以序列化 ruby​​ Digest::SHA1 实例对象吗?

    大家好 我正在 ruby sinatra 中重新实现现有的自定义文件上传服务 并使用 redis 作为后备存储 客户 计算 SHA1 哈希并启动上传 上传最多 64K 块直至完成 服务器 将块附加到文件 计算完整文件的 SHA1 哈希值以验
  • 在 Ansible 中,如何将活动角色的变量组合到一个数组中?

    看着 在 Ansible 中 如何将不同文件中的变量合并到一个数组中 答案之一建议使用包含变量要将多个来源的变量放入一个数组中 这是almost我需要什么 但不完全是 我正在设置 cloudfront logging 它需要 a 中的项目a
  • Qt 使应用程序始终位于 Weston/Wayland 平台之上

    我想在 Wayland Weston 桌面系统中安排两个应用程序的焦点 两个应用是 用 Qt QML 编写 全屏 使用 Wayland 客户端 API OpenGL 编写 全屏 我想让 App 1 始终位于顶部 App 2 始终位于底部 即
  • 使用 ElementTree 从混合元素 xml 标签中获取文本

    我正在使用 ElementTree 来解析我拥有的 XML 文档 我从以下位置获取文本u标签 其中一些包含混合内容 我需要过滤掉或保留为文本 我有两个例子 u u
  • 删除 id=".xxx" 的 div 或 span

    我无法删除 id 带有句点或星号的 div div div div div 我有 jquery 代码 它删除了 div div 但不是上面的 不是在寻找 jQuery 代码 但它需要正斜杠吗 来自 anurag 的请求 JavaScript
  • 回调到可变的 self

    有没有一种方法 在 Rust 中 可以将可变的借用自我发送到回调而不需要mem replace我在以下 MWE 中使用的 hack 我正在使用 Rust stable 1 11 0 use std mem trait Actable fn
  • 如何在强制推送基础分支后更新我的功能分支。我们只使用rebase,禁止合并

    我们正在使用 git 中的一个非常简单的结构 首先我们有我们的master branch 下面我们有develop 最后我们可以有任何feature branch 我们仅使用 rebase 来更新分支上的历史记录 然后转发到上述分支 每周
  • 集合编辑器未针对 TPersistent 属性中的 TCollection 属性打开

    我有我的自定义集合属性 当它是我的组件的直接成员时 它工作得很好 但我想将集合属性移动到组件内的 TPersistent 属性 现在问题来了 它不起作用 双击对象检查器中的集合属性通常会打开集合编辑器 但现在不再这样了 首先 我应该将什么传
  • 我的华为手机如何设置这个配置?

    我的问题是 在我的华为手机上 我的服务被终止 所以我需要更改手机上的设置 我的问题与this 注意 华为和小米设备具有邪恶的任务杀手服务 会干扰 Telegram 通知服务 为了让我们的通知发挥作用 您需要将 Telegram 添加到这些设
  • JavaScript 正则表达式将 URL 和电子邮件包装在锚点中

    我四处搜寻 但无法找到明确的答案 正则表达式经常出现这种情况 所以我想我会在这里问 我正在尝试组合一个可以在 JavaScript 中使用的正则表达式 以用指向它们的锚标记替换 URL 和电子邮件地址的所有实例 不需要如此严格 显然 这通常
  • 在“if”子句中使用“in”时是元组还是列表?

    哪种方法更好 使用元组 例如 if number in 1 2 或列表 例如 if number in 1 2 建议将哪一种用于此类用途 为什么 逻辑和性能方面 Python 解释器将第二种形式替换为第一种形式 这是因为从常量加载元组是一项
  • 使用 JQuery 从数组填充表

    我有一个包含 16 个元素的数组 我想将其填充到一个表格中 我希望它有 2 行 每行 8 个单元格 其中填充有数组 我的问题是 当填充表时 表将所有元素填充到一行中 我对 JQuery 没有太多经验 我想尝试让它发挥作用 任何帮助表示赞赏
  • IIS7上可以在html中包含php吗?

    在 Apache 中似乎可以这样做 在 HTML 中包含 php 脚本 但是我可以让 IIS 7 解析 html 文件为 php 吗 目前我的 html 文件允许包含 asp 如果我可以用 php 文件来做到这一点 那就太好了 我的服务器按
  • 使用自定义 java 运行时映像时发生 javax.net.ssl.SSLHandshakeException 但并非没有

    我有这个类 它只发送一个 http post 请求 import java net import java io public class JarRuntimeTest public void start throws Exception
  • BigDecimal、精度和小数位数

    我在应用程序中使用 BigDecimal 来表示数字 例如使用 JPA 我对 精度 和 规模 这两个术语做了一些研究 但我不明白它们到底是什么 谁能解释一下 BigDecimal 值的 精度 和 小数位数 的含义 Column precis
  • 将单个对象插入 json 文件而不重写整个文件

    我正在研究一种使用 JSON NET 将马对象添加到 JSON 格式的马数据库中的方法 一种选择是将整个文件反序列化为马列表 添加新马 然后序列化该列表并重写整个文件 我在下面的代码中实现了这种方法 adds a horse to the
  • row.names() 和 attribute$row.names 有什么区别?

    row names iris 返回一个字符向量 gt row names head iris 1 1 2 3 4 5 6 and attributes iris row names返回一个整数向量 gt attributes head ir
  • 如何在 protobuf-net 中启用字符串驻留?

    我使用的是 v2 rev 421 当我保存 protobuf net 生成的流并将其放入字符串实用程序时 它发现了许多重复的字符串 我说的是应用程序生成的字符串 它可以被实习 但默认情况下字符串实习似乎没有打开 我如何启用它 Thanks
  • AngularJS:旧 Angular 版本中的 $q.race()

    Angular 1 5 8 实现了 q race 方法 它接受一个 Promise 数组并返回一个 Promise 该 Promise 使用第一个已解析 Promise 的值进行解析 然而我现在坚持使用 Angular 1 4 并且需要某种
  • 计算给定速度的轨道截距。

    背景 尝试编写一款 FTL 旅行不受重力影响并且加速度是即时的游戏 给定行星的开普勒轨道和飞船的当前位置及其最大超光速 FTL 速度 如何计算行星的位置 单位 米 秒 我可以获取给定日期时间的行星位置 但我正在努力弄清楚如何计算行星的位置以