1

我创建了一个简单的行星模拟,其中行星围绕恒星运行。轨道的代码是这样的:

    a = a + vel * delta;
    planetX = Math.cos(a) * orbitRadius + parentStar.getX();
    planetY = Math.sin(a) * orbitRadius + parentStar.getY();

现在效果很好,但我的问题是轨道不是围绕恒星中心的行星中心。 这就是发生的事情

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

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

有什么好的解决方法吗?

4

2 回答 2

3

您对轨道的计算很好。唯一的问题似乎是,在计算轨道和绘制行星时,您对待“位置”的方式不同:绘制它们时,您将xy视为角点之一,但是当您计算轨道时,您将它们视为中心的身体。最简单的方法是更改​​可视化,而不是计算。

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

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

把它改成这样:

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

这样一来,x和是行星中心y的位置,和和就得到角点。当然,您可以以类似的方式更改所有轨道力学公式以从角点计算中心,但恕我直言,将其视为中心要简单得多,也更自然。p.x - p.radiusp.y - p.radiusxy

于 2016-01-30T18:09:36.133 回答
0

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

下一部分是平移它并围绕恒星旋转——实现这一点的方法是通过使用 sin(x)*cos(x) 将行星的位置设置为由恒星的位置转置。

让我给你看一个例子:

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

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

角度会逐渐变化,比例只会使子对象远离其父对象,使其保持恒定(或根据需要进行修改),从而增加其“新”中心的半径。

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

它的工作方式是您获取父母的“世界坐标”并将它们设置为孩子的。通过修改 Scale 值,可以增加对象与中心的距离(因此它们不会重叠),然后将其与指定角度的 sin 和 cos 相乘以使其旋转。

PS 请记住,如果您使用依赖于 FPS 的引擎进行渲染,则 FPS 越高,模拟的速度就越快,反之亦然,因为如果您以 1000 fps 渲染,这意味着您执行代码 1000 次,例如,与 100 相比。因此,您将分别将角度增加 1000 倍或 100。如果您遇到此问题,请尝试设置恒定帧速率 - 这是轻量级模拟最简单的解决方法。

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

于 2016-01-30T16:46:40.720 回答