围绕另一个旋转点旋转一个点 - 一半工作

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);

注意如何将月球的新位移矢量添加到行星的新位置,而不是其原始位置。这就是让月球与地球保持联系的原因。