Skip to content

Commit 398f311

Browse files
committed
mainly new sketches
1 parent 763704f commit 398f311

File tree

5 files changed

+289
-0
lines changed

5 files changed

+289
-0
lines changed

contributed/circle_growth.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
require 'toxiclibs'
2+
3+
W = 1000
4+
H = 600
5+
6+
attr_reader :axiom, :z, :physics
7+
8+
def settings
9+
size(W, H)
10+
end
11+
12+
def setup
13+
sketch_title 'Wolfram Circle Growth'
14+
@axiom = [[0, 1], [0, 2], [1, 2]]
15+
@z = axiom.flatten.max + 1
16+
@physics = Physics::VerletPhysics2D.new
17+
physics.set_drag(0.2)
18+
# Get id of each node
19+
uniques = axiom.flatten.uniq
20+
uniques.each do
21+
p = Physics::VerletParticle2D.new(TVec2D.randomVector.add(TVec2D.new(W >> 1, H >> 1)))
22+
physics.addParticle(p)
23+
physics.addBehavior(Physics::AttractionBehavior2D.new(p, 10, -0.5))
24+
end
25+
axiom.each do |node|
26+
p1 = physics.particles.get(node[0])
27+
p2 = physics.particles.get(node[1])
28+
s = Physics::VerletSpring2D.new(p1, p2, 4, 0.5)
29+
physics.add_spring(s)
30+
end
31+
end
32+
33+
def draw
34+
background(color('#FFFFFF'))
35+
physics.update
36+
idx = rand(z)
37+
x, y = *axiom[idx]
38+
axiom.delete_at(idx)
39+
axiom << [y, z]
40+
axiom << [z, x]
41+
# Manage physics accordingly
42+
px = physics.particles.get(x) # coordinate of node x
43+
py = physics.particles.get(y) # coordinate of node y
44+
pz = Physics::VerletParticle2D.new(px.add(py).scale(0.5)) # create a new particle in between
45+
s = physics.get_spring(px, py) # find spring between the deleted edge
46+
physics.remove_spring(s) # remove that spring
47+
physics.add_particle(pz) # add particle
48+
physics.add_behavior(Physics::AttractionBehavior2D.new(pz, 10, -0.5)) # attach a repulsion behavior to it
49+
s1 = Physics::VerletSpring2D.new(py, pz, 4, 0.5) # create spring between 1st new edge
50+
s2 = Physics::VerletSpring2D.new(pz, px, 4, 0.5) # create spring between 2nd new edge
51+
physics.add_spring(s1) # add them to physics
52+
physics.add_spring(s2)
53+
@z += 1 # increment 'z'
54+
# Draw springs
55+
physics.springs.each do |spring|
56+
line(spring.a.x, spring.a.y, spring.b.x, spring.b.y)
57+
end
58+
end

contributed/sierpinski_carpet.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
attr_reader :limit
2+
3+
def setup
4+
sketch_title 'Sierpinski Carpet'
5+
n = 4
6+
@limit = width / 3**n
7+
fill 0
8+
background 255
9+
no_stroke
10+
holes(0, 0, width / 3)
11+
end
12+
13+
def in_carpet?(xpos, ypos)
14+
!(xpos == 1 && ypos == 1)
15+
end
16+
17+
def holes(xpos, ypos, dim)
18+
return if dim < limit
19+
20+
grid(3, 3) do |row, col|
21+
offset_x = xpos + row * dim
22+
offset_y = ypos + col * dim
23+
rect(offset_x, offset_y, dim, dim) unless in_carpet?(row, col)
24+
holes(offset_x, offset_y, dim / 3)
25+
end
26+
end
27+
28+
def settings
29+
size(729, 729)
30+
end

contributed/truchet_tiling.rb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# After a sketch by Jim Bumgardner
2+
# http://joyofprocessing.com/blog/tag/tilings/page/2/
3+
# Here we create an array of offscreen images
4+
# Create a grid using the ruby-processing :grid method
5+
# Then randomly render tile images from the array
6+
DIM = 24
7+
TYPE = %i[corner alt_corner alt_oval oval alt_line line].freeze
8+
attr_reader :tiles, :images
9+
10+
def make_image(dim, alternate = :line)
11+
create_graphics(dim, dim).tap do |g|
12+
g.smooth(4)
13+
g.begin_draw
14+
g.background(255)
15+
g.stroke(0)
16+
g.stroke_weight(4)
17+
g.no_fill
18+
g.ellipse_mode(RADIUS)
19+
case alternate
20+
when :corner
21+
g.line(dim / 2, 0, dim / 2, dim / 2)
22+
g.line(0, dim / 2, dim / 2, dim / 2)
23+
g.line(dim / 2, dim, dim, dim / 2)
24+
when :alt_corner
25+
g.line(dim / 2, 0, dim / 2, dim / 2)
26+
g.line(dim / 2, dim / 2, dim, dim / 2)
27+
g.line(0, dim / 2, dim / 2, dim)
28+
when :line
29+
g.line(dim / 2, 0, dim, dim / 2)
30+
g.line(0, dim / 2, dim / 2, dim)
31+
when :alt_line
32+
g.line(0, dim / 2, dim / 2, 0)
33+
g.line(dim / 2, dim, dim, dim / 2)
34+
when :alt_oval
35+
g.ellipse(0, dim, dim / 2, dim / 2)
36+
g.ellipse(dim, 0, dim / 2, dim / 2)
37+
when :oval
38+
g.ellipse(0, 0, dim / 2, dim / 2)
39+
g.ellipse(dim, dim, dim / 2, dim / 2)
40+
end
41+
g.end_draw
42+
end
43+
end
44+
45+
def create_image_array(except = [])
46+
@images = TYPE.reject do |type|
47+
except.include?(type)
48+
end.map { |type| make_image(DIM, type) }
49+
@tiles = []
50+
end
51+
52+
def create_grid
53+
@tiles = []
54+
grid(width, height, DIM, DIM) do |posx, posy|
55+
tiles << Tile.new(Vec2D.new(posx, posy))
56+
end
57+
end
58+
59+
def setup
60+
sketch_title 'Mixed Truchet Tiling'
61+
create_image_array
62+
create_grid
63+
no_loop
64+
end
65+
66+
def key_pressed
67+
case key
68+
when 'o', 'O'
69+
create_image_array(%i[alt_line line corner alt_corner])
70+
when 'c', 'C'
71+
create_image_array(%i[alt_line line oval alt_oval])
72+
when 'l', 'L'
73+
create_image_array(%i[alt_oval oval])
74+
end
75+
create_grid
76+
redraw
77+
end
78+
79+
def draw
80+
background(255)
81+
tiles.each(&:render)
82+
end
83+
84+
def settings
85+
size(576, 576)
86+
smooth(4)
87+
end
88+
89+
# encapsulate Tile as a class
90+
class Tile
91+
include Processing::Proxy
92+
attr_reader :vec, :img
93+
94+
def initialize(vec)
95+
@vec = vec
96+
@img = images.sample
97+
end
98+
99+
def render
100+
image(img, vec.x, vec.y, img.width, img.height)
101+
end
102+
end
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// This implementation is based on GLSL code by ArKano22:
2+
// http://www.gamedev.net/topic/590070-glsl-droste/
3+
uniform float time;
4+
uniform sampler2D texture; // iChannel0 in Shadertoy
5+
uniform vec2 resolution; // iResolution in Shadertoy
6+
uniform int mode;
7+
8+
const float TWO_PI = 3.141592*2.0;
9+
//ADJUSTABLE PARAMETERS:
10+
const float Branches = 1.0;
11+
const float scale = 0.4;
12+
const float off = 0.6;
13+
//Complex Math:
14+
vec2 complexExp(in vec2 z){
15+
return vec2(exp(z.x)*cos(z.y),exp(z.x)*sin(z.y));
16+
}
17+
vec2 complexLog(in vec2 z){
18+
return vec2(log(length(z)), atan(z.y, z.x));
19+
}
20+
vec2 complexMult(in vec2 a,in vec2 b){
21+
return vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
22+
}
23+
float complexMag(in vec2 z){
24+
return length(z);
25+
}
26+
vec2 complexReciprocal(in vec2 a){ return vec2(a.x, -a.y) / dot(a, a); }
27+
vec2 complexDiv(in vec2 a,in vec2 b){
28+
return complexMult(a, complexReciprocal(b));
29+
}
30+
vec2 complexPower(in vec2 a, in vec2 b){
31+
return complexExp( complexMult(b,complexLog(a)) );
32+
}
33+
//Misc Functions:
34+
float nearestPower(in float a, in float base){
35+
return pow(base, ceil( log(abs(a))/log(base) )-1.0 );
36+
}
37+
float map(float value, float istart, float istop, float ostart, float ostop) {
38+
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
39+
}
40+
41+
void main( void ){
42+
43+
//SHIFT AND SCALE COORDINATES
44+
vec2 uv=gl_FragCoord.xy/resolution.xy - off;
45+
46+
//ESCHER GRID TRANSFORM:
47+
float factor = pow(1.0/scale,Branches);
48+
uv= complexPower(uv, complexDiv(vec2( log(factor) ,TWO_PI), vec2(0.0,TWO_PI) ) );
49+
50+
//RECTANGULAR DROSTE EFFECT:
51+
float FT = fract(time);
52+
FT = log(FT+1.)/log(2.);
53+
uv *= 1.0+FT*(scale-1.0);
54+
55+
float npower = max(nearestPower(uv.x,scale),nearestPower(uv.y,scale));
56+
// uv.x = map(uv.x,-npower,npower,-1.0,1.0);
57+
// uv.y = map(uv.y,-npower,npower,-1.0,1.0);
58+
uv = normalize(uv) * 2;
59+
60+
//UNDO SHIFT AND SCALE:
61+
gl_FragColor = texture(texture,uv*off+vec2(off));
62+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
load_library :video, :video_event
2+
include_package 'processing.video'
3+
attr_reader :cam, :my_filter, :origin
4+
5+
def settings
6+
size(1280, 960, P2D)
7+
end
8+
9+
def setup
10+
sketch_title 'Droste'
11+
@origin = Time.now
12+
@my_filter = load_shader(data_path('droste.glsl'))
13+
my_filter.set('resolution', width.to_f, height.to_f)
14+
start_capture
15+
end
16+
17+
def time
18+
(Time.now - origin)
19+
end
20+
21+
def start_capture
22+
@cam = Java::ProcessingVideo::Capture.new(self, "UVC Camera (046d:0825)")
23+
cam.start
24+
end
25+
26+
# using snake case to match java reflect method
27+
def captureEvent(cam)
28+
cam.read
29+
end
30+
31+
def draw
32+
background 0
33+
image(cam, 0, 0, width, height)
34+
my_filter.set('time', time)
35+
return if mouse_pressed?
36+
filter(my_filter)
37+
end

0 commit comments

Comments
 (0)