I am trying to make a program where object1 movement is warped by the gravity of object2. It should get flung. However, for some reason the velocity never decreases or goes negative. I expect for the velocity to change in both directions, but this does not happen. Can anyone tell me why? Here is the code.
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);
double[] vect1 = {1, 0}, 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);
object2.lock();
gameTimer.start();
}
private Timer gameTimer = new Timer(1000 / 30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
double[] v = Mass.vector(object1, object2);
object1.dx += v[0];
object1.dy += v[1];
Point p = new Point(
(int) (object1.center.x + object1.dx),
(int) (object1.center.y + object1.dy)
);
object1.center = p;
System.out.println("[" + object1.center.x + "," + 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);
}
});
}
}
Mass.java
import java.awt.Point;
public class Mass {
public static double G = 1f;
public static double deltaTime = 1;
public Point center;
public double mass;
public double radius;
public double dx = 0;
public double dy = 0;
public boolean locked = false;
public Mass(Point center, double[] vect, double mass) {
this.center = center;
this.dx = vect[0];
this.dy = vect[1];
this.mass = mass;
this.radius = mass;
}
public void lock() {
this.locked = true;
}
public void unlock() {
this.locked = false;
}
public static double distance(Mass obj1, Mass obj2) {
double dX = obj1.center.x - obj2.center.x;
double dY = obj1.center.y - obj2.center.y;
double ans = Math.sqrt(Math.pow(dX, 2) + Math.pow(dY, 2));
return (double) ans;
}
public static double force(Mass obj1, Mass obj2) {
double ans = ((obj1.mass * obj2.mass) / Math.pow(distance(obj1, obj2), 2)) * G;
return (double) ans;
}
public static double[] vector(Mass obj1, Mass obj2) {
double force = force(obj1, obj2);
double dX = Math.abs(obj1.center.x - obj2.center.x);
double dY = Math.abs(obj1.center.y - obj2.center.y);
double udX = dX / distance(obj1, obj2);
double udY = dY / distance(obj1, obj2);
double fx = -(udX * force);
double fy = -(udY * force);
double x = obj1.dx + fx / obj1.mass * deltaTime;
double y = obj1.dy + fy / obj1.mass * deltaTime;
double[] v = {x, y};
return v;
}
}
Thank you in advance. I derived my formula from F = G(m1*m2)/r^2.