繁体   English   中英

Object 加速不符合预期

[英]Object acceleration not behaving as expected

我在二维空间中有两个对象。 我希望object1开始围绕object2运行。 我从等式中得出我的方法

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

dx1 += x1 - x2 * f

等等。但是,我很挣扎,因为 object 只在 pos pos 方向移动。 这是每个 object 的 class:

质量.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;
    }
}

这是主要的class。

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

我让它始终打印出object1 (未锁定的对象)的 DX 和 DY。 正如预期的那样,它似乎被甩得非常快,但它从不减速。 相反,dx 只是越来越慢地增加。 我不是很数学,但它似乎是逻辑的。 我想知道为什么会这样。

到目前为止,我已经尝试重写我的公式并使用不同的方程。 我也尝试过使用不同的数据类型,并使一些事情变得消极。 但是,没有任何效果。

TLDR,问题:对象没有像预期的那样改变 DX / DY。

提前谢谢您,对不起,如果这是在其他地方发布的。 我找不到任何重复项。

好的,让我们尝试推导公式。

您已经有了差异向量dX, dY ,并且还制作了归一化向量

udX = dX / distance
udY = dY / distance

你也有force大小。 要获得 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

第一个 object 速度向量是(vx1, vy1) 在每一步,您都必须通过加速来修改它,其中deltaT是 cadr 之间的时间段。

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

现在您可以使用速度修改 position

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

暂无
暂无

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

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