围绕另一个旋转点旋转一个点 - 一半工作
Rotating a point around another rotating point - half working
我正在尝试在 java 中创建一个具有简单轨道(没有重力或任何奇特的东西)的微型太阳系。
我要:月亮绕行星转,绕太阳转
我的问题:“月亮”的轨道是椭圆形的,而不是圆形的。
我使用的代码:
void movePlanet(){
// set referencePoint as origin
double x1 = this.x - referencePoint.getX();
double y1 = this.y - referencePoint.getY();
// apply the rotation matrix (i think, i don't really understand this part)
double x2 = x1 * Math.cos(rotationAngle) - y1 * Math.sin(rotationAngle);
double y2 = x1 * Math.sin(rotationAngle) + y1 * Math.cos(rotationAngle);
// move everything back into position
this.x = x2 + referencePoint.getX();
this.y = y2 + referencePoint.getY();
所以,太阳是静止的。
行星使用此功能,并且工作正常。参考点是太阳,“这个”是行星。
月亮也用这个函数,参考点是行星,“this”是月亮
我想我坚持这个是因为我不明白旋转矩阵是如何工作的。
编辑 1:
更多上下文:
planete[] planetes = new planete[8];
// arguments: ReferencePoint, orbitRadius, rotationTime, size, sprite
// planet/moon cordinates are:
// x:referencePoint + orbitRadius
// y:referencePoint
planetes[0] = new planete(Sun, 100, 10, 32, "earth.gif"); // Planet
planetes[1] = new planete(planetes[0], 50, -5, 32, "earth.gif"); // moon
while (horloge.giveDayCountSinceStarting() < timeLimit) { // drawing loop
StdDraw.clear(Color.BLACK); // On efface le "tableau"
Sun.showAstre(); // display the sun
for (planete planete : planetes) {
if (planete != null) {
planete.drawOrbit(); //display planet orbit
planete.showAstre(); //display planet
planete.movePlanet(); // move planet
}
}
StdDraw.show();
StdDraw.pause(1000 / refreshRate);
}
编辑 2:
答案的解释,感谢 Dawood ibn Kareem:
我的错误是操作顺序:
将行星移至原点 -
在行星上应用旋转 -
将行星移回
将月亮移到原点 -
在月球上应用旋转 -
把月亮移回去
但是当月球开始自转时,地球已经完成了自转。所以月亮转“两倍”。这就是为什么在间隙的最大值处,它是其假定轨道的 2 倍。
解决方案是在行星自转之前保存其位置。当月球自转时,它会在自转前取行星的位置,而不是在自转后,不累加自转。
你的逻辑应该是这样的。这对月球和行星之间的距离应用一个旋转角度,对行星和太阳之间的距离应用另一个旋转角度。
double moonDisplacementX = moon.getX() - planet.getX();
double moonDisplacementY = moon.getY() - planet.getY();
double planetDisplacementX = planet.getX() - sun.getX();
double planetDisplacementY = planet.getY() - sun.getY();
double planetNewDisplacementX
= planetDisplacementX * Math.cos(planetRotation) - planetDisplacementY * Math.sin(planetRotation);
double planetNewDisplacementY
= planetDisplacementX * Math.sin(planetRotation) + planetDisplacementY * Math.cos(planetRotation);
planet.setX(sun.getX() + planetNewDisplacementX);
planet.setY(sun.getY() + planetNewDisplacementY);
double moonNewDisplacementX
= moonDisplacementX * Math.cos(moonRotation) - moonDisplacementY * Math.sin(moonRotation);
double moonNewDisplacementY
= moonDisplacementX * Math.sin(moonRotation) + moonDisplacementY * Math.cos(moonRotation);
moon.setX(planet.getX() + moonNewDisplacementX);
moon.setY(planet.getY() + moonNewDisplacementY);
注意如何将月球的新位移矢量添加到行星的新位置,而不是其原始位置。这就是让月球与地球保持联系的原因。
我正在尝试在 java 中创建一个具有简单轨道(没有重力或任何奇特的东西)的微型太阳系。
我要:月亮绕行星转,绕太阳转
我的问题:“月亮”的轨道是椭圆形的,而不是圆形的。
我使用的代码:
void movePlanet(){
// set referencePoint as origin
double x1 = this.x - referencePoint.getX();
double y1 = this.y - referencePoint.getY();
// apply the rotation matrix (i think, i don't really understand this part)
double x2 = x1 * Math.cos(rotationAngle) - y1 * Math.sin(rotationAngle);
double y2 = x1 * Math.sin(rotationAngle) + y1 * Math.cos(rotationAngle);
// move everything back into position
this.x = x2 + referencePoint.getX();
this.y = y2 + referencePoint.getY();
所以,太阳是静止的。 行星使用此功能,并且工作正常。参考点是太阳,“这个”是行星。 月亮也用这个函数,参考点是行星,“this”是月亮
我想我坚持这个是因为我不明白旋转矩阵是如何工作的。
编辑 1:
更多上下文:
planete[] planetes = new planete[8];
// arguments: ReferencePoint, orbitRadius, rotationTime, size, sprite
// planet/moon cordinates are:
// x:referencePoint + orbitRadius
// y:referencePoint
planetes[0] = new planete(Sun, 100, 10, 32, "earth.gif"); // Planet
planetes[1] = new planete(planetes[0], 50, -5, 32, "earth.gif"); // moon
while (horloge.giveDayCountSinceStarting() < timeLimit) { // drawing loop
StdDraw.clear(Color.BLACK); // On efface le "tableau"
Sun.showAstre(); // display the sun
for (planete planete : planetes) {
if (planete != null) {
planete.drawOrbit(); //display planet orbit
planete.showAstre(); //display planet
planete.movePlanet(); // move planet
}
}
StdDraw.show();
StdDraw.pause(1000 / refreshRate);
}
编辑 2: 答案的解释,感谢 Dawood ibn Kareem:
我的错误是操作顺序:
将行星移至原点 - 在行星上应用旋转 - 将行星移回
将月亮移到原点 - 在月球上应用旋转 - 把月亮移回去
但是当月球开始自转时,地球已经完成了自转。所以月亮转“两倍”。这就是为什么在间隙的最大值处,它是其假定轨道的 2 倍。
解决方案是在行星自转之前保存其位置。当月球自转时,它会在自转前取行星的位置,而不是在自转后,不累加自转。
你的逻辑应该是这样的。这对月球和行星之间的距离应用一个旋转角度,对行星和太阳之间的距离应用另一个旋转角度。
double moonDisplacementX = moon.getX() - planet.getX();
double moonDisplacementY = moon.getY() - planet.getY();
double planetDisplacementX = planet.getX() - sun.getX();
double planetDisplacementY = planet.getY() - sun.getY();
double planetNewDisplacementX
= planetDisplacementX * Math.cos(planetRotation) - planetDisplacementY * Math.sin(planetRotation);
double planetNewDisplacementY
= planetDisplacementX * Math.sin(planetRotation) + planetDisplacementY * Math.cos(planetRotation);
planet.setX(sun.getX() + planetNewDisplacementX);
planet.setY(sun.getY() + planetNewDisplacementY);
double moonNewDisplacementX
= moonDisplacementX * Math.cos(moonRotation) - moonDisplacementY * Math.sin(moonRotation);
double moonNewDisplacementY
= moonDisplacementX * Math.sin(moonRotation) + moonDisplacementY * Math.cos(moonRotation);
moon.setX(planet.getX() + moonNewDisplacementX);
moon.setY(planet.getY() + moonNewDisplacementY);
注意如何将月球的新位移矢量添加到行星的新位置,而不是其原始位置。这就是让月球与地球保持联系的原因。