具有质量碰撞问题的 2D 粒子 (JAVA)
2D particles with mass collision problem (JAVA)
初步
您好,我正在尝试为具有质量的粒子建模 2D 粒子碰撞。物理公式是
我的代码中的粒子有时会正确碰撞,但大多数时候只是粘在一起并开始不受控制地加速(参见下面的可运行 gif)。
代码和问题
我有一个粒子类型的 ArrayList,它有参数 x
y
VelX
VelY
, mass
(它从0.5 到 1.5) 和其他一些不重要的。 Particleclass里面的collide
方法是
public boolean collide(Particle other){
return Math.abs(this.x-other.x) < width
&& Math.abs(this.y-other.y) < height;
}
在主程序中我运行函数
public void actionPerformed(ActionEvent e) {
for(Particle particle : particleList) {
ArrayList<Particle> particleList2 = (ArrayList<Particle>) particleList.clone();
particleList2.remove(particleList.indexOf(particle));
for(Particle particle2 : particleList2) {
if(particle.collide(particle2)) {
particle.setVelY(velCollision(particle, particle2, 'y')[0]);
particle2.setVelY(velCollision(particle, particle2, 'y')[1]);
particle.setVelX(velCollision(particle, particle2, 'x')[0]);
particle2.setVelX(velCollision(particle, particle2, 'x')[1]);
}
}
particle.setX(particle.getX() + particle.getVelX());
particle.setY(particle.getY() + particle.getVelY());
}
repaint();
}
其中velCollision
方法如下
public double[] velCollision(Particle p1 , Particle p2 , char dir) {
double v1i=0,v2i=0,v1f=0,v2f=0;
double m1 = p1.getMass() , m2 = p2.getMass();
if (dir == 'x') {
v1i = p1.getVelX();
v2i = p2.getVelX();
} else {
v1i = p1.getVelY();
v2i = p2.getVelY();
}
v1f = ((m1-m2)/(m1+m2))*v1i + (2*m2/(m1+m2))*v2i;
v2f = ((m2-m1)/(m1+m2))*vi2 + (2*m1/(m1+m2))*v1i;
return new double[] {v1f, v2f};
}
我用
绘制所有东西
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(Particle particle : particleList) {
Shape circle = new Arc2D.Double(particle.getX(),particle.getY(),particle.getWidth(),
particle.getHeight(),
0 , 360, Arc2D.CHORD);
g2d.fill(circle);
}
}
这是我输出的一些运行功能
可运行文件 (GIF)
<a href="https://gyazo.com/79f0247a29935aea1f083d4aa3fa1a91"><img src="https://i.gyazo.com/79f0247a29935aea1f083d4aa3fa1a91.gif" alt="Image from Gyazo" width="300"/></a>
<a href="https://gyazo.com/5e88ccc6710cd6f508fd43c0b1bf8601"><img src="https://i.gyazo.com/5e88ccc6710cd6f508fd43c0b1bf8601.gif" alt="Image from Gyazo" width="300"/></a>
我真的不确定我做错了什么以及导致这个问题的原因。如果我更改 velCollision
方法,使两个粒子的速度对称反转(两个粒子的质量 = 1),那么程序 运行 就可以正常运行,并且粒子会正确碰撞。只有当我引入这个质量差异因子时,我的输出是错误的。
编辑
Particle
class :
import java.awt.Color;
public class Particle{
private double x;
private double y;
private double width;
private double height;
private double mass;
private double velX;
private double velY;
private float[] color;
public Particle(double x, double y, double width, double height, double velX, double velY,double mass, float[] color) {
this.x = x;
this.y=y;
this.width=width;
this.height=height;
this.velX=velX;
this.velY = velY;
this.mass=mass;
this.color=color;
}
public double getMass() {
return mass;
}
public void setMass(double mass) {
this.mass=mass;
}
public float[] getColor() {
return color;
}
public void setColor(float[] color) {
this.color=color;
}
public double getVelX() {
return velX;
}
public void setVelX(double velX) {
this.velX = velX;
}
public double getVelY() {
return velY;
}
public void setVelY(double velY) {
this.velY = velY;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public boolean collide(Particle other){
return Math.abs(this.x-other.x) < width
&& Math.abs(this.y-other.y) < height;
}
}
我可能发现了你的逻辑错误:
particle.setVelY(velCollision(particle, particle2, 'y')[0]);
particle2.setVelY(velCollision(particle, particle2, 'y')[1]);
particle.setVelX(velCollision(particle, particle2, 'x')[0]);
particle2.setVelX(velCollision(particle, particle2, 'x')[1]);
particle.setVelY(velCollision(particle, particle2, 'y')[0]);
的第一次调用更改了 particle
的字段,当您调用 particle2.setVelY(velCollision(particle, particle2, 'y')[1]);
时,它使用与第一次调用不同的值(因为第一次调用更改了值).只需调用您的方法一次并将 return 值保存在临时变量中。
像这样:
tempArrayY = velCollision(particle, particle2, 'y'); // is this correct?
tempArrayX = velCollision(particle, particle2, 'x'); // are both independent?
particle.setVelY(tempArrayY[0]);
particle2.setVelY(tempArrayY[1]);
particle.setVelX(tempArrayX)[0]);
particle2.setVelX(tempArrayX)[1]);
初步
您好,我正在尝试为具有质量的粒子建模 2D 粒子碰撞。物理公式是
我的代码中的粒子有时会正确碰撞,但大多数时候只是粘在一起并开始不受控制地加速(参见下面的可运行 gif)。
代码和问题
我有一个粒子类型的 ArrayList,它有参数 x
y
VelX
VelY
, mass
(它从0.5 到 1.5) 和其他一些不重要的。 Particleclass里面的collide
方法是
public boolean collide(Particle other){
return Math.abs(this.x-other.x) < width
&& Math.abs(this.y-other.y) < height;
}
在主程序中我运行函数
public void actionPerformed(ActionEvent e) {
for(Particle particle : particleList) {
ArrayList<Particle> particleList2 = (ArrayList<Particle>) particleList.clone();
particleList2.remove(particleList.indexOf(particle));
for(Particle particle2 : particleList2) {
if(particle.collide(particle2)) {
particle.setVelY(velCollision(particle, particle2, 'y')[0]);
particle2.setVelY(velCollision(particle, particle2, 'y')[1]);
particle.setVelX(velCollision(particle, particle2, 'x')[0]);
particle2.setVelX(velCollision(particle, particle2, 'x')[1]);
}
}
particle.setX(particle.getX() + particle.getVelX());
particle.setY(particle.getY() + particle.getVelY());
}
repaint();
}
其中velCollision
方法如下
public double[] velCollision(Particle p1 , Particle p2 , char dir) {
double v1i=0,v2i=0,v1f=0,v2f=0;
double m1 = p1.getMass() , m2 = p2.getMass();
if (dir == 'x') {
v1i = p1.getVelX();
v2i = p2.getVelX();
} else {
v1i = p1.getVelY();
v2i = p2.getVelY();
}
v1f = ((m1-m2)/(m1+m2))*v1i + (2*m2/(m1+m2))*v2i;
v2f = ((m2-m1)/(m1+m2))*vi2 + (2*m1/(m1+m2))*v1i;
return new double[] {v1f, v2f};
}
我用
绘制所有东西public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(Particle particle : particleList) {
Shape circle = new Arc2D.Double(particle.getX(),particle.getY(),particle.getWidth(),
particle.getHeight(),
0 , 360, Arc2D.CHORD);
g2d.fill(circle);
}
}
这是我输出的一些运行功能
可运行文件 (GIF)
<a href="https://gyazo.com/79f0247a29935aea1f083d4aa3fa1a91"><img src="https://i.gyazo.com/79f0247a29935aea1f083d4aa3fa1a91.gif" alt="Image from Gyazo" width="300"/></a>
<a href="https://gyazo.com/5e88ccc6710cd6f508fd43c0b1bf8601"><img src="https://i.gyazo.com/5e88ccc6710cd6f508fd43c0b1bf8601.gif" alt="Image from Gyazo" width="300"/></a>
我真的不确定我做错了什么以及导致这个问题的原因。如果我更改 velCollision
方法,使两个粒子的速度对称反转(两个粒子的质量 = 1),那么程序 运行 就可以正常运行,并且粒子会正确碰撞。只有当我引入这个质量差异因子时,我的输出是错误的。
编辑
Particle
class :
import java.awt.Color;
public class Particle{
private double x;
private double y;
private double width;
private double height;
private double mass;
private double velX;
private double velY;
private float[] color;
public Particle(double x, double y, double width, double height, double velX, double velY,double mass, float[] color) {
this.x = x;
this.y=y;
this.width=width;
this.height=height;
this.velX=velX;
this.velY = velY;
this.mass=mass;
this.color=color;
}
public double getMass() {
return mass;
}
public void setMass(double mass) {
this.mass=mass;
}
public float[] getColor() {
return color;
}
public void setColor(float[] color) {
this.color=color;
}
public double getVelX() {
return velX;
}
public void setVelX(double velX) {
this.velX = velX;
}
public double getVelY() {
return velY;
}
public void setVelY(double velY) {
this.velY = velY;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public boolean collide(Particle other){
return Math.abs(this.x-other.x) < width
&& Math.abs(this.y-other.y) < height;
}
}
我可能发现了你的逻辑错误:
particle.setVelY(velCollision(particle, particle2, 'y')[0]);
particle2.setVelY(velCollision(particle, particle2, 'y')[1]);
particle.setVelX(velCollision(particle, particle2, 'x')[0]);
particle2.setVelX(velCollision(particle, particle2, 'x')[1]);
particle.setVelY(velCollision(particle, particle2, 'y')[0]);
的第一次调用更改了 particle
的字段,当您调用 particle2.setVelY(velCollision(particle, particle2, 'y')[1]);
时,它使用与第一次调用不同的值(因为第一次调用更改了值).只需调用您的方法一次并将 return 值保存在临时变量中。
像这样:
tempArrayY = velCollision(particle, particle2, 'y'); // is this correct?
tempArrayX = velCollision(particle, particle2, 'x'); // are both independent?
particle.setVelY(tempArrayY[0]);
particle2.setVelY(tempArrayY[1]);
particle.setVelX(tempArrayX)[0]);
particle2.setVelX(tempArrayX)[1]);