怎样用processing代码让你的女朋友对你心服口服

下雨天跑得快淋雨多还是跑得慢淋浴多?

起因

上周天气不太好,阴雨连连,和女朋友跑到小区门口去买阔口阔落。哪知就这一会的功夫天上就下起了大雨。这时候她认为我们需要快点跑,早点到家,而我认为跑的快慢并不影响我们被淋多少雨,只取决于路程。她不服气,我就解释了:人向前,雨向下,综合起来雨滴会有斜向人的速度。整体算下来只要人的身高不变,速度不要太过分的小,淋多少雨跟走快慢无关。等我解释完,她已经到家了,然后我指着我们身上的水又解释了一遍,她让我抓紧换衣服少说废话。我知道,要强的她是不会轻易服输的,她只是嘴上不说。于是我想起了小学时背诵的一篇古文:恋爱像弹簧,看你强不强。你强她就弱,你弱她就强。为了纠正她这个坏毛病,不能惯着,所以我决定,写个程序来模拟一下下雨的场景。

经过

涉及图像模拟,当然选用Processing是最好的。
思路是:创建2d对象模拟雨滴下落,人体抽象成一个柱体。雨滴落到人身上改变颜色并计数,然后显示出来,跑到屏幕最右边查看计数器即可。因为雨滴落下需要时间,所以,可以等一会再让“人”出来,等待的方式就是简单粗暴的计数(temp),超过100时雨滴基本已经全部下来了。如果直接用延时会比较麻烦,所以采用这个方式。
代码如下:
RainTest类:

import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;
Box2DProcessing box2d;
Box box;
int count,temp=0;
int speed=40;
ArrayList<Particle> particles;
float xoff = 0;
float yoff = 1000;
void setup() {
  size(2000,300);
  textSize(64);
  smooth();
 box2d = new Box2DProcessing(this);
 box2d.createWorld();
 box2d.listenForCollisions();
 particles = new ArrayList<Particle>();


}

void draw() {
  background(0);
  temp++;
    if(temp==100){
     box = new Box(0,height/3); 
    }
    float sz = 2;
    particles.add(new Particle(random(0,width),-20,sz));
    box2d.step();

  xoff += 0.01;
  yoff += 0.01;

  for (int i = particles.size()-1; i >= 0; i--) {
    Particle p = particles.get(i);
    p.display();
    if (p.done()) {
      particles.remove(i);
    }
  }

  text(" Raindrops:"+count, width/3, height/5);
  if(temp>100){
    box.body.setAngularVelocity(0);
    box.display();
    box.body.setLinearVelocity(new Vec2(speed, 0));
}

}


void beginContact(Contact cp) {
  Fixture f1 = cp.getFixtureA();
  Fixture f2 = cp.getFixtureB();
  Body b1 = f1.getBody();
  Body b2 = f2.getBody();
  Object o1 = b1.getUserData();
  Object o2 = b2.getUserData();
  if (o1.getClass() == Box.class) {
    Particle p = (Particle) o2;
    p.change();
    count++;
  } 
  else if (o2.getClass() == Box.class) {
    Particle p = (Particle) o1;
    p.change();
    count++;
  }
}  

Box类(模拟人体)

class Box {
  Body body;
  float w;
  float h;
  Box(float x_, float y_) {
    float x = x_;
    float y = y_;
    w = 24;
    h = 48;
    makeBody(new Vec2(x, y), w, h);
    body.setUserData(this);
  }
  void killBody() {
    box2d.destroyBody(body);
  }

  boolean contains(float x, float y) {
    Vec2 worldPoint = box2d.coordPixelsToWorld(x, y);
    Fixture f = body.getFixtureList();
    boolean inside = f.testPoint(worldPoint);
    return inside;
  }
  void display() {
    Vec2 pos = box2d.getBodyPixelCoord(body);
    float a = body.getAngle();
    rectMode(PConstants.CENTER);
    pushMatrix();
    translate(pos.x, pos.y);
    rotate(-a);
    fill(175);
    stroke(0);
    rect(0, 0, w, h);
    popMatrix();
  }

  
  void makeBody(Vec2 center, float w_, float h_) {
    
    BodyDef bd = new BodyDef();
    bd.type = BodyType.DYNAMIC;
    bd.position.set(box2d.coordPixelsToWorld(center));
    body = box2d.createBody(bd);
    PolygonShape sd = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(w_/2);
    float box2dH = box2d.scalarPixelsToWorld(h_*2);
    sd.setAsBox(box2dW, box2dH);
    FixtureDef fd = new FixtureDef();
    fd.shape = sd;
    fd.density = 1;
    fd.friction = 0.3;
    fd.restitution = 0.5;
    body.createFixture(fd);
  }
}

Particle类(模拟雨滴):

class Particle {
  Body body;
  float r;
  color col;


  Particle(float x, float y, float r_) {
    r = r_;
    makeBody(x, y, r);
    body.setUserData(this);
    col = color(200);
  }
  void killBody() {
    box2d.destroyBody(body);
  }

  void change() {
    col = color(255, 0, 0);
  }
  boolean done() {
    Vec2 pos = box2d.getBodyPixelCoord(body);
    if (pos.y > height+r*2) {
      killBody();
      return true;
    }
    return false;
  }
  void display(){ 
    Vec2 pos = box2d.getBodyPixelCoord(body);
    float a = body.getAngle();
    pushMatrix();
    translate(pos.x, pos.y);
    rotate(a);
    fill(col);
    stroke(0);
    strokeWeight(1);
    ellipse(0, 0, r*2, r*2);
    line(0, 0, r, 0);
    popMatrix();
  }
  void makeBody(float x, float y, float r) { 
    BodyDef bd = new BodyDef();
    bd.position = box2d.coordPixelsToWorld(x, y);
    bd.type = BodyType.DYNAMIC;
    body = box2d.createBody(bd);
    CircleShape cs = new CircleShape();
    cs.m_radius = box2d.scalarPixelsToWorld(r);
    FixtureDef fd = new FixtureDef();
    fd.shape = cs;
    fd.density = 1;
    fd.friction = 0.01;
    fd.restitution = 0.3;
    body.createFixture(fd);
    body.setAngularVelocity(random(-10, 10));
  }
}

经过简单地测试,我们将速度设为20的时候结果如下:
速度是20的运行结果
速度是40:
速度是40的运行结果
速度是60:
速度是60的运行结果
由于雨滴的位置是随机的,所以存在一点点误差是完全合情合理的。可以认为,在雨滴稳定的情况下,人淋雨多少,跟速度快慢并无关系!!!

结果

当我将我模拟程序成功跑起来之后,她已经睡着了,我兴奋地喊她起来看一下我被我成功验证的猜想。在我花了三分钟终于叫醒她之后,她回了我一句“滚”,然后就又睡了。但是我知道,我已经赢了

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值