AList Edges = new AList(); class Edge extends Base { Node n0, n1; AgentProgressComparator agentComparator = new AgentProgressComparator(); int trampled = 0; //Edge properties float weight = 1.0f; float edgeLength; float normalLength; float edgeWidth; float density = 0; Edge(Node n0, Node n1, color c, String label, String type) { super(c, label, type, Edges); this.n0 = n0; this.n1 = n1; n0.addEdge(this); n1.addEdge(this); update(); } boolean isFull() { return getAgentsHere().size() * Graph.singleFileWidth > edgeLength; } float placeAgent() { return (getAgentsHere().size() + 1) * Graph.singleFileWidth / edgeLength; } void placeAgentsUniform() { Agent agent; float numAgents = float(getAgentsHere().size()); for (int i = 0; i < numAgents; i++) { agent = (Agent)getAgentsHere().get(i); agent.percent = i/numAgents; agent.speed = (agent.percent < 0.5) ? -abs(agent.speed) : abs(agent.speed); } } void setWeight(float weight) { this.weight=weight; } void modifyWeight(float delta) { this.weight+=delta; } void paint(){ color crowdColor; if (isCrowded()) { crowdColor = color(red(c),green(c)+255,blue(c),alpha(c)+100); //blend (c, color(0, 255, 0, 200), ADD); } else if (showPeople && getAgentsHere().size()>0) { crowdColor = color(255); } else { crowdColor = c; } stroke(crowdColor); if (subtype != "" && !showPeople) stroke(255); line(n0.x, n0.y, n0.z, n1.x, n1.y, n1.z); paintLabel(CENTER,(n0.x+n1.x)/2,(n0.y+n1.y)/2,(n0.z+n1.z)/2); if (showTrampled && trampled>0) { stroke(255,0,0); line(n0.x, n0.y-trampled/4, n0.z, n1.x, n1.y-trampled/4, n1.z); line(n0.x, n0.y-trampled/4, n0.z, n0.x, n0.y, n0.z); line(n1.x, n1.y-trampled/4, n1.z, n1.x, n1.y, n1.z); } } float len() { //return sqrt(sq(n0.x-n1.x)+sq(n0.y-n1.y)+sq(n0.z-n1.z)); //return isCrowded() ? weight*edgeLength*3.0 : weight*edgeLength; return weight*edgeLength; } float getWidth() { return edgeWidth; } float normalX() { return dz() / normalLength; } float normalZ() { return -dx() / normalLength; } float dx() { return n1.x-n0.x; } float dy() { return n1.y-n0.y; } float dz() { return n1.z-n0.z; } Node n0() { return n0; } Node n1() { return n1; } Node nOther(Node n) { return (n0==n)?n1:n0; // could use ID } void update() { // adjusts x,y,z to be middle of node locations. x=(n0.x+n1.x)/2; y=(n0.y+n1.y)/2; z=(n0.z+n1.z)/2; edgeLength = sqrt(sq(n0.x-n1.x)+sq(n0.y-n1.y)+sq(n0.z-n1.z)); normalLength = sqrt(sq(dx()) + sq(dz())); if (getData(Base.Type) == graph.Row) edgeWidth = Graph.widthOfRow; else if (getData(Base.Type) == graph.Aisle) edgeWidth = Graph.widthOfAisle; else edgeWidth = Graph.widthOfCorridor; } float getCurrentDensity() { return calcCurrentDensity(); //return density; } float calcCurrentDensity() { density = getAgentsHere().size() / edgeLength / edgeWidth ; return density; } boolean isCrowded() { if (graph != null) { return (getCurrentDensity() > graph.crowdedDensity); } return false; } void step() { float D = calcCurrentDensity(); //java.util.Collections.sort(Agents, agentComparator); } boolean twoNeighborRows() { int n = 0; AList neighbors = new AList(); neighbors.addAll(n0.edges); neighbors.addAll(n1.edges); Iterator it = neighbors.iterator(); while (it.hasNext()) { if (((Edge) it.next()).getType() == Graph.Row) n++; if (n>=2) return true; } return false; } } // ---- Utils ---- class ModifyWeight implements Ask { float delta; ModifyWeight(float delta) { this.delta = delta; } void ask(Object o) { ((Edge)o).modifyWeight(delta); } } class ModifyWeightByRadius implements Ask { Node center; float maxDelta; ModifyWeightByRadius(Node center, float maxDelta) { this.center = center; this.maxDelta = maxDelta; } void ask(Object o) { float radius = ((Edge)o).lenTo(center); float delta = maxDelta/radius; ((Edge)o).modifyWeight(delta); } } public class AgentProgressComparator implements java.util.Comparator { int compare (Object o1, Object o2) { Agent a1 = (Agent) o1, a2 = (Agent) o2; if (a1.percent == a2.percent) return 0; return (a1.percent < a2.percent) ? -1 : 1; } }