xxxxxxxxxx
106
//noprotect
var circles;
var ray;
function setup() {
createCanvas(480, 320);
noFill();
circles = [];
for (var i = 0; i < 10; i++) {
var radius = random(8, 32);
var x = random(radius, width - radius);
var y = random(radius, height - radius);
var c = new Circle(x, y, radius);
//var rv = p5.Vector.random2D();
//c.addForce(rv.x, rv.y);
c.addForce(random(), random());
circles.push(c);
}
console.log(circles.length);
ray = new Ray(width / 2, height / 2, 0);
}
function draw() {
background(220);
//translate(width / 2, height / 2);
stroke(255, 255, 255, 150);
for(var i = 0; i < circles.length; i++) {
var circle = circles[i];
circle.update();
circle.draw();
}
scene(ray);
ray.update();
}
function scene() {
var closestRadius = 10000000;
var closestCircle = null;
var current = ray.pos.copy();
var numSteps = 100;
for (var i = 0; i < numSteps; i++) {
for (var j = 0; j < circles.length; j++) {
var circle = circles[j];
var d = sdCircle(current, circle.pos, circle.radius);
if (d < closestRadius) {
closestRadius = d;
closestCircle = circle;
}
}
if(closestRadius < 1 || current.x < 0 || current.x > width || current.y < 0 || current.y > height) {
break;
}
stroke(255, 0, 255);
ellipse(current.x, current.y, closestRadius * 2);
var v = p5.Vector.fromAngle(ray.angle);
v.setMag(closestRadius);
current.add(v);
}
}
function sdCircle(rayOrigin, circleOrigin, circleRadius) {
return p5.Vector.dist(rayOrigin, circleOrigin) - circleRadius;
}
function Ray(x, y, angle) {
this.pos = createVector(x, y);
this.angle = angle;
}
Ray.prototype.update = function() {
this.angle += radians(.5);
}
function Circle(x, y, radius) {
this.pos = createVector(x, y);
this.vel = createVector();
this.acc = createVector();
this.radius = radius;
}
Circle.prototype.addForce = function(x, y) {
this.acc.x += x;
this.acc.y += y;
}
Circle.prototype.update = function() {
this.vel.add(this.acc);
this.acc.mult(0);
this.pos.add(this.vel);
if(this.pos.x < this.radius || this.pos.x > width - this.radius) {
this.vel.x = -this.vel.x;
}
if(this.pos.y < this.radius || this.pos.y > height - this.radius) {
this.vel.y = -this.vel.y;
}
}
Circle.prototype.draw = function() {
push();
translate(this.pos.x, this.pos.y);
ellipse(0, 0, this.radius * 2);
pop();
}