java 中的精确圆轨道方程
Accurate Circular Orbit Equation in java
public void move(){
double angle;
for(int i = 0; i < planets.size(); i++){
if(Math.abs(Math.sqrt(Math.pow(ship.locX - (planets.get(i).locX + planets.get(i).radi), 2) + Math.pow(ship.locY - (planets.get(i).locY + planets.get(i).radi), 2))) < planets.get(i).gravrange){
//Distance formula between spaceship and planets to determine whether the ship is within the influence of the planet.
angle = ((Math.atan2((planets.get(i).locX + planets.get(i).radi) - ship.locX, (planets.get(i).locY + planets.get(i).radi) - ship.locY)) / Math.PI) + 1;
//The problematic math equation.
产生一个从 0 到 2 的双精度数,当 ship.locY < planets.get(i).locY && ship.locX == (planets.get(i) 时为 0。 locX - planets.get(i).radi)。 (当相对 X = 0 且相对 Y < 0 时。)
if(ship.locX > (planets.get(i).locX + planets.get(i).radi)){xm += Math.cos(angle) * planets.get(i).gravrate;}
else{xm -= Math.cos(angle) * planets.get(i).gravrate;}
if(ship.locY > (planets.get(i).locY + planets.get(i).radi)){ym += Math.sin(angle) * planets.get(i).gravrate;}
else{ym -= Math.sin(angle) * planets.get(i).gravrate;}
}
}
这使用数据来修改航天器的 X 和 Y 速度。
这个方程式适用于大部分轨道,但在某些情况下存在一个问题,即航天器会受到逆行力,从而减慢速度。不久之后,它开始被行星体排斥,行星体在短时间后又开始吸引它。当航天器到达发生这种情况的原始位置时,它开始向与原始轨道相反的方向移动。
这种情况会持续发生,直到航天器开始波状运动。
有没有办法解决这个问题,还是我只是使用了错误的方程式?我已经尝试解决这个问题大约两周了。我目前没有受过物理或微积分方面的教育,所以我的理解是有限的。
编辑:评论对我的数学有疑问,所以我会尝试在这里回答。根据我对 atan2 的了解,它会生成一个从 -pi 到 pi 的数字。我除以 pi 得到一个从 -1 到 1 的数字,然后加 1 得到 0 到 2。然后我用这个数字作为弧度测量值。我对弧度(单位圆)的了解是圆的弧度度量是 0 到 2pi。
编辑 2:以下代码具有非常不同的数学运算,但产生了预期的结果,除了在接近地球的南北 'poles' 时排斥而不是吸引的问题。
public void move(){
double angle;
double x1, x2, y1, y2;
for(int i = 0; i < planets.size(); i++){
x1 = ship.locX;
y1 = ship.locY;
x2 = planets.get(i).locX + planets.get(i).radi;
y2 = planets.get(i).locY + planets.get(i).radi;
if(Math.abs(Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))) < planets.get(i).gravrange){
//Distance formula between spaceship and planets
angle = (y2 - y1)/(x2 - x1); //Gets slope of line between points.
if(angle > 0){
if(y1 > y2){
xm += Math.cos(angle) * planets.get(i).gravrate;
ym += Math.sin(angle) * planets.get(i).gravrate;
}else{
xm -= Math.cos(angle) * planets.get(i).gravrate;
ym -= Math.sin(angle) * planets.get(i).gravrate;
}
}
else{
if(y1 > y2){
xm -= Math.cos(angle) * planets.get(i).gravrate;
ym -= Math.sin(angle) * planets.get(i).gravrate;
}else{
xm += Math.cos(angle) * planets.get(i).gravrate;
ym += Math.sin(angle) * planets.get(i).gravrate;}
}
}
}
我很快就把它写了下来,看看使用直线的斜率而不是那个奇怪的 atan2 方程是否有帮助。显然是这样。我还在本节中使代码更具可读性。
以下代码解决了我的问题。我像往常一样把我的数学方程式复杂化了。我花了三个星期的时间在谷歌上搜索,询问拥有物理和数学学位的人,并阅读了 Javadocs,然后才弄明白。事实证明 atan2 的工作方式与我认为的完全不同,我使用不当。
解决方案是事先简化 atan2 方程并删除不必要的添加。
x1 = ship.locX;
y1 = ship.locY;
x2 = planets.get(i).locX + planets.get(i).radi;
y2 = planets.get(i).locY + planets.get(i).radi;
if(Math.abs(Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))) < planets.get(i).gravrange){
//Distance formula between spaceship and planets
angle = Math.atan2((y2 - y1),(x2 - x1)); //Converts the difference to polar coordinates and returns theta.
xm -= Math.cos(angle) * planets.get(i).gravrate; //Converts theta to X/Y
ym -= Math.sin(angle) * planets.get(i).gravrate; //velocity values.
}
public void move(){
double angle;
for(int i = 0; i < planets.size(); i++){
if(Math.abs(Math.sqrt(Math.pow(ship.locX - (planets.get(i).locX + planets.get(i).radi), 2) + Math.pow(ship.locY - (planets.get(i).locY + planets.get(i).radi), 2))) < planets.get(i).gravrange){
//Distance formula between spaceship and planets to determine whether the ship is within the influence of the planet.
angle = ((Math.atan2((planets.get(i).locX + planets.get(i).radi) - ship.locX, (planets.get(i).locY + planets.get(i).radi) - ship.locY)) / Math.PI) + 1;
//The problematic math equation.
产生一个从 0 到 2 的双精度数,当 ship.locY < planets.get(i).locY && ship.locX == (planets.get(i) 时为 0。 locX - planets.get(i).radi)。 (当相对 X = 0 且相对 Y < 0 时。)
if(ship.locX > (planets.get(i).locX + planets.get(i).radi)){xm += Math.cos(angle) * planets.get(i).gravrate;}
else{xm -= Math.cos(angle) * planets.get(i).gravrate;}
if(ship.locY > (planets.get(i).locY + planets.get(i).radi)){ym += Math.sin(angle) * planets.get(i).gravrate;}
else{ym -= Math.sin(angle) * planets.get(i).gravrate;}
}
}
这使用数据来修改航天器的 X 和 Y 速度。
这个方程式适用于大部分轨道,但在某些情况下存在一个问题,即航天器会受到逆行力,从而减慢速度。不久之后,它开始被行星体排斥,行星体在短时间后又开始吸引它。当航天器到达发生这种情况的原始位置时,它开始向与原始轨道相反的方向移动。
这种情况会持续发生,直到航天器开始波状运动。
有没有办法解决这个问题,还是我只是使用了错误的方程式?我已经尝试解决这个问题大约两周了。我目前没有受过物理或微积分方面的教育,所以我的理解是有限的。
编辑:评论对我的数学有疑问,所以我会尝试在这里回答。根据我对 atan2 的了解,它会生成一个从 -pi 到 pi 的数字。我除以 pi 得到一个从 -1 到 1 的数字,然后加 1 得到 0 到 2。然后我用这个数字作为弧度测量值。我对弧度(单位圆)的了解是圆的弧度度量是 0 到 2pi。
编辑 2:以下代码具有非常不同的数学运算,但产生了预期的结果,除了在接近地球的南北 'poles' 时排斥而不是吸引的问题。
public void move(){
double angle;
double x1, x2, y1, y2;
for(int i = 0; i < planets.size(); i++){
x1 = ship.locX;
y1 = ship.locY;
x2 = planets.get(i).locX + planets.get(i).radi;
y2 = planets.get(i).locY + planets.get(i).radi;
if(Math.abs(Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))) < planets.get(i).gravrange){
//Distance formula between spaceship and planets
angle = (y2 - y1)/(x2 - x1); //Gets slope of line between points.
if(angle > 0){
if(y1 > y2){
xm += Math.cos(angle) * planets.get(i).gravrate;
ym += Math.sin(angle) * planets.get(i).gravrate;
}else{
xm -= Math.cos(angle) * planets.get(i).gravrate;
ym -= Math.sin(angle) * planets.get(i).gravrate;
}
}
else{
if(y1 > y2){
xm -= Math.cos(angle) * planets.get(i).gravrate;
ym -= Math.sin(angle) * planets.get(i).gravrate;
}else{
xm += Math.cos(angle) * planets.get(i).gravrate;
ym += Math.sin(angle) * planets.get(i).gravrate;}
}
}
}
我很快就把它写了下来,看看使用直线的斜率而不是那个奇怪的 atan2 方程是否有帮助。显然是这样。我还在本节中使代码更具可读性。
以下代码解决了我的问题。我像往常一样把我的数学方程式复杂化了。我花了三个星期的时间在谷歌上搜索,询问拥有物理和数学学位的人,并阅读了 Javadocs,然后才弄明白。事实证明 atan2 的工作方式与我认为的完全不同,我使用不当。 解决方案是事先简化 atan2 方程并删除不必要的添加。
x1 = ship.locX;
y1 = ship.locY;
x2 = planets.get(i).locX + planets.get(i).radi;
y2 = planets.get(i).locY + planets.get(i).radi;
if(Math.abs(Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))) < planets.get(i).gravrange){
//Distance formula between spaceship and planets
angle = Math.atan2((y2 - y1),(x2 - x1)); //Converts the difference to polar coordinates and returns theta.
xm -= Math.cos(angle) * planets.get(i).gravrate; //Converts theta to X/Y
ym -= Math.sin(angle) * planets.get(i).gravrate; //velocity values.
}