Tutorials | (back to the list of tutorials) |
The code below shows a method to convert line geometries in a tensile line network by the method ITensileNet.create(lines, fixedPoints). In the code, all the lines and all the points in the file are fed into the method and lines become tension lines creating particles at every end points and points become fixing points if they are on the end points of the lines.
The input Rhino file used in the example is this one below.
import igeo.*; import processing.opengl.*; size(480, 360, IG.GL); IG.open("lines1.3dm"); ITensileNet.create(IG.curves(), IG.points());
This image is before applying tension.
The below is after applying tension.
import igeo.*; import processing.opengl.*; void setup(){ size(480, 360, IG.GL); IG.open("lines1.3dm"); ITensileNet.create(IG.curves(), IG.points()); new Gravity(IG.v(0.1, 0, 0)); //gravity toward x direction new Attractor(IG.v(7, 7, 7)).clr(1.0, 0, 0); } class Gravity extends IAgent{ IVec gravity; Gravity(IVec g){ gravity=g; } void interact(IDynamics agent){ if(agent instanceof IParticle){ IParticle particle = (IParticle)agent; particle.push(gravity); } } } class Attractor extends IPointAgent{ double attraction = -0.05; double threshold = 9; Attractor(IVec p){ super(p); } void interact(IDynamics agent){ if(agent instanceof IParticle){ IParticle particle = (IParticle)agent; double dist = particle.pos().dist(pos()); if(dist < threshold){ IVec frc = pos.dif(particle.pos()); frc.len( (threshold - dist) * attraction ); particle.push(frc); } } } }
import igeo.*; import processing.opengl.*; void setup(){ size(480, 360, IG.GL); IG.open("lines1.3dm"); ITensileNet.tension(50); //strength of tension line ITensileNet.friction(0.05); //friction of particles ITensileNet.tolerance(0.01); //tolerance to judge if 2 end points are connected ITensileNet.fixOpenEnd(false); //fixing open end line or not ITensileNet.pointColor(0,0,1.0); //color of particle points ITensileNet.pointLayer("tension node"); //layer to put particle points ITensileNet.fixedPointColor(0,1.0,1.0); //color of fixed particle points ITensileNet.fixedPointLayer("fixed node"); //layer to put fixed particle points ITensileNet.create(IG.curves(), IG.points()); }
The input Rhino file used in the example is this one below.
import igeo.*; import processing.opengl.*; void setup(){ size(480, 360, IG.GL); IG.open("lines2.3dm"); ITensileNet.particleClass(MyBoid.class); //custom particle class ITensileNet.create(IG.curves(), IG.points()); new Gravity(IG.v(0, 0, 0.5)); //gravity toward z } class MyBoid extends IBoid{ MyBoid(IVec pos, IVec vel){ super(pos, vel); cohesionDist(2); cohesionRatio(1); separationDist(4); separationRatio(2); alignmentDist(5); alignmentRatio(3); } void update(){ if(IRand.pct(2.0)){ //random occasion of 2% push(IRand.pt(-50,-50,-50,50,50,50)); //random force } } } class Gravity extends IAgent{ IVec gravity; Gravity(IVec g){ gravity=g; } void interact(IDynamics agent){ if(agent instanceof IParticle){ IParticle particle = (IParticle)agent; particle.push(gravity); } } }
Initial state.
After simulation.
The input Rhino file used in the example is this one below.
import igeo.*; import processing.opengl.*; void setup(){ size(480, 360, IG.GL); IG.open("lines3.3dm"); IG.duration(500); ITensileNet.tensionClass(MyTension.class); //custom tension class ITensileNet.create(IG.curves(), IG.points()); new Gravity(IG.v(0, 0, 5)); //gravity toward z } class MyTension extends ITensionLine{ MyTension(IParticle p1, IParticle p2){ super(p1,p2); } void update(){ if(IG.time()%10==0){ IVec p1 = pos1().cp(); IVec p2 = pos2().cp(); new ICurve(p1, p2).clr(IG.time()*0.002); } } } class Gravity extends IAgent{ IVec gravity; Gravity(IVec g){ gravity=g; } void interact(IDynamics agent){ if(agent instanceof IParticle){ IParticle particle = (IParticle)agent; particle.push(gravity); } } }
Initial state.
After simulation.
The code below is putting polygon mesh geometries instead of lines. Using the current two points of a tension line and the previous two points of the line, it forms a rectangular shape. On top of this rectangle, thickness is added creating total eight points and then these eight points are fed into IG.meshBox().
import igeo.*; import processing.opengl.*; void setup(){ size(480, 360, IG.GL); IG.open("lines3.3dm"); IG.duration(500); ITensileNet.tensionClass(MyTension.class); //custom tension class ITensileNet.create(IG.curves(), IG.points()); new Gravity(IG.v(0, 0, 5)); //gravity toward z } class MyTension extends ITensionLine{ IVec prevPos1, prevPos2; MyTension(IParticle p1, IParticle p2){ super(p1,p2); } void update(){ double thickness = 0.8; if(IG.time()%15==0){ IVec p1 = pos1().cp(); IVec p2 = pos2().cp(); if(prevPos1!=null && prevPos2!=null && IRand.pct(80)){ if( !prevPos1.eq(p1) || !prevPos2.eq(p2) ){ //only when moved // mesh slab (box) IVec hdir1 = p2.dif(p1); IVec hdir2 = prevPos2.dif(prevPos1); IVec vdir1 = p1.dif(prevPos1); IVec vdir2 = p2.dif(prevPos2); if(p1.eq(prevPos1)){ vdir1 = vdir2; } //avoid zero vector if(p2.eq(prevPos2)){ vdir2 = vdir1; } //avoid zero vector IVec vertex1 = p1.cp().add(hdir1.cross(vdir1).len(thickness/2)); IVec vertex2 = p2.cp().add(hdir1.cross(vdir2).len(thickness/2)); IVec vertex3 = prevPos2.cp().add(hdir2.cross(vdir2).len(thickness/2)); IVec vertex4 = prevPos1.cp().add(hdir2.cross(vdir1).len(thickness/2)); IVec vertex5 = p1.cp().sub(hdir1.cross(vdir1).len(thickness/2)); IVec vertex6 = p2.cp().sub(hdir1.cross(vdir2).len(thickness/2)); IVec vertex7 = prevPos2.cp().sub(hdir2.cross(vdir2).len(thickness/2)); IVec vertex8 = prevPos1.cp().sub(hdir2.cross(vdir1).len(thickness/2)); IG.meshBox(vertex1, vertex2, vertex3, vertex4, vertex5, vertex6, vertex7, vertex8).clr(IG.time()*0.002); } } prevPos1 = p1; prevPos2 = p2; } } } class Gravity extends IAgent{ IVec gravity; Gravity(IVec g){ gravity=g; } void interact(IDynamics agent){ if(agent instanceof IParticle){ IParticle particle = (IParticle)agent; particle.push(gravity); } } }