Processing.jsで衝突運動

前回の続き。ムックの第6章Part2を読んで球同士の衝突運動を確認。

確認コード:collision_ballandball.html

<!DOCTYPE HTML>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Processing: parabolic motion</title>
</head>
<body>
	<canvas id="mycanvas"></canvas><br />
	White ball vx: <input type="number" name="wvx" id="wvx" value="3.5" min="0.0" max="5.0" step="0.1" /><br />
	White ball vy: <input type="number" name="wvy" id="wvy" value="-1.2" min="-5.0" max="5.0" step="0.1" /><br />
	<br />
	Red ball vx: <input type="number" name="rvx" id="rvx" value="0.0" min="-5.0" max="0.0" step="0.1" /><br />
	Red ball vy: <input type="number" name="rvy" id="rvy" value="0.0" min="-5.0" max="5.0" step="0.1" /><br />
	<br />
	<button onclick="startSketch();">Start</button>
	<button onclick="stopSketch();">Stop</button>

	<script src="processing-1.4.1.min.js" type="text/javascript"></script>
	<script type="application/processing" data-processing-target="mycanvas">
		// ball(white)
		float x1 = 40;
		float y1 = 200;
		float vx1 = 3.5;
		float vy1 = -1.2;

		// ball(red)
		float x2 = 200;
		float y2 = 180;
		float vx2 = 0.0;
		float vy2 = 0.0;

		float r = 30;

		void setup() {
		  size(400, 300);
		  background(0);
		  noLoop();
		}

		void draw() {
		  background(0);

		  fill(255);
		  // ball(white)
		  ellipse(x1, y1, r*2, r*2);
		  fill(255, 0, 0);
		  // ball(red)
		  ellipse(x2, y2, r*2, r*2);

		  // collision check
		  float l = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
		  if (l <= r*2) {
		     float vi = sqrt(vx1*vx1 + vy1*vy1);
		     float alpha = atan2(vy1, vx1);
		     float beta = atan2(y2-y1, x2-x1);
		     float diff = beta - alpha;

		     float th;
		     if (diff > PI || diff < -PI) {
		       th = TWO_PI - abs(diff);
		     }
		     else {
		       th = diff;
		     }

		     float vfa = abs(vi * sin(th));
		     float vfb = abs(vi * cos(th));

		     float buf;
		     if (diff > PI || diff < -PI) {
		       buf = HALF_PI + PI;
		     }
		     else {
		       buf = HALF_PI;
		     }

		     if (beta > alpha) {
		       vx1 = vfa * cos(beta - buf);
		       vx2 = vfa * sin(beta - buf);
		     }
		     else {
		       vx1 = vfa * cos(beta + buf);
		       vx2 = vfa * sin(beta + buf);
		     }

		     vx2 = vfb * cos(beta);
		     vy2 = vfb * sin(beta);
		  }

		  x1 = x1 + vx1;
		  y1 = y1 + vy1;
		  x2 = x2 + vx2;
		  y2 = y2 + vy2;
		}

		void setParameter() {
			vx1 = getWhiteVelocityX();
			vy1 = getWhiteVelocityY();

			vx2 = getRedVelocityX();
			vy2 = getRedVelocityY();
		}
	</script>
	<script type="text/javascript">
	    var processingInstance;

	    function startSketch() {
			switchSketchState(true);
	    }

	    function stopSketch() {
			switchSketchState(false);
	    }

	    function switchSketchState(on) {
	        if (!processingInstance) {
	            processingInstance = Processing.getInstanceById('mycanvas');
	        }

			if (on) {
				processingInstance.setParameter();
				processingInstance.loop();  // call Processing loop() function
			}
			else {
				processingInstance.noLoop(); // stop animation, call noLoop()
			}
		}

		function getWhiteVelocityX() {
			var vx = document.getElementById('wvx').value;
			return parseFloat(vx);
		}

		function getWhiteVelocityY() {
			var vy = document.getElementById('wvy').value;
			return parseFloat(vy);
		}

		function getRedVelocityX() {
			var vx = document.getElementById('rvx').value;
			return parseFloat(vx);
		}

		function getRedVelocityY() {
			var vy = document.getElementById('rvy').value;
			return parseFloat(vy);
		}

	</script>
</body>
</html>

参考サイト

ゲームプログラミング入門 (日経BPパソコンベストムック)
日経BP社 (2012-10-22)
売り上げランキング: 23469

関連エントリー

  1. Processing.jsで自由落下
  2. Processing.jsで放物運動
  3. Processing.jsで斜面落下
  4. Processing.jsでフォームの値を参照したい
  5. Processing.jsでフリックを認識したい
This entry was posted in 未分類 and tagged , , . Bookmark the permalink.