processing模拟刚体碰撞,最终碰撞次数趋近于π

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

创作不易多谢照顾。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值