首页 文章

我更新星球附近行星位置的功能有什么问题?

提问于
浏览
-1

最初,当行星朝向恒星弯曲时,代码似乎起作用,但是当它应该被拉入恒星或进入轨道时,它就会被推向相反的方向 . 我究竟做错了什么?似乎行为的变化发生在距离的变化时 .

if(!alive){
    return;
}
xPos += t * velocity/10000 * cos(direction / 180 * 3.14);
yPos += t * velocity/10000 * sin(direction / 180 * 3.14);

double gravity = 1000;
double starX = 1920/2;
double starY = 1080/2;

double deltaX = xPos - starX;
double deltaY = yPos - starY;
double distance = sqrt(pow(deltaX, 2) + pow(deltaY, 2));
int modifier = 1;
if (xPos > starX){
    modifier = -1;
}
double angle = atan(deltaY / deltaX) * 180 / 3.14;
std::cout << angle << std::endl;

xPos += t * gravity / pow(distance,2) * modifier * cos(angle / 180 * 3.14);
yPos += t * gravity / pow(distance,2) * modifier * sin(angle / 180 * 3.14);

if (xPos > starX - 100 && xPos < starX + 100 && yPos > starY - 100 && yPos < starY + 100){
    alive = false;
}

xPos和yPos是这个星球的当前位置 . t是自上次更新以来的时间 . 速度和方向是行星开始的初始速度和角度 . 由于我们在太空中,这种力量永远不会改变 . 引力是引力常数 . starX和starY是恒星的位置,距离是恒星和行星之间的距离 . 角度是恒星和行星之间的角度(我感觉这是造成不良行为的原因 . )

1 回答

  • 1

    你的第一个问题是使用atan(y / x)而不是atan2(y,x),这意味着你遇到的麻烦 . 特别是当x变小时,atan2将正确应对,而atan将无法在相同条件下处理y / x . 我认为这是你爆炸的主要原因,因为我按照自己的条件采取你的代码 .

    话虽如此,@ Jim Lewis和@CodesInChaos也在做重要的观察 . F = ma意味着您应该从力中获得加速度,然后将加速度积分以获得速度(必须是状态变量),并将速度积分到位置 . 如果你希望你的程序在行星旋转到恒星时保持稳定,那么你将需要一种更复杂的集成方法 . 您现有的方法被称为“欧拉方法”,如果您在维基百科中查找,您将了解自己的立场以及应该去的地方 .

    另一个改进是结合“智能三角学” . 观察当你有三角形的三边时,没有必要计算角度来计算正弦和余弦 . 在这种情况下,你的边是距离,deltaX和deltaY . 因此,您可以执行cosAngle = deltaX / distance和sinAngle = deltaY / distance,并使用它们来计算加速度的分量 . 要确认这一点,您可以检查cosAngle * cosAngle sinAngle * sinAngle = 1.此外,这些符号完全适用于其余计算 .

    我想你会发现如果你“正确地做欧拉”,忠实地实现运动方程并使用atan2或智能触发,你会发现你根本不需要你的“修改器”黑客 . 如果这是一个游戏(你的1920 / 2,1080 / 2让我相信它是),你可以很好地控制初始条件,而不是让系统太lo太低,你可能不需要从欧拉升级 .

相关问题