Skip to content

Instantly share code, notes, and snippets.

@ricardojmendez
Last active December 17, 2015 15:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricardojmendez/2047eb3187992157ea4c to your computer and use it in GitHub Desktop.
Save ricardojmendez/2047eb3187992157ea4c to your computer and use it in GitHub Desktop.
P5.js sketch showing the intersection of wandering circles
class Circle
constructor: (@x, @y, @radius, @x_move, @y_move) ->
class Overlap
constructor: (@x = 0, @y = 0, @amount = 0) ->
mysketch = (sketch) ->
circles = []
random_circle = (x = sketch.random(sketch.width), y = sketch.random(sketch.height)) ->
new Circle(x, y, sketch.random(100) + 10, sketch.random(4) - 2, sketch.random(4) - 2)
flatten = (arr) ->
arr.reduce ((xs, el) ->
if Array.isArray el
xs.concat flatten el
else
xs.concat [el]), []
circle_overlap = (circle1, circle2) ->
are_same = circle1 == circle2
if are_same
new Overlap()
else
distance = sketch.dist(circle1.x, circle1.y, circle2.x, circle2.y) - circle1.radius - circle2.radius
new Overlap((circle1.x + circle2.x) / 2, (circle1.y + circle2.y) / 2, distance)
all_overlaps = (circle, all_circles) ->
(circle_overlap(circle, other) for other in all_circles)
calculate_intersections = (circle_list) ->
total = circle_list.length
l = []
overlaps = while total -= 1
l = l.concat all_overlaps(circle_list[total - 1], circle_list[0..total-2])
total
l
### Alternative version, similar actual performance
overlaps = while total -= 1
all_overlaps(circle_list[total - 1], circle_list[0..total-2])
flatten(overlaps)
###
update_circle_position = (circle) ->
new_x = circle.x + circle.x_move
new_y = circle.y + circle.y_move
new_x = -circle.radius if new_x > sketch.width + circle.radius
new_x = sketch.width + circle.radius if new_x < -circle.radius
new_y = -circle.radius if new_y > sketch.height + circle.radius
new_y = sketch.height + circle.radius if new_y < -circle.radius
circle.x = new_x
circle.y = new_y
circle
draw_intersection = (intersection) ->
if intersection.amount < 0
sketch.stroke(0, 10)
sketch.noFill()
sketch.ellipse(intersection.x, intersection.y, -intersection.amount, -intersection.amount)
draw_intersections = (intersections) ->
draw_intersection i for i in intersections
sketch.setup = ->
sketch.createCanvas 512, 384
circles = (random_circle() for num in [0..100])
sketch.background 240
sketch.frameRate 60
sketch.smooth
sketch.strokeWeight 1
sketch.fill 150, 50
sketch.draw = ->
sketch.fill 240, 2
sketch.noStroke()
sketch.rect 0, 0, sketch.width, sketch.height
update_circle_position c for c in circles
draw_intersections(calculate_intersections(circles))
myp5 = new p5(mysketch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment