简体   繁体   English

Object 加速不符合预期

[英]Object acceleration not behaving as expected

I have two objects in a 2D space.我在二维空间中有两个对象。 I expect object1 to begin orbiting object2 .我希望object1开始围绕object2运行。 I derived my methods from the equation我从等式中得出我的方法

f = G * (m1 * m2 / r*r) f = G * (m1 * m2 / r*r)

and

dx1 += x1 - x2 * f dx1 += x1 - x2 * f

etc. However, I am struggling because the object is only moving in the pos pos direction.等等。但是,我很挣扎,因为 object 只在 pos pos 方向移动。 Here is the class for each object:这是每个 object 的 class:

Mass.java质量.java

import java.awt.Point;

public class Mass {
    public static float G = 0.1f;

    public Point center;
    public float mass, radius, dx = 0, dy = 0;
    public boolean locked = false;
    
    public Mass(Point center, float[] vect, float mass) {
        this.center = center;
        this.dx = vect[0];
        this.dy = vect[1];
        this.mass = mass;
        this.radius = mass;
    }

    public void moveVector(float[] vector) {
        if(!this.locked) {
            this.dx += vector[0];
            this.dy += vector[1];
        }
    }

    public void lock() {
        this.locked = true;
    }

    public static float distance(Mass obj1, Mass obj2) {
        float dX = obj1.center.x - obj2.center.x;
        float dY = obj1.center.y - obj2.center.y;
        double ans = Math.sqrt(Math.pow(dX, 2) + Math.pow(dY, 2));
        return (float) ans;
    }
    
    public static float force(Mass obj1, Mass obj2) {
        double ans = ((obj1.mass * obj2.mass) / Math.pow(distance(obj1, obj2), 2)) * G;
        return (float) ans;
    }
    
    public static float[] vector(Mass obj1, Mass obj2) {
        
        // total change between the two objects
        float force = force(obj1, obj2);
        
        float totalX = Math.abs(obj1.center.x - obj2.center.x);
        float totalY = Math.abs(obj1.center.y - obj2.center.y);
        
        float x = totalX * force;
        float y = totalY * force;
        
        float[] vector = {x, y};
        return vector;
    }
}

This is the main class.这是主要的class。

Sim.java Sim.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Sim extends JPanel {
    private static final long serialVersionUID = -2669101810074157675L;
    public static final int PREF_W = 800, PREF_H = 600;
    
    private Mass object1, object2;
    
    private Sim() {
        this.setFocusable(true);
        this.setBackground(Color.WHITE);
        
        float[] vect1 = {0, -1}, vect2 = {0, 0};
        object1 = new Mass(new Point(PREF_W / 2 - 100, PREF_H / 2 - 100), vect1, 10);
        object2 = new Mass(new Point(PREF_W / 2 + 100, PREF_H / 2 + 100), vect2, 30);
        
        gameTimer.start();
    }
    
    private Timer gameTimer = new Timer(1000/30, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            object1.moveVector(Mass.vector(object1, object2));
            object1.center.x += object1.dx;
            object1.center.y += object1.dy;
            System.out.println("[" + object1.dx + "," + object1.dy + "]");
        }
    });

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.fillOval(
                (int) object1.center.x - (int) object1.radius, 
                (int) object1.center.y - (int) object1.radius, 
                (int) object1.radius, 
                (int) object1.radius
            );
        
        g2.fillOval(
                (int) object2.center.x - (int) object2.radius, 
                (int) object2.center.y - (int) object2.radius, 
                (int) object2.radius, 
                (int) object2.radius
            );
        
        g2.drawLine(object1.center.x, object1.center.y, object2.center.x, object2.center.y);

        repaint();
    }
    
    /* METHODS FOR CREATING JFRAME AND JPANEL */

    public Dimension getPreferredSize() {
        return new Dimension(PREF_W, PREF_H);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Gravity Simulation");
                JPanel gamePanel = new Sim();

                frame.getContentPane().add(gamePanel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

I have it printing out the DX and DY of object1 (the unlocked object) at all times.我让它始终打印出object1 (未锁定的对象)的 DX 和 DY。 It seems to get flung super fast, as expected, but it never slows down.正如预期的那样,它似乎被甩得非常快,但它从不减速。 Instead, the dx is just increasing slower and slower.相反,dx 只是越来越慢地增加。 I'm not very mathy, but it seems to be logistic.我不是很数学,但它似乎是逻辑的。 I wonder why this is happening.我想知道为什么会这样。

So far I have tried rewriting my formula and using a different equation.到目前为止,我已经尝试重写我的公式并使用不同的方程。 I have also attempted using different datatypes, and making some things negative.我也尝试过使用不同的数据类型,并使一些事情变得消极。 Nothing works, though.但是,没有任何效果。

TLDR, the problem: Objects are not changing DX / DY as expected. TLDR,问题:对象没有像预期的那样改变 DX / DY。

Thank you in advance, Sorry if this was posted somewhere else.提前谢谢您,对不起,如果这是在其他地方发布的。 I could not find any duplicates.我找不到任何重复项。

OK, let's try to derive formulas.好的,让我们尝试推导公式。

You already have difference vector dX, dY , and make also normalized vector您已经有了差异向量dX, dY ,并且还制作了归一化向量

udX = dX / distance
udY = dY / distance

You also have force magnitude.你也有force大小。 To get force vector for object 1, just multiply normalized difference components by this magnitude (note minus sign because force direction is TO object2 (while dx, dy is vector FROM object 2))要获得 object 1 的力矢量,只需将归一化的差分分量乘以该幅度(注意减号,因为力方向是 TO object2(而 dx,dy 是来自 object 2 的矢量))

fx1 = - udX * force  
fy1 = - udY * force  
(and force vector for object2 if needed)
fx2 = - fx1
fy2 = - fy1

First object velocity vector is (vx1, vy1) .第一个 object 速度向量是(vx1, vy1) At every step you have to modify it with acceleration, where deltaT is time period between cadrs.在每一步,您都必须通过加速来修改它,其中deltaT是 cadr 之间的时间段。

vx1 = vx1 + fx1 / mass1 * deltaT
vy1 = vy1 + fy1 / mass1 * deltaT

Now you can modify position with velocity现在您可以使用速度修改 position

x1 = x1 + vx * deltaT
y1 = y1 + vy * deltaT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM