Skip to content

Commit 2498c2b

Browse files
committed
New contributed example, from OpenProcessing.
1 parent 7303b75 commit 2498c2b

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

contributed/circles.rb

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env jruby
2+
# coding: utf-8
3+
require 'propane'
4+
5+
## Circles by Bárbara Almeida
6+
## A fork of Circle through 3 points by Bárbara Almeida.
7+
## Draw circles from 3 points moving on smooth random trajectories.
8+
## https://www.openprocessing.org/sketch/211167
9+
10+
## Propane version by Jérémy Laviole - @poqudrof
11+
12+
class Circles < Propane::App
13+
14+
def settings
15+
size(800, 600, P3D)
16+
end
17+
18+
## To be overriden by the Presentation Code.
19+
def setup
20+
colorMode(HSB, 360, 100, 100, 100);
21+
@c = random(360);
22+
23+
@points = []
24+
3.times { @points << Points.new(random(width),random(height)) }
25+
26+
background 0
27+
@setup_done = true
28+
end
29+
30+
def draw
31+
fill(0, 0, 0);
32+
noStroke
33+
34+
if (frameCount % 8000 == 0)
35+
rect(0, 0, width, height);
36+
end
37+
38+
@points.each do |point|
39+
##change direction sometimes
40+
point.setDir random(-Propane::PConstants::PI, Propane::PConstants::PI) if (random(1) > 0.96)
41+
point.update
42+
point.checkEdges
43+
end
44+
45+
## set the style of the circle
46+
@dc = Propane::PApplet::map(millis(), 0, 150000, 0, 360) ## slowly changes hue
47+
stroke((@c + @dc) % 360, 50, 100, 5)
48+
noFill
49+
50+
## verifies if there is a circle and draw it
51+
52+
det = (@points[0].p.x * @points[1].p.y) + (@points[1].p.x * @points[2].p.y) + (@points[2].p.x * @points[0].p.y);
53+
54+
det -= (@points[0].p.y * @points[1].p.x) + (@points[1].p.y * @points[2].p.x) + (@points[2].p.y * @points[0].p.x);
55+
56+
57+
draw_circle @points if Propane::PApplet::abs(det) > 50
58+
end
59+
60+
61+
def draw_circle(pts)
62+
63+
## find the midpoints of 2 sides
64+
mp = []
65+
mp[0] = midpoint(pts[0].p, pts[1].p);
66+
mp[1] = midpoint(pts[1].p, pts[2].p);
67+
68+
center_point = center(mp); ## find the center of the circle
69+
r = dist(center_point.x, center_point.y, pts[2].p.x, pts[2].p.y); ##calculate the radius
70+
71+
ellipse(center_point.x, center_point.y, 2*r, 2*r); ## if not collinear display circle
72+
end
73+
74+
def midpoint(a, b)
75+
d = dist(a.x, a.y, b.x, b.y); ## distance AB
76+
theta = atan2(b.y - a.y, b.x - a.x); ## inclination of AB
77+
p = Propane::PVector.new(a.x + d/2* Propane::PApplet::cos(theta),
78+
a.y + d/2* Propane::PApplet::sin(theta), # midpoint
79+
theta - Propane::PConstants::HALF_PI); #inclination of the bissecteur
80+
return p
81+
end
82+
83+
def center(mid_point)
84+
eq = []
85+
86+
## equation of the first bissector (ax - y = -b)
87+
mid_point.each do |mp|
88+
a = tan mp.z
89+
eq << Propane::PVector.new(a,
90+
-1,
91+
-1*(mp.y - mp.x*a))
92+
end
93+
94+
## calculate x and y coordinates of the center of the circle
95+
ox = (eq[1].y * eq[0].z - eq[0].y * eq[1].z) /
96+
(eq[0].x * eq[1].y - eq[1].x * eq[0].y);
97+
oy = (eq[0].x * eq[1].z - eq[1].x * eq[0].z) /
98+
(eq[0].x * eq[1].y - eq[1].x * eq[0].y);
99+
return Propane::PVector.new(ox,oy);
100+
end
101+
end
102+
103+
104+
class Points
105+
106+
include Propane::Proxy
107+
attr_accessor :p, :velocity, :acceleration
108+
109+
def initialize(x, y)
110+
@p = Propane::PVector.new(x, y, 1)
111+
@velocity = Propane::PVector.new(0, 0, 0);
112+
@acceleration = Propane::PVector.new($app.random(1), $app.random(1), 0)
113+
end
114+
115+
# change direction
116+
def setDir(angle)
117+
## direction of the acceleration is defined by the new angle
118+
acceleration.set(Propane::PApplet::cos(angle), Propane::PApplet::sin(angle), 0);
119+
120+
## magnitude of the acceleration is proportional to the angle between acceleration and velocity
121+
acceleration.normalize
122+
dif = Propane::PVector::angleBetween(acceleration, velocity)
123+
dif = Propane::PApplet::map(dif, 0, Propane::PConstants::PI, 0.1, 0.001)
124+
acceleration.mult(dif);
125+
end
126+
127+
## update position
128+
def update
129+
velocity.add(acceleration);
130+
velocity.limit(1.5);
131+
p.add(velocity);
132+
end
133+
134+
def checkEdges
135+
p.x = constrain(p.x, 0, $app.width)
136+
p.y = constrain(p.y, 0, $app.height)
137+
end
138+
end
139+
140+
Circles.new

0 commit comments

Comments
 (0)