Tutorials | (back to the list of tutorials) |
Multi-Agent 3D Example 2 (requires iGeo version 7.6.0 or higher)![]()
![]()
![]()
![]()
import processing.opengl.*;
import igeo.*;
void setup() {
size(480, 360, IG.GL);
IG.duration(300);
// left 100%, right 4.5%
new LineAgent(IG.v(0,0,0), IG.v(2,0,0), 100.0, 4.5).clr(0);
}
static class LineAgent extends IAgent{
IVec pos;
IVec dir;
double pctL, pctR;
boolean isColliding=false;
IVec intersection;
LineAgent(IVec pt, IVec dir, double pctL, double pctR) {
pos = pt;
this.dir = dir;
this.pctL = pctL;
this.pctR = pctR;
}
public void interact(ArrayList < IDynamics > agents){
if(time()==0){
for(int i=0; i < agents.size() && !isColliding ; i++){
if(agents.get(i) instanceof LineAgent){
LineAgent a = (LineAgent)agents.get(i);
if(a != this){
IVec pos2 = pos.cp(dir);
IVec apos2 = a.pos.cp(a.dir);
if(!apos2.eq(pos) && !a.pos.eq(pos)){ //not sharing root
intersection = IVec.intersectLine(a.pos,apos2,pos,pos2); //keep intersection to draw line later
if(intersection!=null){ //intersecting
isColliding=true;
}
}
}
}
}
}
}
public void update() {
if(time()==0){
IVec pos2 = pos.dup().add(dir);
double thickness = 0.3;
IVec widthDir = dir.dup().rot(PI/2).len(thickness/2);
double z1 = sin(IG.time()*0.05)*10+15;
double z2 = sin((IG.time()+1)*0.05)*10+15;
IVec meshPt1 = pos;
IVec meshPt2 = pos2;
if(isColliding){ meshPt2 = intersection; }
IG.meshBox(meshPt1.dup().sub(widthDir),
meshPt2.dup().sub(widthDir),
meshPt2.dup().add(widthDir),
meshPt1.dup().add(widthDir),
meshPt1.dup().sub(widthDir).add(0,0,z1),
meshPt2.dup().sub(widthDir).add(0,0,z2),
meshPt2.dup().add(widthDir).add(0,0,z2),
meshPt1.dup().add(widthDir).add(0,0,z1)).clr(clr());
if(isColliding){
del();
return;
}
double r = red() + IRand.get(-0.05, 0.05);
double g = green() + IRand.get(-0.05, 0.05);
double b = blue() + IRand.get(-0.05, 0.05);
boolean branchL = IRand.pct(pctL);
boolean branchR = IRand.pct(pctR);
double lenL = dir.len();
double lenR = dir.len();
lenL*=0.995; //shrinking length
lenR*=0.995; //shrinking length
if (branchL && branchR) { //only when branching both
if(IRand.pct(50.0)){
if (pctL < pctR) { lenL *= 0.9; }
else{ lenR *= 0.9; }
}
else if(IRand.pct(6.0)){
if (pctL < pctR) { lenL *= 0.4; }
else{ lenR *= 0.4; }
}
else if(IRand.pct(5.0)){
if (pctL < pctR) { lenL *= 4; }
else{ lenR *= 4; }
}
}
if (branchL) { //bend left
IVec dir2 = dir.dup();
dir2.len(lenL); //update length
dir2.rot(PI/30);
if(branchR && pctR > pctL){ //swap L/R% when branching both
new LineAgent(pos2, dir2, pctR, pctL).clr(r,g,b);
}
else{
new LineAgent(pos2, dir2, pctL, pctR).clr(r,g,b);
}
}
if (branchR) { //bend right
IVec dir2 = dir.dup();
dir2.len(lenR); //update length
dir2.rot(-PI/30);
if(branchL && pctR < pctL){ //swap L/R% when branching both
new LineAgent(pos2, dir2, pctR, pctL).clr(r,g,b);
}
else{
new LineAgent(pos2, dir2, pctL, pctR).clr(r,g,b);
}
}
}
}
}
The example code below takes the previous tutorial code at "Multi-Agent 2D Example 3" and layering multiple agents in different z levels and interconnect them. All the branches and interconnection lines are made out of polygon mesh sticks.
![]()
![]()
![]()
![]()
import processing.opengl.*;
import igeo.*;
void setup() {
size(480, 360, IG.GL);
IG.duration(80);
double z = 0;
for(int i=0; i < 20; i++){
//IRand.dir() is giving a random direction with given length perpendicular to given axis
new LineAgent(IRand.pt(-30,-30,z,30,30,z), IRand.dir(IG.zaxis,2), 100.0, 4.5).clr(0);
z += IRand.get(1,5);
}
}
static class LineAgent extends IAgent{
IVec pos;
IVec dir;
double pctL, pctR;
boolean isColliding=false;
IVec intersection;
LineAgent(IVec pt, IVec dir, double pctL, double pctR) {
pos = pt;
this.dir = dir;
this.pctL = pctL;
this.pctR = pctR;
}
public void interact(ArrayList < IDynamics > agents){
if(time()==0){
for(int i=0; i < agents.size() && !isColliding ; i++){
if(agents.get(i) instanceof LineAgent){
LineAgent a = (LineAgent)agents.get(i);
if(a != this){
//draw interconnection in z
if( !pos.eqZ(a.pos) ){ //z is not equal
double minLen = dir.len();
if(a.dir.len() < minLen){ minLen = a.dir.len(); }
double threshold = minLen * 2.5;
if( pos.eqX(a.pos, threshold) && pos.eqY(a.pos, threshold) ){ //x and y is equal with in given tolerance
if(IRand.pct(60)){
//new ICurve(pos, a.pos).clr(clr());
IG.meshSquareStick(pos, a.pos, 0.3).clr(clr());
}
}
}
else{
IVec pos2 = pos.cp(dir);
IVec apos2 = a.pos.cp(a.dir);
if(!apos2.eq(pos) && !a.pos.eq(pos)){ //not sharing root
intersection = IVec.intersectLine(a.pos,apos2,pos,pos2); //keep intersection to draw line later
if(intersection!=null){ //intersecting
isColliding=true;
}
}
}
}
}
}
}
}
public void update() {
if(time()==0){
if(isColliding){
//new ICurve(pos, intersection).clr(clr());
IG.meshSquareStick(pos, intersection, 0.5).clr(clr()); //keep line to intersection
del();
return;
}
IVec pos2 = pos.dup().add(dir);
//new ICurve(pos, pos2).clr(clr());
IG.meshSquareStick(pos, pos2, 0.5).clr(clr());
double r = red() + IRand.get(-0.05, 0.05);
double g = green() + IRand.get(-0.05, 0.05);
double b = blue() + IRand.get(-0.05, 0.05);
boolean branchL = IRand.pct(pctL);
boolean branchR = IRand.pct(pctR);
double lenL = dir.len();
double lenR = dir.len();
lenL*=0.995; //shrinking length
lenR*=0.995; //shrinking length
if (branchL && branchR) { //only when branching both
if(IRand.pct(50.0)){
if (pctL < pctR) { lenL *= 0.9; }
else{ lenR *= 0.9; }
}
else if(IRand.pct(6.0)){
if (pctL < pctR) { lenL *= 0.4; }
else{ lenR *= 0.4; }
}
else if(IRand.pct(5.0)){
if (pctL < pctR) { lenL *= 1.4; }
else{ lenR *= 1.4; }
}
}
if (branchL) { //bend left
IVec dir2 = dir.dup();
dir2.len(lenL); //update length
dir2.rot(PI/30);
if(branchR && pctR > pctL){ //swap L/R% when branching both
new LineAgent(pos2, dir2, pctR, pctL).clr(r,g,b);
}
else{
new LineAgent(pos2, dir2, pctL, pctR).clr(r,g,b);
}
}
if (branchR) { //bend right
IVec dir2 = dir.dup();
dir2.len(lenR); //update length
dir2.rot(-PI/30);
if(branchL && pctR < pctL){ //swap L/R% when branching both
new LineAgent(pos2, dir2, pctR, pctL).clr(r,g,b);
}
else{
new LineAgent(pos2, dir2, pctL, pctR).clr(r,g,b);
}
}
}
}
}
HOME
FOR PROCESSING
DOWNLOAD
DOCUMENTS
TUTORIALS (Java /
Python)
GALLERY
SOURCE CODE(GitHub)
PRIVACY POLICY
ABOUT/CONTACT