Tutorials | (back to the list of tutorials) |
IVec.intersectLine(pt1,pt2,a.pt1,a.pt2)!=null
The input argument of the intersectLine() method is 4 vector varaibles of one end point of the first line, another end point of the first line, one end point of the second line, and another end point of the second line. It returns an intersection point of two line as IVec variable but if they don't intersect, it returns null value. The two more conditions !pt1.eq(a.pt1) and !pt1.eq(a.pt2) inside the if-condition statement exclude the case of the parent line agent or other branching line agents which share the same parent agent.
import processing.opengl.*; import igeo.*; void setup(){ size(480, 360, IG.GL); IG.duration(300); new LineAgent(new IVec(0,0,0), new IVec(0,1,0)).clr(0); } static class LineAgent extends IAgent{ IVec pt1, pt2; boolean isColliding=false; LineAgent(IVec pt, IVec dir){ pt1 = pt; pt2 = pt.cp(dir); } void interact(ArrayList< IDynamics > agents){ if(time == 0){ //only in the first time for(int i=0; i < agents.size() && !isColliding; i++){ if(agents.get(i) instanceof LineAgent){ LineAgent a = (LineAgent)agents.get(i); // checking clearance of end point if(!pt1.eq(a.pt1) && !pt1.eq(a.pt2) && IVec.intersectLine(pt1,pt2,a.pt1,a.pt2)!=null){ isColliding=true; } } } } } void update(){ if(isColliding){ del(); } else if(time == 0){ //if not colliding new ICurve(pt1,pt2).clr(clr()); IVec dir = pt2.dif(pt1); double r = red() + IRand.get(-0.06,0.06); double g = green() + IRand.get(-0.06,0.06); double b = blue() + IRand.get(-0.06,0.06); if(IRand.pct(2.5)){ //branching int num = 15; for(int i=1; i < num; i++){ if(IRand.pct(40)){ IVec dir2 = dir.dup().rev(); dir2.rot(2*PI*i/num); new LineAgent(pt2,dir2).clr(r,g,b); } } } else if(IRand.pct(99)){ //going straight new LineAgent(pt2,dir).clr(r,g,b); } } } }
The next code adds just one line to let the agent turn slightly instead of going straight by rotating the direction vector dir.
dir.rot( PI/80 );
import processing.opengl.*; import igeo.*; void setup(){ size(480, 360, IG.GL); IG.duration(300); new LineAgent(new IVec(0,0,0), new IVec(0,1,0)).clr(0); } static class LineAgent extends IAgent{ IVec pt1, pt2; boolean isColliding=false; LineAgent(IVec pt, IVec dir){ pt1 = pt; pt2 = pt.cp(dir); } void interact(ArrayList< IDynamics > agents){ if(time == 0){ //only in the first time for(int i=0; i < agents.size() && !isColliding; i++){ if(agents.get(i) instanceof LineAgent){ LineAgent a = (LineAgent)agents.get(i); // checking clearance of end point if(!pt1.eq(a.pt1) && !pt1.eq(a.pt2) && IVec.intersectLine(pt1,pt2,a.pt1,a.pt2)!=null){ isColliding=true; } } } } } void update(){ if(isColliding){ del(); } else if(time == 0){ //if not colliding new ICurve(pt1,pt2).clr(clr()); IVec dir = pt2.dif(pt1); double r = red() + IRand.get(-0.06,0.06); double g = green() + IRand.get(-0.06,0.06); double b = blue() + IRand.get(-0.06,0.06); if(IRand.pct(2.5)){ //branching int num = 15; for(int i=1; i < num; i++){ if(IRand.pct(40)){ IVec dir2 = dir.dup().rev(); dir2.rot(2*PI*i/num); new LineAgent(pt2,dir2).clr(r,g,b); } } } else if(IRand.pct(99)){ //bending dir.rot(PI/80); new LineAgent(pt2,dir).clr(r,g,b); } } } }
The code below randomize the move of an agent when it doesn't create branches by randomly rotating the direction vector dir.
dir.rot( IRand.get(-PI/8, PI/8) );
import processing.opengl.*; import igeo.*; void setup(){ size(480, 360, IG.GL); IG.duration(300); new LineAgent(new IVec(0,0,0), new IVec(0,1,0)).clr(0); } static class LineAgent extends IAgent{ IVec pt1, pt2; boolean isColliding=false; LineAgent(IVec pt, IVec dir){ pt1 = pt; pt2 = pt.cp(dir); } void interact(ArrayList< IDynamics > agents){ if(time == 0){ //only in the first time for(int i=0; i < agents.size() && !isColliding; i++){ if(agents.get(i) instanceof LineAgent){ LineAgent a = (LineAgent)agents.get(i); // checking clearance of end point if(!pt1.eq(a.pt1) && !pt1.eq(a.pt2) && IVec.intersectLine(pt1,pt2,a.pt1,a.pt2)!=null){ isColliding=true; } } } } } void update(){ if(isColliding){ del(); } else if(time == 0){ //if not colliding new ICurve(pt1,pt2).clr(clr()); IVec dir = pt2.dif(pt1); double r = red() + IRand.get(-0.06,0.06); double g = green() + IRand.get(-0.06,0.06); double b = blue() + IRand.get(-0.06,0.06); if(IRand.pct(2.5)){ //branching int num = 15; for(int i=1; i < num; i++){ if(IRand.pct(40)){ IVec dir2 = dir.dup().rev(); dir2.rot(2*PI*i/num); new LineAgent(pt2,dir2).clr(r,g,b); } } } else if(IRand.pct(99)){ //random bend dir.rot(IRand.get(-PI/20,PI/20)); new LineAgent(pt2,dir).clr(r,g,b); } } } }
This code below changes two parts of
the second rotating agent code.
First, the range of branching angle is limited to
Pi, instead of 2 Pi, by changing this line in the previous code
dir2.rot( 2*PI*i/num );
to
dir2.rot( PI*i/num );
The second change is to scale down (or sometimes up)
the length of
line agents in both cases of creating branch agents and just going
with a single agent.
This is done by multiplying some number to the
direction vector dir for a single agent
or dir2 for branching
agents in those lines.
dir2.mul( IRand.get(0.9, 1.35) ); //scale up or down
dir.mul( 0.98 ); //scale down
import processing.opengl.*; import igeo.*; void setup(){ size(480, 360, IG.GL); IG.duration(250); new LineAgent(new IVec(0,0,0), new IVec(0,1,0)).clr(0); } static class LineAgent extends IAgent{ IVec pt1, pt2; boolean isColliding=false; LineAgent(IVec pt, IVec dir){ pt1 = pt; pt2 = pt.cp(dir); } void interact(ArrayList< IDynamics > agents){ if(time == 0){ //only in the first time for(int i=0; i < agents.size() && !isColliding; i++){ if(agents.get(i) instanceof LineAgent){ LineAgent a = (LineAgent)agents.get(i); // checking clearance of end point if(!pt1.eq(a.pt1) && !pt1.eq(a.pt2) && IVec.intersectLine(pt1,pt2,a.pt1,a.pt2)!=null){ isColliding=true; } } } } } void update(){ if(isColliding){ del(); } else if(time == 0){ //if not colliding new ICurve(pt1,pt2).clr(clr()); IVec dir = pt2.dif(pt1); double r = red() + IRand.get(-0.06,0.06); double g = green() + IRand.get(-0.06,0.06); double b = blue() + IRand.get(-0.06,0.06); if(IRand.pct(2.5)){ //branching int num = 15; for(int i=1; i < num; i++){ if(IRand.pct(40)){ IVec dir2 = dir.dup().rev(); dir2.rot(PI*i/num); dir2.mul(IRand.get(0.9, 1.35)); //scale up or down new LineAgent(pt2,dir2).clr(r,g,b); } } } else if(IRand.pct(99)){ //bend and scale dir.rot(PI/40); dir.mul(0.98); //scale down new LineAgent(pt2,dir).clr(r,g,b); } } } }