# 投稿記事

28 Jun 2016

## Forces

var Mover = function() {
// 簡単にするため質量は　１　とする
this.mass = 1;
this.position = new processing.PVector(30, 30);
this.velocity = new processing.PVector(0, 0);
this.acceleration = new processing.PVector(0, 0);
};

// ニュートンの第２法則をシミュレートする
// force　を受取り, 質量で割り, 加速度に加える
Mover.prototype.applyForce = function(force) {
var f = processing.PVector.div(force, this.mass);
};

Mover.prototype.update = function() {
// Vectorsの最初の例でシミュレートする
// 毎回加速度をクリア
this.acceleration.mult(0);
};

Mover.prototype.display = function() {
processing.stroke(0);
processing.strokeWeight(2);
processing.fill(255, 255, 255, 127);
// 質量により、サイズを変更する
processing.ellipse(this.position.x, this.position.y, this.mass*30, this.mass*30);
};

// mover をエッジでバウンドさせるため、速度を変えています
Mover.prototype.checkEdges = function() {
if (this.position.x > width) {
this.position.x = width;
this.velocity.x *= -1;
} else if (this.position.x < 0) {
this.velocity.x *= -1;
this.position.x = 0;
}
if (this.position.y > height) {
this.velocity.y *= -1;
this.position.y = height;
}
};
// setup
processing.setup = function(){
// canvas size
processing.size(width,height);
};
// mover生成
var m = new Mover();

processing.draw = function() {
processing.background(66, 66, 66);
//風と重力
var wind = new processing.PVector(0.01, 0);
var gravity = new processing.PVector(0, 0.1);
m.applyForce(wind);
m.applyForce(gravity);

m.update();
m.display();
m.checkEdges();
};


### Many objects

var Mover = function(m, x, y) {
this.mass = m;
this.position = new processing.PVector(x, y);
this.velocity = new processing.PVector(0, 0);
this.acceleration = new processing.PVector(0, 0);
};

.....

Mover.prototype.display = function() {
processing.stroke(0);
processing.strokeWeight(2);
processing.fill(255, 255, 255, 127);
processing.ellipse(this.position.x, this.position.y, this.mass*30, tmass*30);
};
....
var m = [];
for (var i = 0; i < 20; i++) {
m[i] = new Mover(processing.random(0.1, 5), 0, 0);
};

.....


### Many objects 2

Mover.prototype.calculateWallForce = function() {
var fx = 0;
var fy = 0;
if (this.position.x > width) {
fx = -1;
} else if (this.position.x < 0) {
fx =1;
}
if (this.position.y > height) {
fy = -1;
} else if (this.position.y < 0) {
fy = 1;
}
return new processing.PVector(fx,fy);
};
....
processing.draw = function() {
processing.background(66, 66, 66);
for (var i = 0; i < m.length; i++) {
var wind = new processing.PVector(0.01, 0);
var gravity = new processing.PVector(0, 0.1);

m[i].applyForce(wind);
m[i].applyForce(gravity);
m[i].applyForce(m[i].calculateWallForce());
m[i].update();
m[i].display();
};
};


## Modeling gravity and friction

### gravity

processing.draw = function() {
processing.background(66, 66, 66);

for (var i = 0; i < m.length; i++) {
var wind = new processing.PVector(0.01, 0);

var gravity = new processing.PVector(0, 0.1 * m[i].mass);

m[i].applyForce(wind);
m[i].applyForce(gravity);
m[i].update();
m[i].display();
m[i].checkEdges();
};
};


### friction

for (var i = 0; i < movers.length; i++) {
var wind = new processing.PVector(0.01, 0);
var gravity = new processing.PVector(0, 0.1*movers[i].mass);

var c = 0.01; // 摩擦係数
var normal = 1; // 垂直抗力
var frictionMag = c * normal;　// 抗力
var friction = movers[i].velocity.get(); // 速度の取得
friction.mult(-1); // 速度の向きを反転
friction.normalize(); //　単位ベクトル化
friction.mult(frictionMag); // 摩擦力の大きさ

movers[i].applyForce(friction); // 摩擦力を適用
movers[i].applyForce(wind); // 風力を適用
movers[i].applyForce(gravity); // 重力を適用
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}


### Air and fluid resistance

$$F_{d} = -\frac{1}{2}\rho v^{2}AC_{d}\hat{v}$$ $$F_{d} : Drag \quad force(抗力)$$ $$-\frac{1}{2} : 定数$$ $$\rho : 流体の密度$$ $$v^2 : v は物体のスピードで、速度ベクトルの大きさ -- velocity.mag()$$ $$A : 流体を押す物体の正面の面積$$ $$C_{d} : 抗力係数$$ $$_hat{v} : 速度の単位ベクトル -- velocity.normalize()$$
// Calculate drag force
Liquid.prototype.calculateDrag = function(m) {
// Magnitude is coefficient * speed squared
var speed = m.velocity.mag();
var dragMagnitude = this.c * speed * speed;

// Direction is inverse of velocity
var dragForce = m.velocity.get();
dragForce.mult(-1);

// Scale according to magnitude
// dragForce.setMag(dragMagnitude);
dragForce.normalize();
dragForce.mult(dragMagnitude);
return dragForce;
};
....
for (var i = 0; i < movers.length; i++) {

// Is the Mover in the liquid?
if (liquid.contains(movers[i])) {
// Calculate drag force
var dragForce = liquid.calculateDrag(movers[i]);
// Apply drag force to Mover
movers[i].applyForce(dragForce);
}
....


### Gravitational attraction

$$F=G\frac{m_{1} \dot m_{2}}{r^2}\hat{r}$$ $$F:引力$$ $$G:万有引力定数=6.67408x10^{-11}m^{3}kg^{-1}s^{-2}$$ $$m_{1},m_{2}:物体の質量$$ $$r:物体間の距離$$ $$\hat{r}:距離の単位ベクトル$$
Attractor.prototype.calculateAttraction = function(mover) {
// Calculate direction of force
var force = processing.PVector.sub(this.position, mover.position);
// Distance between objects
var distance = force.mag();
// Limiting the distance to eliminate "extreme" results
// for very close or very far objects
distance = processing.constrain(distance, 5, 25);
// Normalize vector
force.normalize();
// Calculate gravitional force magnitude
var strength = (this.G * this.mass * mover.mass) / (distance * distance);
// Get force vector --> magnitude * direction
force.mult(strength);
return force;
};


### Mutual attraction

Mover.prototype.calculateAttraction = function(m, i) {
// Calculate direction of force
var force = processing.PVector.sub(this.position, m.position);
// Distance between objects
var distance = force.mag();
// Limiting the distance to eliminate "extreme" results for very closevery far objects
distance = processing.constrain(distance, 5.0, 25.0);
// Normalize vector (distance doesn't matter here, we just want tvector for direction
force.normalize();
// Calculate gravitional force magnitude
var strength = (G * this.mass * m.mass) / (distance * distance);
// Get force vector --> magnitude * direction
force.mult(strength);
return force;
};

...

processing.draw = function() {
processing.background(50, 50, 50);

for (var i = 0; i < movers.length; i++) {
for (var j = 0; j < movers.length; j++) {
if (i !== j) {
var force = movers[j].calculateAttraction(movers[i]);
movers[i].applyForce(force);
}
}

movers[i].update();
movers[i].display();
}
};