Java行星轨道模拟:行星居中

Java行星轨道模拟:行星居中,java,math,orbital-mechanics,Java,Math,Orbital Mechanics,我创建了一个简单的行星模拟,行星围绕恒星运行。 轨道的代码如下: a = a + vel * delta; planetX = Math.cos(a) * orbitRadius + parentStar.getX(); planetY = Math.sin(a) * orbitRadius + parentStar.getY(); 这很好,但我的问题是轨道不是从行星中心到恒星中心。 如你所见,小圆上的第一个红点是围绕第二个红点运行的行星的位置,这是因为圆是从(0,0

我创建了一个简单的行星模拟,行星围绕恒星运行。 轨道的代码如下:

    a = a + vel * delta;
    planetX = Math.cos(a) * orbitRadius + parentStar.getX();
    planetY = Math.sin(a) * orbitRadius + parentStar.getY();
这很好,但我的问题是轨道不是从行星中心到恒星中心。

如你所见,小圆上的第一个红点是围绕第二个红点运行的行星的位置,这是因为圆是从(0,0)开始绘制的,所以两个行星(0,0)都围绕恒星的(0,0)旋转

我需要行星的中心来环绕恒星中心,而不是它们的原点


有什么好办法吗?

目前我能想到的最合适的方法是获取恒星的世界坐标,并将它们每帧传递给孩子的坐标。这样做时,每个帧的子对象都将具有相同的坐标

下一部分是平移它并围绕恒星旋转-实现这一点的方法是将行星的位置设置为与恒星的位置用sin(x)*cos(x)进行换位

让我给你举个例子:

行星[0]=恒星[0]+sin(角度)*比例

行星[1]=恒星[1]+cos(角度)*比例

角度会逐渐改变,比例只会将子对象从其父对象进一步移动,使其保持不变(或根据需要进行修改),从而从其“新”中心增加半径

我知道有些人可能会提到矩阵或其他类型的转换,但对于这种情况,我认为上述解决方案在我看来是最相关和最干净的

它的工作方式是您获取父对象的“世界坐标”,并将它们设置为子对象的。通过修改“缩放”值,可以增加对象与中心的距离(这样它们就不会重叠),并将其与指定角度的正反方向相乘,使其旋转

请记住,如果使用依赖于FPS的引擎进行渲染,则FPS越多,模拟速度越快,反之亦然,因为如果以1000 FPS进行渲染,这意味着执行代码1000次,而不是100次。因此,将分别将角度增加1000倍或100倍。如果您有这个问题,请尝试设置一个恒定的帧速率(如果可以的话)——这是轻量级模拟最简单的解决方法


编辑:我忘了提到这个概念适用于您案例中的所有对象。您只需处理这些关系,并分别使用eqch对象的函数,其中每个对象都有一个位置和轨道角度(如果它围绕不同的对象旋转)。

您的轨道计算很好。唯一的问题似乎是,在计算轨道和绘制行星时,对“位置”的处理方式有所不同:绘制它们时,将
x
y
视为角点之一,但在计算原点时,将它们视为天体的中心。最简单的方法是改变可视化,而不是计算

由于您没有发布用于绘制形状的代码,我只能猜测,但我假设它看起来有点像这样(显然是伪代码):

将此更改为类似以下内容:

for (Planet p : starsAndPlanets) {
    drawCircle(p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2);
}

这样,
x
y
就是行星中心的位置,通过
p.x-p.radius
p.y-p.radius
就可以得到角点。当然,你可以用类似的方法改变你所有的轨道力学公式来计算从角点开始的中心,但是我认为把
x
y
作为中心更简单、更自然。

我能假设parentStar是矩形吗?你为什么不给我们完整的代码;静态图片无法解释anything@gpasch因为所有其他代码都只是创建并绘制图像,是的,它们是矩形图像中的圆。
for (Planet p : starsAndPlanets) {
    drawCircle(p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2);
}