Create an animation in which characters emerge for a moment using molecular dynamics

Introduction

The molecular dynamics method is used to move particles to create an animation in which letters appear for a moment. The molecular dynamics method does not consider the interaction between particles.

Specifically, I will make such an animation.

Ballistic version

b.gif

Diffusion version

d.gif

The source is below.

https://github.com/kaityo256/stringtext

policy

I will draw letters for the time being. With Ruby, it's easier to use Cairo. The method is the same as "How to drop the supercomputer". If Cairo is not included, add it.

 sudo gem install cairo

After that, draw characters on a canvas of an appropriate size with an appropriate font. Is it like this for a "supercomputer"?

require 'rubygems'
require 'cairo'
format = Cairo::FORMAT_RGB24
width = 400
height = 100
surface = Cairo::ImageSurface.new(format, width, height)
context = Cairo::Context.new(surface)
context.set_source_rgb(0, 0, 0)
context.rectangle(0, 0, width, height)
context.fill
context.set_source_rgb(1, 1, 1)
context.select_font_face('Meiryo')
context.move_to(5,90)
context.font_size = 96 
context.show_text('Supercomputer')

Now that we've rasterized the characters, we'll take them out as particle coordinates. You can find out if there is a point by looking at whether the surface.data of the surface extracted by surface = Cairo :: ImageSurface.new is 0.

Note that surface.data is String, so you need to read ʻord` to compare it with an integer. It is like this.

  height.times do |y|
    width.times do |x|
      i = x + y * width
      next if surface.data[i*4].ord ==0
      #Additional processing of particles
    end
  end

Once you have extracted the coordinates of the particles with this, you can do whatever you want with the rest.

Molecular dynamics simulation

Ballistic version

First, let's simply make all the particles move in a constant velocity linear motion. I want to loop when I make an animated GIF, so I want you to come back to the original place after an appropriate step.

Consider an image with a height of 100 and a width of 400 pixels. The animation is 200 frames. Considering the periodic boundary conditions, in 200 steps, the x-coordinate is 400 and the y-coordinate is an integral multiple of 100, and the original location is restored.

So, let's randomly select the velocity vx in the x direction from 4 types: -4, -2, 2, 4. In addition, the y coordinate will be randomly selected from eight types: -2, -1.5, -1.0, -0.5, 0.5, 1.0, 1.5, 2.0. When both are multiplied by 200, the x-coordinate becomes an integral multiple of 400 and the y-coordinate becomes an integer multiple of 100, so the original location is restored. Also, let's change the color randomly. Let's create a Particle structure and create an array of it.

Particle = Struct.new(:x, :y, :vx, :vy, :r, :g, :b)
  height.times do |y|
    width.times do |x|
      i = x + y * width
      next if surface.data[i*4].ord ==0

      vx = [-1, 1, -2, 2].sample
      vy = [-1, 1, -0.5, 0.5, -0.25, 0.25, 0.75, -0.75].sample
      r = rand
      g = rand
      b = rand
      atoms.push Particle.new(x, y, vx, vy, r, g, b)
    end
  end

At first, the letters "supercomputer" are displayed.

img107.png

This will gradually collapse.

img109.png

img111.png

After that, it's boring if you can see the characters from the beginning, so if you create a file with a slight index shift, you're done.

iter = 200
iter.times do |i|
  index = (i + 108) % iter
  filename = format("img%03d.png ", index)
  puts filename
  step(atoms)
  save_png(filename, atoms)
end

By the way, this method is easy, but since all the particles have a constant velocity linear motion and the variation of the velocity vector is small, strange patterns will appear several times. For example, depending on the timing, you may find that "Oh, the characters are hidden" like this.

img006.png

To prevent this, consider a different method.

Diffusion version

I made a constant velocity linear motion earlier, but next let's make a random walk. However, we want to loop, so let's create an array where the sum of the elements is 0 and make it the velocity of each step.

Anything is fine, but let's simply make an array that is half -2 and half 2 and shuffle it.

steps = 200
$a = Array.new(steps) do |i|
  if i < steps/2
    2
  else
    -2
  end
end

Shuffle this array into the vx and vy arrays of each particle and pass it.

  height.times do |y|
    width.times do |x|
      i = x + y * width
      next if surface.data[i*4].ord ==0

      vx = $a.shuffle.dup
      vy = $a.shuffle.dup
      r = rand
      g = rand
      b = rand
      atoms.push Particle.new(x, y, vx, vy, r, g, b)
    end
  end

All you have to do is add vx [i], vy [i] to x, y every step. The sum of vx and vy is zero, so it will always come back.

At first, the word "supercomputer" is displayed, and it is the same that it gradually collapses.

img107.png

This will gradually collapse.

img109.png

img111.png

The way it collapses is slower than constant velocity linear motion. Also, since it spreads by spreading, even in the most spread state, the blurred characters are still visible.

img006.png

Summary

I tried to make an animated GIF in which characters appear for a moment by the molecular dynamics method. It is a secret why I decided to make something like this.

If you devise it, characters will appear one after another and become a message, so please play around with it.

Recommended Posts

Create an animation in which characters emerge for a moment using molecular dynamics
Create a tool for name identification in Salesforce
Create an environment for Tomcat and Postgres on a Chromebook without using developer mode
I tried using an extended for statement in Java
A memorandum for creating an extended logger using org.slf4j.Logger
[Ruby] Searching for elements in an array using binary search
Create a base for your batch processing project in Eclipse.
Procedure for publishing an application using AWS (4) Creating a database
Create QR code for Google Authenticator using ZXing in Java