互动编程习作——表现随机行为及牛顿力

习作1

随机游走类

示例代码0-1 传统的随机游走
在这里插入图片描述

“传统”随机游走模型中的上述变量,都有一个共同点:在任意时刻,游走对象朝某一个方 向移动的概率等于它朝其他任意方向移动的概率。比如,如果游走对象有4个可能的移动 方向,它朝某个方向移动一步的概率就是1/4(25%);如果它有9个可能的移动方向,朝 某个方向移动的概率是1/9(11%)。

示例代码0-2 随机数的分布
在这里插入图片描述
上面的截图是本例运行几分钟后的结果。请注意柱状图中每个矩形的高度。我们选取的样 本量(随机数个数)很少,有些偶然因素能使某些随机数被较多选中。如果有一个优秀的 随机数生成器,随着时间推移和样本量的增加,整幅图将会被拉平。 伪随机数 我们从random()函数中取得的随机数并不是真正随机的,因此它们称为"伪随机 数"。它们是由模拟随机的数学函数生成的。随着时间推移,这个函数将呈现出固定 的模式,但那段时间很长,所以对我们来说,它的随机性已经足够了。
在这里插入图片描述

float ex,ey; 
void setup() {   
size(618,618); 
ex=width/2;ey=width/2; 
}   
void draw() {  
ellipse(ex,ey,66,66);       
int r=int(random(4));   //1,2,3  
if(r==0){    
ex++;  
}  
else if(r==1){    
ex--;  
}  
else if(r==2){    
ey++;  
}
else{    
ey--;  
}}

在这里插入图片描述

斜上游走 ex++;ey++; 同时 会得到斜下的运动。
在这里插入图片描述

随机游走:
生成-1,0,1
也就是说-1是x-- ,0原地,1为x++
但是-1 不是int,所以算法是

ex+=(random(-1,1));//-1,0,1
ey+=(random(-1,1));//-1,0,1

动画是
在这里插入图片描述
时间越久会得到,八个方向游走。
在这里插入图片描述
拓展:
随机游走光滑轨迹

float t = 0.007; 
PVector p0=new PVector(0,400); 
void setup(){  
size(800,800);  
color(255);    
smooth();}
int value =1; 
PVector p = new PVector(400,400);
void draw(){    
float sk = random(100);  
if (sk>75){   
p = new PVector(p.x+sk*t,p.y+(100-sk)*t);   
value=0;}  
else {    
if (sk>50){   
p = new PVector(p.x+sk*t,p.y-(100-sk)*t);    
//p = new PVector(p.x+s*t,p.y);   
value=1;}   
else {     
if (sk>25){       
p = new PVector(p.x-sk*t,p.y+(100-sk)*t);       
//p = new PVector(p.x,p.y+(1-s)*t);     
}     
else {       
p = new PVector(p.x-sk*t,p.y-(100-sk)*t);       
//p = new PVector(p.x,p.y);      
}   
}  
}  
if (p.x>800) p.x-=800;  
else {   
if (p.x<0) p.x+=800;  
}  if (p.y>800) p.y-=800;  
else {   
if (p.y<0) p.y+=800;  
}   
ellipse(p.x,p.y,20,20);  
fill(#7FFFD4);   
}

结果演示得:
在这里插入图片描述
习作一的难度没有很高,通过网上视频形式学习和阅读PDF算是能做出来的。
习作2
第一章 向量

参考程序 示例代码1-1 没有使用向量的弹球。

和示例代码1-2的用pvector对象实现弹球。

在这里插入图片描述
在这里插入图片描述
因此这些是关于弹弹球的过程,而制作弹弹球我们肯定首先要画一个圆,接着还要设置碰到边框就反弹等程序,还可以加上背景颜色和球的颜色,更好看。
代码:

 
 float circle_x=0;
 
 void setup(){
   size(400, 400);
   noStroke();
   fill(#C1FF3E);
 }
 float moveX = 2;
 float moveY = 2;
 float radiu =50;
 float radiuPosX = 50;
 float radiuPosY = 0;
 boolean isXSub= true;
  boolean isYSub= true;
  void draw(){
    background(#1BB1F5);
    ellipse(radiuPosX,radiuPosY, radiu,radiu);
    if(isXSub){
      radiuPosX += moveX;
    }else {
      radiuPosX -=moveX;
    }
    if (radiuPosX >width) {
    radiuPosX =width;
   isXSub = false;
  }
  if (radiuPosX < 0){
    radiuPosX = 0;
    isXSub= true;
  }
  if (isYSub){
     radiuPosY += moveY;
  }else {
    radiuPosY -= moveY;
    }
    
    if (radiuPosY>height){
      radiuPosY =height;
      isYSub = false;
    }
    if (radiuPosY < 0) {
      radiuPosY =0;
      isYSub= true;
    }
    }

结果运行得到:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
这个代码比较好懂,从代码本色中有点不一样了。可以最终实现弹球的效果,有一定的速度。往回进行得到加速度一定的圆球的弹回运动。

习作3
第二章力 万有引力相关
在第1章的最后一个示例中,我们让一个圆朝着鼠标所在的方向运动,
并由此展示了如何计算动态加速度。程序运行后,我们看到圆和鼠
标之间有吸引作用,仿佛有个力在拉近它们之间的距离。本章,我
们会正式学习力的概念以及力和加速度的关系。希望到本章的最后,
你能学会如何模拟物体在各种外力作用下的运动。
参考示例2-6 引力
在这里插入图片描述
和示例2-8 万有引力
在这里插入图片描述

在第1章的最后一个示例中,我们让一个圆朝着鼠标所在的方向运动,
并由此展示了如何计算动态加速度。程序运行后,我们看到圆和鼠
标之间有吸引作用,仿佛有个力在拉近它们之间的距离。本章,我
们会正式学习力的概念以及力和加速度的关系。希望到本章的最后,
你能学会如何模拟物体在各种外力作用下的运动。
代码:

float r, theta;
float speed;

void setup() {
size(400, 400);
r = 150.0;
theta = 0.0; // theta = 0 to TWO_PI
speed = 0.05;
}

void draw() {
background(0, 0, 0);
noStroke();

// draw the sun
fill(255, 255, 0);
translate(width/2, height/2);
ellipse(0, 0, 50, 50);

// draw the earth
theta += speed;
float x = r * cos(theta);
float y = r * sin(theta);
fill(0, 255, 255);
translate(x, y);
ellipse(0, 0, 20, 20);
}

运行可得:

在这里插入图片描述
在这里插入图片描述
这个跟习作三的风格有点类似。
x,y的参数。一定的速度和圆周运动的圆的半径大小。进行循环圆周运动。
习作4
第三章 振荡 三角函数正弦
参考代码本色的示例代码3-2 力和(随意)角运动的结合
在这里插入图片描述
练习3.2
步骤L模拟物体被大炮射岀的场景,在这个过程中,物体
受两个力的作用,即发射力(只有一次)和重力(一直作用
在物体上)。
步骤2:假设物体从大炮中发射岀去时会发生旋转,模拟
旋转效果。

现在,我们只需要一个简单快捷的解决方法:简单地将物体的加速
度向量映射成一个合理的角加速度。比如:
aAcceleration = acceleration.x;
这是一种很随意的方法,但却能起到一定的效果。如果物体的加速
度向右,它就有一个顺时针的角加速度;如果加速度向左,它就有
一个逆时针的角加速度。除了方向,我们还要考虑角加速度的大小。
加速度的X分量可能很大,以至于会导致物体旋转的速度过快,使运
行效果不符合实际情况。为了得到一个大小合理的角加速度,我们
可以将X分量除以某个值,或将角速度限定在合理的范围内。下面给出的Update函数充分考虑这一情况。

参考二的示例1-10
在这里插入图片描述
在这个例子中,我们让Mover对象朝着鼠标所在
的方向加速。
向量是三角形的
斜边,它的x分量和y分量是三角形的两条直角边。图中还标注了一
个夹角,这个夹角可以用来表示向量的方向。
代码:

`class Mover{
PVector location;
PVector velocity;
PVector acceleration;
float mass;
float G;
Mover(float m_, float x_, float y_){
location = new PVector(x_, y_);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
mass = m_;
G = 1;
}
Mover(){
location = new PVector(random(width), random(height));
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
mass = 1;
G = 1;
}

void applyForce(PVector force){
PVector f = PVector.div(force, mass);
acceleration.add(f);
}

void update(){
velocity.add(acceleration);
location.add(velocity);

acceleration.mult(0);

}
void display(){
stroke(0);
fill(175);
ellipse(location.x, location.y, mass16, mass16);
}

void checkEdges(){
if(location.x > width){
location.x = width;
velocity.x *= -1;
}else if(location.x < 0){
location.x = 0;
velocity.x *= -1;
}

if(location.y > height){
  location.y = height;
  velocity.y *= -1;
}else if(location.y < 0){
  location.y = 0;
  velocity.y *= -1;
}

}

boolean isInside(Liquid l){
if(location.x > l.x && location.x < l.x+l.w && location.y > l.y && location.y < l.y+l.h){
return true;
}else{
return false;
}
}

void drag(Liquid l){
float speed = velocity.mag();
float dragMagnitude = 0.5*l.c * speed *speed;

PVector drag = velocity.get();
drag.mult(-1);
drag.normalize();

drag.mult(dragMagnitude);
applyForce(drag);

}
PVector disAttract(Mover m){
PVector force = PVector.sub(location, m.location);
float distance = force.mag();
distance = constrain(distance, 5, 10);
force.mult(-1);
force.normalize();

float strength = (G * mass * m.mass)/(distance * distance);
force.mult(strength);
return force;

}

PVector attract(Mover m){
PVector force = PVector.sub(location, m.location);
float distance = force.mag();
distance = constrain(distance, 5, 10);
force.normalize();

float strength = (G * mass * mass)/(distance * distance);
force.mult(strength);
return force;

}
}
class Liquid{
float x,y,w,h;
float c;
Liquid(float x_, float y_, float w_, float h_, float c_){
x = x_;
y = y_;
w = w_;
h = h_;
c = c_;
}
void display(){
noStroke();
fill(175);
rect(x, y, w, h);
}
}
class Attractor{
float mass;
PVector location;
float G;
Attractor(){
location = new PVector(width/4, height/4);
mass = 20;
G = 1;
}
Attractor(float m_, float x_, float y_){
location = new PVector(x_, y_);
mass = m_;
G = 1;
}
void update(){
location.x = mouseX;
location.y = mouseY;
}
void display(){
stroke(0);
fill(175, 0);
ellipse(location.x, location.y, mass2, mass2);
}
PVector attract(Mover m){
PVector force = PVector.sub(location, m.location);
float distance = force.mag();
distance = constrain(distance, 5, 25);
force.normalize();
float strength = (Gmassm.mass)/(distancedistance);
force.mult(strength);
return force;
}
PVector disAttract(Mover m){
PVector force = PVector.sub(location, m.location);
float distance = force.mag();
distance = constrain(distance, 7, 7);
force.normalize();
force.mult(-1);
float strength = (G
massm.mass)/(distancedistance);
force.mult(strength);
return force;
}
}

Mover[] movers = new Mover[4];
Attractor disA;
void setup(){
size(600, 600);
for(int i = 0; i < movers.length; i++){
movers[i] = new Mover(random(1,1), random(width), random(height));
}
disA = new Attractor(50, width/4, height/4);
}
void draw(){
//background(255);
disA.update();
for(int i = 0; i < movers.length; i++){
for(int j = 0; j < movers.length; j++){
if(i != j){
PVector force = movers[j].disAttract(movers[i]);
movers[i].applyForce(force);
}
}
PVector abs = disA.attract(movers[i]);
movers[i].applyForce(abs);
movers[i].update();
movers[i].display();
}
}`
运行得到的是
通过鼠标点哪里他就会运动,而且他的参数是可以调的。
在这里插入图片描述在这里插入图片描述
习作5粒子系统
第四章粒子系统
“粒子系统是由许多粒子组成的用于代表模糊对象的集合。
在一段特定时间内,粒子在系统中生成、移动、转化,最后
消亡。“
在这里插入图片描述
代码:

int num = 1000;//the number of point(s).
float mts = PI/24;//max theta speed.
int r = 100;//radius of the circle
int rdtr = 5;//range of the rdt
int rdu = 1;//radius of circle
//**********
PVector v[]=new PVector[num];
boolean mv = true;
boolean mo = true;
color c[] = new color[num];//color of each point.
float theta[] = new float[num];//original angle of each point.
float mtheta[] = new float[num];//translate angle to math value.
float dtheta[] = new float[num];//speed of theta.
float easing[] = new float[num];
int rdt[] = new int[num];//make a shuffle of radius.
void setup() {
colorMode(RGB,255,255,255);
size(250,250);
for(int i =0;i<num-1;i++){
c[i] = color(random(100,200),random(100,200),random(100,200));
v[i] = new PVector(random(width),random(height));
theta[i] = round(random(360));
dtheta[i] = random(mts);
mtheta[i] = theta[i]/180*PI;
rdt[i] = round(random(-rdtr,rdtr));
easing[i] = random(0.02,0.3);
}
frameRate(60);
}
void draw() {
fill(25,25,25,25);
rect(0,0,width,height);
pushMatrix();
noStroke();
if(mv){
if(mo){
for(int i = 0;i<num-1;i++){
mtheta[i] += dtheta[i];
v[i].lerp(mouseX+cos(mtheta[i])*(rdt[i]+r), mouseY+sin(mtheta[i])*(rdt[i]+r),0,easing[i]);
fill(c[i]);
ellipse(v[i].x, v[i].y, rdu,rdu);
}
}
if(!mo){
for(int i = 0;i<num-1;i++){
v[i].lerp(mouseX+cos(mtheta[i])*(rdt[i]+r), mouseY+sin(mtheta[i])*(rdt[i]+r),0,easing[i]);
fill(c[i]);
ellipse(v[i].x, v[i].y, rdu,rdu);
}
}
}
if(!mv){
if(mo){
for(int i = 0;i<num-1;i++){
mtheta[i] += dtheta[i];
v[i].lerp(mouseX+cos(mtheta[i])*rdt[i], mouseY+sin(mtheta[i])*rdt[i],0,easing[i]);
fill(c[i]);
ellipse(v[i].x, v[i].y, rdu,rdu);
}
}
if(!mo){
for(int i = 0;i<num-1;i++){
v[i].lerp(mouseX+cos(mtheta[i])*rdt[i], mouseY+sin(mtheta[i])*rdt[i],0,easing[i]);
fill(c[i]);
ellipse(v[i].x, v[i].y, rdu,rdu);
}
}
}
popMatrix();
fill(0);
rect(0,0,width,15);
fill(255);
textAlign(LEFT,TOP);
text("r = "+r,0,0);
text("fps = "+round(frameRate),40,0);
if(mv){
fill(255,0,0);
text("Running",100,0);
}
if(!mv){
text("Static",100,0);
}
if(mo) {
fill(255,0,0);
text("motion",150,0);
}
if(!mo){
fill(255);
text("stop",150,0);
}
}
void mousePressed(){
/*for(int i = 0;i<num-1;i++){
v[i] = new PVector(random(width),random(height));
theta[i] = round(random(360));
mtheta[i] = theta[i]/180*PI;
dtheta[i] = random(mts);
rdt[i] = round(random(-rdtr,rdtr)+r);
}*/
mv = !mv;
}
void keyPressed(){
if(key == 's'||key == 'S'){
mo =!mo;
}
}
void mouseWheel(MouseEvent event){
float e = event.getCount();
if(e == -1) r+=10;
if(e == 1) r-=10;
}

该程序一次性达到通过鼠标的点和速度来改变粒子的运动状态,如果不动就是粒子圆运动。在这里插入图片描述在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值