-
Notifications
You must be signed in to change notification settings - Fork 0
Animating Sierpinski triangle
kkrmno edited this page Mar 19, 2020
·
1 revision
require "imgrb"
width = 400
height = 400
#Grayscale image of size 400x400 filled with black
image_0 = Imgrb::Image.new(width, height, [0, 255])
#Iterated Sierpinski triangle generates the sequence
#used for the animation.
rng = Random.new(0) #Seeded for reproducibility
frames = 24*8 #Number of frames of animation
points_per_frame = 600 #Number of points to generate per frame
#Vertices of the triangle
p0 = [width/2, 0]
p1 = [width-1, height-1]
p2 = [0, height-1]
#Starting point
new_p = [(p0[0]+p1[0]+p2[0])/3, (p0[1]+p1[1]+p2[1])/3]
#Generating frames
frames.times do
#Create the next frame in the sequence
image_i = Imgrb::Image.new(width, height, [0, 0])
points_per_frame.times do
move_towards = p0
vertex_idx = rng.rand(3)
if vertex_idx == 1
move_towards = p1
elsif vertex_idx == 2
move_towards = p2
end
new_p[0] = new_p[0]/2 + move_towards[0]/2
new_p[1] = new_p[1]/2 + move_towards[1]/2
image_i.set_pixel(new_p[0], new_p[1], [255, 10])
end
#Add new frame data with 0 offset
x_offset = 0
y_offset = 0
#Each frame should display for 1/24 of a second
delay_numerator = 1
delay_denominator = 24
#In this case we can leave the pixels from the last frame and
#simply blend in the pixels that have been added using alpha
#compositing. I.e., we do nothing for the dispose step, and
#use the :over blend option to overlay the pixel data of the
#next frame. This way we end up with a much smaller file, since
#the pixel data of each frame consists of mostly 0s.
dispose_op = :none
blend_op = :over
image_0.push_frame(image_i, x_offset, y_offset,
delay_numerator, delay_denominator,
dispose_op, blend_op)
end
#Add a comment describing the image.
image_0.add_text("Comment", "This is an animated png illustrating an iterated approach to constructing the Sierpinski triangle.")
image_0.save("animated_sierpinski.png")