Processing.js で物理シミュレーション
From Usipedia
Contents |
Processing.js とは?
ProcessingをHTML5+JavaScript環境でも描画出来てしまうライブラリです.文法は通常のProcessingと同じで,Javaを単純にしたものが使えます.
単振動と減衰振動の軌跡とトラジェクトリを描画する
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>