メニュー 閉じる

021. p5.jsで自律エージェントの動きを3Dで描いてみる

007を3D版にしてみました。でも、ちょっとどこかに不具合がある。

http://www.velvet-number.com/p5_test/test016/

var debug;

var flowfield;

var vehicles;

function setup () {

	pixelDensity (displayDensity ());
	createCanvas (windowWidth, windowHeight, WEBGL);
	background (0);
	colorMode (HSB, 100);

	flowfield = new FlowField (40);
	flowfield.init ();
	vehicles = [];

	translate (width / 2, height / 2, 0.0);

	for (var i = 0; i < 3000; i++) {
		vehicles.push (new Vehicle (new p5.Vector (random (-width / 2, width / 2), random (-height / 2, height / 2)), random (2, 5), random (0.1, 0.5)));
	}

	debug = false;

}

function draw () {

	background (0);

	camera (0, 0, -400,
			0, 0, 0,
			0.0, 1.0, 0.0);

	rotateX (map (mouseY, 0, width, -PI, PI));
	rotateZ (map (mouseX, 0, width, -PI, PI));

	if (debug) {
		flowfield.render ();
	}

	for (var i = 0; i < vehicles.length; i++) {
		vehicles[i].follow (flowfield);
		vehicles[i].run ();
	}

}

function keyPressed () {

	if (key == ' ') {
		debug = !debug;
	}

}

function mousePressed () {

	flowfield.init ();
	
}
function Vehicle (l, ms, mf) {

	var location = l.copy ();
	var velocity = new p5.Vector (0, 0);
	var acceleration = new p5.Vector (0, 0);

	var r = 2.0;
	var maxforce = mf;
	var maxspeed = ms;
	var theta;

	this.run = function () {
		this.update ();
		this.border ()
		this.render ();
	}

	this.update = function () {

		velocity.add (acceleration);
		velocity.limit (maxspeed);
		location.add (velocity);
		acceleration.mult (0);

	}

	this.border = function () {

		if (location.x < -width / 2 -r) location.x = width / 2 + r;
		if (location.y < -height / 2 -r) location.y = height / 2 + r;
		if (location.x > width / 2 + r) location.x = -width / 2 - r;
		if (location.y > height / 2 + r) location.y = -height / 2 - r;

	}

	this.render = function () {

		theta = velocity.heading () + PI / 2;

		fill (map (theta, -1.0, 5.0, 0, 100), 100, 100);
		noStroke ()
		push ();
		translate (location.x, location.y, 0.0);
		rotate (theta);
		beginShape ();
		vertex (0, -r * 2, 0);
		vertex (-r, r * 2, 0);
		vertex (r, r * 2, 0);
		endShape (CLOSE);
		pop ();

	}

	this.applyForce = function (force) {

		acceleration.add (force);

	}

	this.follow = function (flow) {

		var desired = flow.lookup (location);
		desired.mult (maxspeed);

		var steer = p5.Vector.sub (desired, velocity);
		steer.limit (maxforce);

		this.applyForce (steer);

	}

}
function FlowField (r) {

	var field = [];

	var resolution = r;
	var cols = width / resolution;
	var rows = height / resolution;

	this.init = function () {

		noiseSeed (int (random (10000)));

		var xoff = 0;
		for (var i = 0; i < cols; i++) {
			var yoff = 0;
			field[i] = [];
			for (var j = 0; j < rows; j++) {
				var theta = map (noise (xoff, yoff), 0, 1, -TWO_PI, TWO_PI);
				field[i][j] = new p5.Vector (cos (theta), sin (theta));
				yoff += 0.1;
			}
			xoff += 0.1;
		}

	}

	this.render = function () {

		for (var i = 0; i < cols; i++) {
			for (var j = 0; j < rows; j++) {
				this.draw_vector (field[i][j], i * resolution - (width / 2), j * resolution - (height / 2), resolution);
			}
		}

	}

	this.draw_vector = function (v, x, y, sc) {

		stroke (100, 50);

		var len = v.mag () * sc;

		stroke (50);
		strokeWeight (0.1);

		push ();
		translate (x, y);
		rotate (v.heading ());
		line (0, 0, len, 0);
		pop ();

	}

	this.lookup = function (look_v) {

		var col = int (constrain (look_v.x / resolution, 0, cols - 1));
		var row = int (constrain (look_v.y / resolution, 0, rows - 1));
		return (field[col][row].copy ());

	}

}

 

 

Posted in p5.js , processing