我创造了一个简单的行星模拟,其中一颗行星绕着恒星运行。 轨道的代码是:
a = a + vel * delta;
planetX = Math.cos(a) * orbitRadius + parentStar.getX();
planetY = Math.sin(a) * orbitRadius + parentStar.getY();
现在工作得很好,但我的问题是轨道不是从恒星中心周围的行星中心开始的。 This is what happens
正如你所看到的,小圆圈上的第一个红点是围绕第二个小红点绕行星运动的行星的位置,这是因为圆圈是从(0,0)绘制的,所以这两个行星( 0,0)围绕恒星(0,0)的圆圈。
我需要行星的中心围绕恒星中心,而不是它们的原点。
对此有一个很好的解决方法吗?
答案 0 :(得分:3)
你的轨道计算很好。唯一的问题似乎是你在计算轨道和绘制行星时对待“位置”的方式:当你绘制它们时,你将x
和y
视为角点之一,但当你计算oribit,你将它们视为身体的中心。最简单的方法是更改可视化,而不是计算。
由于你没有发布用于绘制形状的代码,我只能猜测,但我认为它看起来有点像(显然是伪代码):
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.radius
和p.y - p.radius
则得到了角点。当然,你可以以类似的方式改变你所有的轨道机制公式,从角点计算中心,但恕我直言,它更简单,更自然地对待x
和{{ 1}}作为中心。
答案 1 :(得分:0)
现在我能想到的最合适的方式就是让明星的世界变得协调,并将每一帧传递给孩子的坐标。当你这样做时,孩子每帧都会有相同的坐标。
接下来的部分是翻译它并围绕恒星旋转 - 你可以通过将行星的位置设置为由星的位置转换为sin(x)* cos(x)来实现。
让我举个例子:
planet [0] = star [0] + sin(角度)* scale
planet [1] = star [1] + cos(angle)* scale
角度会逐渐变化,而比例只会将子对象从其父对象中移开,保持恒定(或根据需要修改它),从而将半径从“新”中心增加。
我知道有些人可能会提到矩阵或其他类型的转换,但对于这种情况,我认为上述解决方案在我看来是最相关和最干净的
它的工作方式是你取父母的'WORLD坐标'并将它们设置为孩子的。通过修改“比例”值,可以增加对象与中心的距离(因此它们不会重叠),然后将其乘以指定角度的sin和cos,使其旋转。
P.S。请记住,如果您要处理依赖于FPS的引擎进行渲染,则FPS越多,模拟的速度就越快,反之亦然,因为如果以1000 fps渲染,这意味着您执行代码1000次,比较以100为例。因此,您将分别增加1000倍或100倍的角度。如果您遇到此问题,请尝试设置恒定的帧速率 - 这是轻量级模拟的最简单的解决方法。
编辑:我忘了提到这个概念适用于您案例中的所有对象。你只需要处理我们的关系并单独使用eqch对象的函数,其中每个对象都有一个位置和轨道角度(如果它围绕另一个对象运行)。