Java 行星轨道模拟:居中行星
Java planetary orbit simulation: centering planets
我创建了一个简单的行星模拟,其中行星围绕恒星运行。
轨道代码是这样的:
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) 旋转。
我需要行星的中心来环绕星星的中心,而不是它们的原点。
有什么好的解决方法吗?
目前我能想到的最合适的方法是获取恒星的世界坐标并将它们每一帧传递给child的坐标。当您这样做时,child 每一帧都会有相同的坐标。
下一部分是平移它并使其围绕恒星旋转 - 实现这一点的方法是通过 sin(x)*cos(x) 将行星的位置设置为由恒星的位置调换。
举个例子:
行星[0] = 恒星[0] + sin(角度)*尺度
行星[1] = 恒星[1] + 余弦(角度)*尺度
角度会逐渐变化,比例尺只会将 child object 远离其 parent,使其保持不变(或根据需要进行修改),因此从其 'new' 中心增加半径。
我知道有些人可能会提到矩阵或其他类型的转换,但对于这种情况,我认为上述解决方案在我看来是最相关和最简洁的
它的工作方式是将 parent 的 'WORLD coordinates' 设置为 child 的。通过修改 Scale 值,您可以增加 object 与中心的距离(因此它们不会重叠),并将其乘以指定角度的 sin 和 cos 以使其旋转。
P.S。请记住,如果您处理 FPS-dependant 引擎进行渲染,FPS 越高,模拟速度越快,并且 vice-versa,因为如果您以 1000 fps 渲染,这意味着您执行代码1000 次,例如与 100 相比。因此,您将分别增加角度 1000 次或 100。如果您遇到此问题,请尽可能尝试设置恒定的帧率 - 这是轻量级模拟的最简单解决方法。
编辑:我忘了说这个概念适用于你的所有 objects。您只需要处理我们的关系并分别使用 eqch object 函数,其中每个 object 都有一个位置和轨道角度(如果它围绕不同的 object 运行)。
你的轨道计算没问题。唯一的问题似乎是你在计算轨道和绘制行星时对 "position" 的处理方式不同:当你绘制它们时,你将 x
和 y
视为角点之一,但是当你计算轨道时,你将它们视为 body 的中心。最简单的方法是更改 可视化 ,而不是计算。
由于您没有 post 用于绘制形状的代码,我只能猜测,但我认为它看起来有点像这样(显然是伪代码):
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
更简单、更自然和 y
为中心。
我创建了一个简单的行星模拟,其中行星围绕恒星运行。 轨道代码是这样的:
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) 旋转。
我需要行星的中心来环绕星星的中心,而不是它们的原点。
有什么好的解决方法吗?
目前我能想到的最合适的方法是获取恒星的世界坐标并将它们每一帧传递给child的坐标。当您这样做时,child 每一帧都会有相同的坐标。
下一部分是平移它并使其围绕恒星旋转 - 实现这一点的方法是通过 sin(x)*cos(x) 将行星的位置设置为由恒星的位置调换。
举个例子:
行星[0] = 恒星[0] + sin(角度)*尺度
行星[1] = 恒星[1] + 余弦(角度)*尺度
角度会逐渐变化,比例尺只会将 child object 远离其 parent,使其保持不变(或根据需要进行修改),因此从其 'new' 中心增加半径。
我知道有些人可能会提到矩阵或其他类型的转换,但对于这种情况,我认为上述解决方案在我看来是最相关和最简洁的
它的工作方式是将 parent 的 'WORLD coordinates' 设置为 child 的。通过修改 Scale 值,您可以增加 object 与中心的距离(因此它们不会重叠),并将其乘以指定角度的 sin 和 cos 以使其旋转。
P.S。请记住,如果您处理 FPS-dependant 引擎进行渲染,FPS 越高,模拟速度越快,并且 vice-versa,因为如果您以 1000 fps 渲染,这意味着您执行代码1000 次,例如与 100 相比。因此,您将分别增加角度 1000 次或 100。如果您遇到此问题,请尽可能尝试设置恒定的帧率 - 这是轻量级模拟的最简单解决方法。
编辑:我忘了说这个概念适用于你的所有 objects。您只需要处理我们的关系并分别使用 eqch object 函数,其中每个 object 都有一个位置和轨道角度(如果它围绕不同的 object 运行)。
你的轨道计算没问题。唯一的问题似乎是你在计算轨道和绘制行星时对 "position" 的处理方式不同:当你绘制它们时,你将 x
和 y
视为角点之一,但是当你计算轨道时,你将它们视为 body 的中心。最简单的方法是更改 可视化 ,而不是计算。
由于您没有 post 用于绘制形状的代码,我只能猜测,但我认为它看起来有点像这样(显然是伪代码):
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
更简单、更自然和 y
为中心。