Toxiclibs particles and springs

Hi,

I wrote that with the help of a toxiclibs tutorial. I want all the particles moving upwards to make cylindrical mesh. But in my sketch, particles moves horizontally. What should I change to move particles and springs vertically?

Thank you so much

import toxi.geom.*;
import toxi.math.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;
import toxi.physics2d.constraints.*;
import toxi.physics3d.*;
import toxi.physics3d.constraints.*;
import toxi.processing.*;

import processing.opengl.*;

import peasy.*;

PeasyCam cam;

VerletPhysics3D physics;

VerletParticle3D particles;

Creator unit;

void setup() {
  size(800, 600,P3D);
  
  cam = new PeasyCam(this, 100);
  
  physics = new VerletPhysics3D();
  
  Vec3D cen = new Vec3D (0,0,0);
  unit = new Creator(cen);
  
  
 
 
    
   //for(int i = 0; i < 40; i++){
   //VerletParticle3D p = new VerletParticle3D(i *10,0,0); 
   //if(i ==0){
   //  p.lock();
   //}
   //physics.addParticle(p);
   //}
   //
   //
   //for (int i = 1; i < physics.particles.size(); i++){
   //  VerletParticle3D vp1 = (VerletParticle3D) physics.particles.get(i);
   //  VerletParticle3D vp2 = (VerletParticle3D) physics.particles.get(i-1);
   
   //VerletSpring3D sp = new VerletSpring3D(vp1, vp2, 10, 0.1);
   //physics.addSpring(sp);
   //}
   
}

void draw() {
  background(0);
  stroke(255);
  strokeWeight(1);
  noFill();
  box(600);
  
  unit.run();
  
  drawParticles();
  
  drawSprings();
 
  physics.update();
 
}

void drawSprings(){
   for(int i = 0; i < physics.springs.size(); i++){
    VerletSpring3D sp = (VerletSpring3D) physics.springs.get(i);
    
    stroke(255);
    strokeWeight(1);
    line(sp.a.x,sp.a.y, sp.a.z, sp.b.x,sp.b.y, sp.b.z);
  }
}

void drawParticles(){
  for(int i = 0; i < physics.particles.size(); i++){
    VerletParticle3D vp = (VerletParticle3D) physics.particles.get(i);
    
    strokeWeight(5);
    
    if(vp.isLocked()){
     stroke(255,0,0);
     }
    else{
      stroke(0,255,200);
    }
    point(vp.x, vp.y, vp.z);
  }
}

class Creator {
  
  Vec3D loc = new Vec3D();
  Vec3D cen;
  
  float angle = 0;
  float radius = 200;
  
  float z = 0;
  
  int count = 0;
  
  
 float speed = 0.07;
  
  Creator(Vec3D _cen){
    cen = _cen;
}

void run(){
 calcLoc();
 moveUpdate();
 dropParticles();
 dropSprings();
 display();

}

void dropSprings(){
  
  int dif = int(TWO_PI/speed);
  
  if(z > 0){
  if(count > 1){
  VerletParticle3D p0 = (VerletParticle3D) physics.particles.get(count-1);
  VerletParticle3D p1 = (VerletParticle3D) physics.particles.get(count-2);
  VerletParticle3D p2 = (VerletParticle3D) physics.particles.get(count-1-dif);
 
 
  VerletSpring3D sp = new VerletSpring3D(p0, p1, 10, 0.1);
  physics.addSpring(sp);
  
  VerletSpring3D sp2 = new VerletSpring3D(p0, p2, 10, 0.1);
  physics.addSpring(sp2);
  
  }
  }
  
}

void dropParticles(){
  
 VerletParticle3D p = new VerletParticle3D(loc.x,loc.y,loc.z);
 
 if(z == 0) {
   p.lock();
 }
   physics.addParticle(p);
   count ++;
 }

void moveUpdate(){
 
  angle += speed; 
 if(angle >= TWO_PI){
   angle = 0;
   z++;
 }
}

void calcLoc(){
 
  loc = new Vec3D(cos(angle)*radius, sin(angle)*radius, 0);
}

void display() {
  strokeWeight(8);
  stroke(0,0,255);
  
  point(loc.x,loc.y,loc.z); 
}
}
1 Like

Hi @orbicularis,

If I understand you correctly, you would like your particles to follow the same connecting pattern but along the Z axis (from top to down). The whole thing would look like the net of a basketbal hoop being knitted, right ?

If so you may want to add gravity to your sketch.
On top of your script just add:

import toxi.physics3d.behaviors.*;

And in setup(), under physics:

physics.addBehavior(new GravityBehavior3D(new Vec3D(0,0,0.5)));

1 Like

Thank you so much for your help @solub . Yes that exactly what I want to do. All particles move upward. Now, I want to add a sound file to effect particles and I want change radius. I don’t know, is it possible with minim library? I want to modify this cylindrical object with sound. Can you help me for that? Thank you so much again.

@orbicularis – In a nutshell: instead of “knitting” in real time (layer by layer) a circular mesh, you could build a cylindrical mesh in a single pass with a nested for loop. Each circle of this cylinder could correspond to a frequency of your sound file. You could then change the radius of these circles according to their corresponding frequency.

For that, I would suggest to:

  • read this Processing reference page to understand how to build a custom mesh
  • apply the trigonometry of your sketch accordingly
  • look in the forum for threads about the minim library (this one is helpful)

Here is a simple example sketch in Python mode to help you get started

add_library('peasycam')
add_library('minim')

R = 10 #radius of cylinder
facets = 20 #number of sides of the cylinder
step = 4 #spacing between each circle
freqs = 128 #number of frequencies to display (up to 512)

def setup():
    size(1000, 600, P3D)
    smooth(8)

    global render, song, fft
    cam = PeasyCam(this, 600)    
    minim = Minim(this)
    song = minim.loadFile("mysong.mp3") #load song
    fft = FFT(song.bufferSize(), song.sampleRate()) #analyse buffer size and sample rate

def draw():
    background('#DCDCDC')
    translate(0, 0, -freqs*step>>1)
    
    song.play() #play the song
    fft.forward(song.mix) #computes frequencies
    
    for i in xrange(freqs): 
        beginShape(QUAD_STRIP) #building a custom PShape
        h1 = map(fft.getBand(i), 0, 35, 1, 4) #get corresponding frequency and map its value
        h2 = map(fft.getBand(i+1), 0, 35, 1, 4)
        for n in xrange(i*facets, (i+1)*facets+1):
            x = R * cos(TWO_PI / facets * n) #trigonometry -> coordinates of the vertices
            y = R * sin(TWO_PI / facets * n) 
            vertex(x*h1, y*h1, i * step) #multiplying the X and Y coordinates by the corresponding frequency
            vertex(x*h2, y*h2, (i+1) * step)
        endShape()

If for some reason, you want to avoid both the PShape and the trigonometric part you can use the Hemesh library and import a cylindrical mesh directly into your sketch.

add_library('peasycam')
add_library('hemesh')
add_library('minim')

R = 10 #radius of cylinder
LEN = 600 #length of cylinder
facets = 20 #number of sides of the cylinder
freqs = 128 #number of frequencies to display (up to 512)

def setup():
    size(1000, 600, P3D)
    smooth(8)

    global render, song, fft
    cam = PeasyCam(this, 600)
    render = WB_Render(this)
    
    minim = Minim(this)
    song = minim.loadFile("mysong.mp3")
    fft = FFT(song.bufferSize(), song.sampleRate())

def draw():
    background('#DCDCDC')
    
    song.play() #play the song
    fft.forward(song.mix) #computes frequencies
    
    #import a cylindrical mesh
    cylinder = HE_Mesh(HEC_Cylinder().setRadius(R).setHeight(LEN).setFacets(facets).setSteps(freqs))

    #for each frequency (each circle of the cylinder correspond to a frequency)
    for i in xrange(freqs): 
        h = map(fft.getBand(i), 0, 35, 1, 4) #remap its value
        
        #for each vertex of each circle -> displace its X and Y coordinates according to frequency
        for n in xrange(i*facets, (i+1)*facets):
            p = cylinder.getVertex(n)
            p.set(WB_Point(p.xf() * h, p.yf() * h, p.zf()))
          
    #draw cylinder  
    render.drawFaces(cylinder)

3 Likes

@solub I am working on your code thank you so much. I added two links and those videos may help me to explain what I want to do. Of course, I don’t want to do exactly same thing but the idea is almost same. I as far as I know, they both used toxiclibs library.

I started to work on your code to adapt on Processing Java mode because I can’t play it on Python mode. I don’t know why. As far as I understand from the photo, it works for my project. If I can make a 3D mesh with sound (from music file or mic), that will be enough. And length of music will determine the length of the object. If the music is short, the object will be short. I think I can do this with your last codes without Toxiclibs.

I hope these links help you to explain my idea and thank you so much again for your consideration.

2 Likes

I’m afraid you’re confusing things.

  • In the first video, the artist is using an anemometer (wind sensor) similar to this one. It doesn’t record the sound coming out of a mouth but the speed of a breath. The harder people blow, the larger the radius of the vase. In this case Minim library won’t help you.

  • The length of the cylinder in the sketch above depends on the number of frequencies you chose to display (from 1 to 512), not on the duration of an audio file. In other words, what you see on the picture is the spectrum of an audio file at a given moment.

If you want your cylinder to grow as the music is playing while keeping a circular shape with smooth curves, you need to think differently. Maybe use the volume as an input instead of the frequencies, or the average of the spectrum…
Either way keep in mind that if one of your dimensions is time (Z axis) then the others (X and Y) should be indexed to an input that returns one single value at a time.

4 Likes