Processing.js で物理シミュレーション

From Usipedia
Jump to: navigation, search

Contents

Processing.js とは?

ProcessingをHTML5+JavaScript環境でも描画出来てしまうライブラリです.文法は通常のProcessingと同じで,Javaを単純にしたものが使えます.

単振動と減衰振動の軌跡とトラジェクトリを描画する

ProcessingOscillation.png

Javaっぽく書ける利点を最大限活かしています.

原理

高校物理の範囲です

ソースコード

<!DOCTYPE html>
<html>
<head>
	<script src="./processing.js"></script>
	<script src="./init.js"></script>
	<link rel="stylesheet" href="./style.css"/></head>
<body>
 
<h1>単振動と減衰振動の軌跡とトラジェクトリの描画</h1>
<h2>難読化などを施していないのでこのプログラムのソースコードは自由に見られます.</h2>
<script type="application/processing">
float time = 0.0;
Oscillation o0;
DecreasingOscillation1 o1;
DecreasingOscillation2 o2;
DecreasingOscillation3 o3;
 
void setup() {
	size(800, 600);
	smooth();
	amplitude = width/4 - R;
	omega = PI;
	background(255);
	ellipseMode(CENTER);
	rectMode(CENTER); 
 
	o0 = new Oscillation(width/8, R+20);
	o1 = new DecreasingOscillation1(width*3/8, R+20);
	o2 = new DecreasingOscillation2(width*5/8, R+20);
	o3 = new DecreasingOscillation3(width*7/8, R+20);
}
 
void draw() {
	time = millis() / 250;
	// time = millis() / 50; // for debug
	o0.draw();
	o1.draw();
	o2.draw();
	o3.draw();
}
 
class Oscillation {
	float x;
	float y;
	float R = 10;
	float speed = 5.0;
	float amplitude = width/8 - R;
	float omega0 = PI;
	float oldX = 0.0;
	float oldY = 0.0;
 
	Oscillation(float x, float y){
		this.x = x;
		this.y = y;
	}
 
	void draw(){
		noStroke();
 
		// 軌跡
		pushMatrix();
		{
			translate(x, y);
			// 軌跡
			fill(0, 30);
			ellipse(oldX, oldY-R-6, 2, 2);
			// 消すための円
			fill(255);
			ellipse(oldX, oldY, 2*R+5, 2*R+5);
			// 描くための円
			fill(0, 100);
			oldX = calcX();
			oldY = speed*time;
			ellipse(oldX, oldY, 2*R, 2*R);
		}
		popMatrix();
 
		// トラジェクトり
		pushMatrix();
		{
			translate(x, height-50-5);
			fill(0, 5);
			// canvasは左上が原点
			ellipse(oldX, calcV(), 5, 5);
		}
		popMatrix();
	}
 
	float calcX(){
		return amplitude * cos(omega0 * time);
	} 
 
	float calcV(){
		//見やすく調整した値を返す
		//return -amplitude * omega0 * sin(omega0 * time);
		return -50 * sin(omega0 * time);
	}
}
 
class DecreasingOscillation1 extends Oscillation {
	float gmma;
	float omega;
	DecreasingOscillation1(float x, float y){
		super(x, y);
		gamma = 0.04; // > PI で振動しなくなる
		omega = Math.sqrt(omega0 * omega0 - gamma * gamma);
	}
 
	float calcX(){
		return Math.pow(Math.E, -gamma*time) * amplitude * cos(omega * time);
	}
 
	float calcV(){
		return -50 * Math.pow(Math.E, -gamma*time) * (sin(omega * time) + gamma*cos(omega * time)/omega);
	}
}
 
class DecreasingOscillation2 extends DecreasingOscillation1 {
	DecreasingOscillation2(float x, float y){
		super(x, y);
	}
 
	float calcX(){
		return Math.pow(Math.E, -gamma * time) * amplitude * (1 + time * gamma);
	}
 
	float calcV(){
		return -2.5 * Math.pow(Math.E, -gamma*time) * time; // 分かりやすくするために2.5
	}
}
 
class DecreasingOscillation3 extends DecreasingOscillation1 {
	float mu;
	float gamma;
	float lambda1;
	float lambda2;
	float A;
	float B;
	DecreasingOscillation3(float x, float y){
		super(x, y);
		gamma = PI+2; // > PIにする
		mu = Math.sqrt(gamma * gamma - omega * omega);
		lambda1 = mu - gamma;
		lambda2 = -(mu+gamma);
		A = amplitude * lambda2 / (lambda2 - lambda1);
		B = amplitude * lambda1 / (lambda2 - lambda1);
	}
 
	float calcX(){
		return (A * Math.pow(Math.E, lambda1 * time) + B * Math.pow(Math.E, lambda2 * time))/1.2; // 見やすいように調整した
	}
 
	float calcV(){
		return 25*(Math.pow(Math.E, lambda1 * time) + (B/A) * (lambda2/lambda1) * Math.pow(Math.E, lambda2 * time));
	}
}
 
</script><canvas width="800" height="600"></canvas>
<br>
S学科 B1 10268010 石川直樹 
</p>
</body>
</html>
Namespaces
Variants
Views
Actions
Categories