Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

円の交点

/**
 * intersection points of circles
 * 
 * @author aadebdeb
 * @date 2017/03/04
 */

var circles;

function setup() {
  createCanvas(windowWidth, windowHeight);
  circles = [];
  for (var i = 0; i < 30; i++) {
    circles.push(new Circle());
  }
}

function draw() {
  background(255);
  var interPoints = [];
  noFill();
  stroke(210);
  for (var i = 0; i < circles.length; i++) {
    var c1 = circles[i];
    c1.render();
    for (var j = i + 1; j < circles.length; j++) {
      var c2 = circles[j];
      Array.prototype.push.apply(interPoints, c1.getIntersectionPoints(c2));
    }
  }
  

  for (var i = 0; i < interPoints.length; i++) {
    var p = interPoints[i];
    noStroke();
    fill(167, 117, 160);
    ellipse(p.x, p.y, 4, 4);
  }
  
  for (var i = 0; i < circles.length; i++) {
    var circle = circles[i];
    circle.update();
  }
}

function Circle() {
  this.radius = random(20, 150);
  this.loc = createVector(random(this.radius, width - this.radius), random(this.radius, height - this.radius));
  var velSize = random(0.2, 2);
  var velAng = random(TWO_PI);
  this.vel = createVector(velSize * cos(velAng), velSize * sin(velAng));
}

Circle.prototype = {
  render: function() {
    ellipse(this.loc.x, this.loc.y, this.radius * 2, this. radius * 2);
  },
  
  update: function() {
    this.loc.add(this.vel);
    if (this.loc.x < this.radius) {
      this.vel.x *= -1;
      this.loc.x += this.vel.x;
    }
    if (this.loc.x > width - this.radius) {
      this.vel.x *= -1;
      this.loc.x += this.vel.x;
    }
    if (this.loc.y < this.radius) {
      this.vel.y *= -1;
      this.loc.y += this.vel.y;
    }
    if (this.loc.y > height - this.radius) {
      this.vel.y *= -1;
      this.loc.y += this.vel.y;
    }
  },
  
  getIntersectionPoints: function(c) {
    var relLoc = p5.Vector.sub(c.loc, this.loc);
    var a = (relLoc.magSq() + sq(this.radius) - sq(c.radius)) / 2.0;
    var v2sq = relLoc.magSq() * sq(this.radius) - sq(a);
    if (v2sq > 0) {
      var v1 = relLoc.magSq();
      var v2 = sqrt(v2sq);
      var p1 = createVector(this.loc.x + (a * relLoc.x + relLoc.y * v2) / v1, this.loc.y + (a * relLoc.y - relLoc.x * v2) / v1);
      var p2 = createVector(this.loc.x + (a * relLoc.x - relLoc.y * v2) / v1, this.loc.y + (a * relLoc.y + relLoc.x * v2) / v1);
      return [p1, p2];
    } else {
      return [];
    }
  }
}
f:id:aa_debdeb:20170302224728j:plain