processing模拟刚体碰撞,最终碰撞次数趋近于
π
\pi
π
昨天在网上看到了一个有趣的视频,说是理想情况下两个物体碰撞,当两个物体的质量比是 10 0 n 100^n 100n倍 n n n趋于无穷大时,碰撞次数会无限接近于 π \pi π。听起来很有趣,恰好processing很适合做这个事情。于是就尝试了一下,先给大家看结果
processing模拟刚体碰撞,最终碰撞次数趋近于π
当个两个质量块的质量比为 10 0 0 = 1 100^0=1 1000=1时,碰撞次数为3;当两个质量块重量比为 10 0 1 = 100 100^1=100 1001=100时,碰撞次数为31。由于再增加碰撞次数,整个过程时间会比较长,需要的路径也比较长,这里不好演示。
其中原理大家也可以再B站搜索,有专业的老师讲的比较仔细。
下面附上代码
PFont myFont;
void setup(){
// fullScreen(P2D);
size(1200,750,P2D);
rectMode(CENTER);
myFont = createFont("Times New Roman", 32);
textFont(myFont);
textAlign(CENTER, CENTER);
}
float i1 = width/10*8;
float i2 = width/10*6;
float v1 = -5;
float v2 = 0;
float v1_ = 0;
float v2_ = 0;
int times = 0;
float m1 = 1;
float m2 = 1;
float k = m1/m2;
boolean state = false;
boolean onbtn = false;
boolean onk1 = false;
boolean onk100 = false;
boolean onk10000 = false;
void draw(){
background(230, 230, 250, 30);
//m = 1
fill(118,113,219);
rect(100,height-200,120,120);
fill(255);
text("k = 1",100,height-200);
if(dist(mouseX, mouseY, 100,height-200)<60){
//cursor(HAND);
onk1 = true;
}
else {
//cursor(ARROW);
onk1 = false;
}
//m = 100
fill(118,113,219);
rect(300,height-200,120,120);
fill(255);
text("k = 100",300,height-200);
if(dist(mouseX, mouseY, 300,height-200)<60){
//cursor(HAND);
onk100 = true;
}
else {
//cursor(ARROW);
onk100 = false;
}
if(onk100 && mousePressed){
m1 = 100;
k = m1/m2;
}
//m = 10000
fill(118,113,219);
rect(500,height-200,120,120);
fill(255);
text("k=10000",500,height-200);
if(dist(mouseX, mouseY, 500,height-200)<60){
//cursor(HAND);
onk10000 = true;
}
else {
//cursor(ARROW);
onk10000 = false;
}
//启动按键
fill(0,0,100);
rect(width-280,height-200,120,120);
fill(0,200,0);
text(str(state),width-280,height-200);
//判断是否按下按键
if(dist(mouseX, mouseY, width-280,height-200)<60){
//cursor(HAND);
onbtn = true;
}
else {
//cursor(ARROW);
onbtn = false;
}
//绘制墙体
fill(0);
rect(50,height/2-70,10,300);
rect(45+(width-50)/2,height/2+80,width-50,10);
//是否开始运行
if(state){
i1 = i1+v1;
i2 = i2+v2;
v1_ = v1;
v2_ = v2;
if(i2<=80){
i2 = 80;
v2 = -v2;
times = times+1;
}
if((i1-i2)<=100){
if(times == 0){
i1 = i2+100;
v1 = (k-1)*v1_/(k+1);
v2 = k*(v1_-v1);
times = times+1;
}
else{
i1 = i2+100;
times = times+1;
//v1 = (k-1)*v1_/(k+1)-2*v2_/(k+1);
//v2 = 2*k*v1_/(k+1)+(k-1)*v2_/(k+1);
v1 = ((m1-m2)*v1_+2*m2*v2_)/(m1+m2);
v2 = ((m2-m1)*v2_+2*m1*v1_)/(m1+m2);
}
}
}
else{
i1 = width/10*8;
i2 = width/10*6;
v1 = -5;
v2 = 0;
v1_ = 0;
v2_ = 0;
times = 0;
state = false;
}
//绘制刚体
fill(20,20,20,50);
rect(int(i1), height/2,150, 150);
fill(0);
text("m1 = "+str(m1),int(i1), height/2-95);
fill(80,80,10,50);
rect(int(i2), height/2+50, 50, 50);
fill(0);
text("m2 = "+str(m2),int(i2), height/2-10);
//显示碰撞次数
fill(0);
text("times=" + str(times), width/2, 30);
text("v1 = " + str(v1), width/2, 60);
text("v2 = " + str(v2), width/2, 90);
text("m1/m2 = " + str(m1), width/2, 120);
}
void mousePressed(){
if(onbtn)
state = !state;
if(onk10000 && mousePressed){
m1 = 10000;
k = m1/m2;
}
if(onk100 && mousePressed){
m1 = 100;
k = m1/m2;
}
if(onk1 && mousePressed){
m1 = 1;
k = m1/m2;
}
}
}
创作不易多谢照顾。