Tutorials | (back to the list of tutorials) |
The first code below shows an algorithm to import curves from an external file and to create particles at divided points on each curve. Then each pair of particles in an array is connected again with tension lines.
The input file used in the code is tension_lines1.3dm.
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.bg(0); IG.open("tension_lines1.3dm"); ICurve[] curves = IG.curves(); int division=30; double inc = 1.0/division; for (int i=0; i < curves.length; i++) { IParticle[] pts = new IParticle[division+1]; for (int j=0; j <= division; j++) { // creating particles pts[j] = new IParticle( curves[i].pt( j*inc ) ).fric(0.01); } pts[0].fix(); // fixing the start point pts[division].fix(); // fixing the end point for (int j=0; j < division; j++) { // connecting particles new ITensionLine(pts[j], pts[j+1]).tension(150).clr(1.0, 0.5).weight(2); } curves[i].del(); }
The next code applies forces to the tension lines with two attractors, one with attractive force and another with repulsive force.
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.bg(0); IG.open("tension_lines1.3dm"); ICurve[] curves = IG.curves(); new IAttractor(15, 6, 0).intensity(10).linear(30).clr(1.0,0,0).size(8); new IAttractor(5, 4, 0).intensity(-30).linear(10).clr(1.0,0,0).size(8); int division=30; double inc = 1.0/division; for (int i=0; i < curves.length; i++) { IParticle[] pts = new IParticle[division+1]; for (int j=0; j <= division; j++) { // creating particles pts[j] = new IParticle( curves[i].pt( j*inc ) ).fric(0.01); } pts[0].fix(); // fixing the start point pts[division].fix(); // fixing the end point for (int j=0; j < division; j++) { // connecting particles new ITensionLine(pts[j], pts[j+1]).tension(150).clr(1.0, 0.5).weight(2); } curves[i].del(); }
This third code creates instances of swarm agent IBoid class, instead of particle instances. Because of forces between swarm, each node of tension strings attracts each other trying to form clusters but the tension still pulls them apart in certain directions.
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.bg(0); IG.open("tension_lines1.3dm"); ICurve[] curves = IG.curves(); int division=30; double inc = 1.0/division; for (int i=0; i < curves.length; i++) { IBoid[] pts = new IBoid[division+1]; for (int j=0; j <= division; j++) { // creating particles pts[j] = new IBoid( curves[i].pt( j*inc ) ).fric(0.1); pts[j].cohesionDist(1); pts[j].cohesionRatio(10); pts[j].separationRatio(0); pts[j].alignmentRatio(0); } pts[0].fix(); // fixing the start point pts[division].fix(); // fixing the end point for (int j=0; j < division; j++) { // connecting particles new ITensionLine(pts[j], pts[j+1]).tension(150).clr(1.0, 0.5).weight(2); } curves[i].del(); }
The next example only changes the input file. When you have random intersecting lines, swarm forces to cluster together are clear. The final lines are result of the balance between gathering swarm forces and smoothing tension forces. The code below also hides points by hide() method.
The input file used in the next code is tension_lines2.3dm.
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.bg(0); IG.open("tension_lines2.3dm"); ICurve[] curves = IG.curves(); int division=50; double inc = 1.0/division; for (int i=0; i < curves.length; i++) { IBoid[] pts = new IBoid[division+1]; for (int j=0; j <= division; j++) { // creating particles pts[j] = new IBoid( curves[i].pt( j*inc ) ).fric(0.1); pts[j].cohesionDist(0.5); pts[j].cohesionRatio(50); pts[j].separationRatio(0); pts[j].alignmentRatio(0); pts[j].hide(); } pts[0].fix(); // fixing the start point pts[division].fix(); // fixing the end point for (int j=0; j < division; j++) { // connecting particles new ITensionLine(pts[j], pts[j+1]).tension(100).clr(1.0, 0.5).weight(2); } curves[i].del(); }
This shows the random intersecting input lines.
This is the result when they are in equilibrium.