MrMusAddict

Satisfactory Graph Theory Proof-Of-Concept v2

Oct 22nd, 2024
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 26.12 KB | None | 0 0
  1. NHandler nodeHandler;
  2.  
  3. Node test;
  4.  
  5. void setup() {
  6.   size(1920, 1080);
  7.   nodeHandler = new NHandler();
  8. }
  9.  
  10. void draw() {
  11.   background(51);
  12.  
  13.   if (frameCount % 30 == 0) nodeHandler.pulseQTYs();
  14.  
  15.   nodeHandler.render();
  16. }
  17.  
  18.  
  19.  
  20.  
  21. class Node {
  22.   PVector pos;
  23.   color col;
  24.  
  25.   color ringCol;
  26.   float ringSize;
  27.  
  28.   int nodeID;
  29.  
  30.   NHandler handler;
  31.  
  32.   ArrayList<Integer> parents;
  33.   ArrayList<Integer> children;
  34.  
  35.   boolean valid;
  36.  
  37.   int trueQTY;
  38.   int infiniteRate;
  39.   int reserveQTY1;
  40.   int reserveQTY2;
  41.  
  42.   int pulseCount;
  43.  
  44.   PVector northPort;
  45.   PVector southPort;
  46.   PVector eastPort;
  47.   PVector westPort;
  48.  
  49.   Node(NHandler nh, int posx, int posy) {
  50.     handler = nh;
  51.     nodeID = handler.NodeIDsCreated;
  52.     valid = true;
  53.     parents = new ArrayList<Integer>();
  54.     children = new ArrayList<Integer>();
  55.     pos = new PVector(posx, posy);
  56.     northPort = new PVector(posx, posy-handler.nodeSize/2.0);
  57.     southPort = new PVector(posx, posy+handler.nodeSize/2.0);
  58.     eastPort = new PVector(posx+handler.nodeSize/2.0, posy);
  59.     westPort = new PVector(posx-handler.nodeSize/2.0, posy);
  60.     trueQTY = 0;
  61.     reserveQTY1 = 0;
  62.     reserveQTY2 = 0;
  63.     infiniteRate = 15;
  64.   }
  65.  
  66.   void setValid(boolean b) {
  67.     valid = b;
  68.   }
  69.  
  70.   void addParent(int parentID) {
  71.     parents.add(parentID);
  72.   }
  73.  
  74.   void addChild(int childID) {
  75.     children.add(childID);
  76.   }
  77.  
  78.   void tryRemoveParent(int parentID) {
  79.     for (int i = parents.size()-1; i >= 0; i--) {
  80.       if (parents.get(i) == parentID) {
  81.         parents.remove(i);
  82.       }
  83.     }
  84.   }
  85.  
  86.   void tryRemoveChild(int childID) {
  87.     for (int i = children.size()-1; i >= 0; i--) {
  88.       if (children.get(i) == childID) {
  89.         children.remove(i);
  90.       }
  91.     }
  92.   }
  93.  
  94.   void updatePortPositions() {
  95.     northPort = new PVector(pos.x, pos.y-handler.nodeSize/2.0);
  96.     southPort = new PVector(pos.x, pos.y+handler.nodeSize/2.0);
  97.     eastPort = new PVector(pos.x+handler.nodeSize/2.0, pos.y);
  98.     westPort = new PVector(pos.x-handler.nodeSize/2.0, pos.y);
  99.   }
  100.  
  101.   void show(color f) {
  102.     stroke(0);
  103.     fill(f);
  104.     circle(pos.x, pos.y, handler.nodeSize);
  105.     fill(0);
  106.     stroke(0);
  107.     textSize(handler.textSize);
  108.     if (parents.size()==0) {
  109.       text(infiniteRate, pos.x, pos.y);
  110.     } else {
  111.       text(trueQTY, pos.x, pos.y);
  112.     }
  113.   }
  114.  
  115.   void pulseToChildren() {
  116.     if (parents.size() == 0) {
  117.       trueQTY = infiniteRate;
  118.     }
  119.     if (children.size()>0) {
  120.       for (int i = trueQTY; i > 0; i--) {
  121.         pulseCount++;
  122.         handler.getNodeByID(children.get(pulseCount % (children.size()))).reserveQTY1++;
  123.         trueQTY--;
  124.       }
  125.     } else {
  126.       trueQTY = 0;
  127.       reserveQTY2 = 0;
  128.     }
  129.   }
  130.  
  131.  
  132.   String getSendingPortDirection(Node otherNode) {
  133.     float onXD = otherNode.pos.x - pos.x;
  134.     float cXD1 = 100000;
  135.     float cXD2 = 100000;
  136.     float cXD3 = 100000;
  137.  
  138.     float onYD = otherNode.pos.y - pos.y;
  139.     float cYD1 = 100000;
  140.     float cYD2 = 100000;
  141.     float cYD3 = 100000;
  142.  
  143.     float distON = dist(0, 0, onXD, onYD);
  144.     float dist1 = 100000;
  145.     float dist2 = 100000;
  146.     float dist3 = 100000;
  147.  
  148.     switch(children.size()) {
  149.     case 1:
  150.       return "south";
  151.     case 2:
  152.       cXD1 = handler.getNodeByID(children.get(0)).pos.x - pos.x;
  153.       cXD2 = handler.getNodeByID(children.get(1)).pos.x - pos.x;
  154.  
  155.       cYD1 = handler.getNodeByID(children.get(0)).pos.y - pos.y;
  156.       cYD2 = handler.getNodeByID(children.get(1)).pos.y - pos.y;
  157.  
  158.       dist1 = dist(0, 0, cXD1, cYD1);
  159.       dist2 = dist(0, 0, cXD2, cYD2);
  160.  
  161.       if (cXD1 < 0 && cXD2 < 0) { //if both are on the left, the further left one connects west, the closer left one connects south
  162.         if (onXD == min(cXD1, cXD2)) {
  163.           return "west";
  164.         } else {
  165.           return "south";
  166.         }
  167.       } else if (cXD1 > 0 && cXD2 > 0) { //if both are on the right, the further right one connects east, the closer right one connects south
  168.         if (onXD == min(cXD1, cXD2)) {
  169.           return "south";
  170.         } else {
  171.           return "east";
  172.         }
  173.       } else if (min(abs(cXD1), abs(cXD2)) == 0 && max(abs(cXD1), abs(cXD2)) > 0) { //if one is directly below, connect it south. Otherwise go east or west
  174.         if (onXD == 0) {
  175.           return "south";
  176.         } else {
  177.           if (onXD > 0) {
  178.             return "east";
  179.           } else {
  180.             return "west";
  181.           }
  182.         }
  183.       } else { //otherwise, the closer node connects south, and the remaining node connects either east or west
  184.         if (distON == min(dist1, dist2)) {
  185.           return "south";
  186.         } else {
  187.           if (max(dist1, dist2) == dist1) {
  188.             float sign = cXD1/abs(cXD1);
  189.             if (sign > 0) {
  190.               return "east";
  191.             } else {
  192.               return "west";
  193.             }
  194.           }
  195.         }
  196.       }
  197.       return "east";
  198.     case 3:
  199.       cXD1 = handler.getNodeByID(children.get(0)).pos.x - pos.x;
  200.       cXD2 = handler.getNodeByID(children.get(1)).pos.x - pos.x;
  201.       cXD3 = handler.getNodeByID(children.get(2)).pos.x - pos.x;
  202.       float[] cXD = {cXD1, cXD2, cXD3};
  203.       cXD = sort(cXD);
  204.  
  205.       cYD1 = handler.getNodeByID(children.get(0)).pos.y - pos.y;
  206.       cYD2 = handler.getNodeByID(children.get(1)).pos.y - pos.y;
  207.       cYD3 = handler.getNodeByID(children.get(2)).pos.y - pos.y;
  208.       float[] cYD = {cYD1, cYD2, cYD3};
  209.       cYD = sort(cYD);
  210.  
  211.       dist1 = dist(0, 0, cXD1, cYD1);
  212.       dist2 = dist(0, 0, cXD2, cYD2);
  213.       dist3 = dist(0, 0, cXD3, cYD3);
  214.  
  215.       if (cXD[0] != cXD[1] && cXD[1] != cXD[2] && cXD[2] != cXD[0]) { //if all deltas of X are different, assign west/south/east to min/med/max
  216.         if (onXD == cXD[0]) {
  217.           return "west";
  218.         } else if (onXD == cXD[2]) {
  219.           return "east";
  220.         } else {
  221.           return "south";
  222.         }
  223.       } else if (((cXD[1] == cXD[0]) || (cXD[1] == cXD[2])) && cXD[0] != cXD[2]) { //if 2 are the same, just combine them out of the same port (too complex otherwise), the last one goes out the correct port.
  224.         if (cXD[1] == cXD[0]) {
  225.           if (onXD == cXD[2]) {
  226.             return "east";
  227.           } else {
  228.             return "west";
  229.           }
  230.         } else {
  231.           if (onXD == cXD[0]) {
  232.             return "west";
  233.           } else {
  234.             return "east";
  235.           }
  236.         }
  237.       } else {
  238.         return "south";
  239.       }
  240.     default:
  241.       return "south";
  242.     }
  243.   }
  244.  
  245.   String getReceivingPortDirection(Node otherNode) {
  246.  
  247.     float onXD = otherNode.pos.x - pos.x;
  248.     float cXD1 = 100000;
  249.     float cXD2 = 100000;
  250.     float cXD3 = 100000;
  251.  
  252.     float onYD = otherNode.pos.y - pos.y;
  253.     float cYD1 = 100000;
  254.     float cYD2 = 100000;
  255.     float cYD3 = 100000;
  256.  
  257.     float distON = dist(0, 0, onXD, onYD);
  258.     float dist1 = 100000;
  259.     float dist2 = 100000;
  260.     float dist3 = 100000;
  261.  
  262.     switch(parents.size()) {
  263.     case 1:
  264.       return "north";
  265.     case 2:
  266.       cXD1 = handler.getNodeByID(parents.get(0)).pos.x - pos.x;
  267.       cXD2 = handler.getNodeByID(parents.get(1)).pos.x - pos.x;
  268.  
  269.       cYD1 = handler.getNodeByID(parents.get(0)).pos.y - pos.y;
  270.       cYD2 = handler.getNodeByID(parents.get(1)).pos.y - pos.y;
  271.  
  272.       dist1 = dist(0, 0, cXD1, cYD1);
  273.       dist2 = dist(0, 0, cXD2, cYD2);
  274.  
  275.       if (cXD1 < 0 && cXD2 < 0) { //if both are on the left, the further left one connects west, the closer left one connects south
  276.         if (onXD == min(cXD1, cXD2)) {
  277.           return "west";
  278.         } else {
  279.           return "north";
  280.         }
  281.       } else if (cXD1 > 0 && cXD2 > 0) { //if both are on the right, the further right one connects east, the closer right one connects south
  282.         if (onXD == min(cXD1, cXD2)) {
  283.           return "north";
  284.         } else {
  285.           return "east";
  286.         }
  287.       } else if (min(abs(cXD1), abs(cXD2)) == 0 && max(abs(cXD1), abs(cXD2)) > 0) { //if one is directly below, connect it south. Otherwise go east or west
  288.         if (onXD == 0) {
  289.           return "north";
  290.         } else {
  291.           if (onXD > 0) {
  292.             return "east";
  293.           } else {
  294.             return "west";
  295.           }
  296.         }
  297.       } else { //otherwise, the closer node connects south, and the remaining node connects either east or west
  298.         if (distON == min(dist1, dist2)) {
  299.           return "north";
  300.         } else {
  301.           if (max(dist1, dist2) == dist1) {
  302.             float sign = cXD1/abs(cXD1);
  303.             if (sign > 0) {
  304.               return "east";
  305.             } else {
  306.               return "west";
  307.             }
  308.           }
  309.         }
  310.       }
  311.       return "east";
  312.     case 3:
  313.       cXD1 = handler.getNodeByID(parents.get(0)).pos.x - pos.x;
  314.       cXD2 = handler.getNodeByID(parents.get(1)).pos.x - pos.x;
  315.       cXD3 = handler.getNodeByID(parents.get(2)).pos.x - pos.x;
  316.       float[] cXD = {cXD1, cXD2, cXD3};
  317.       cXD = sort(cXD);
  318.  
  319.       cYD1 = handler.getNodeByID(parents.get(0)).pos.y - pos.y;
  320.       cYD2 = handler.getNodeByID(parents.get(1)).pos.y - pos.y;
  321.       cYD3 = handler.getNodeByID(parents.get(2)).pos.y - pos.y;
  322.       float[] cYD = {cYD1, cYD2, cYD3};
  323.       cYD = sort(cYD);
  324.  
  325.       dist1 = dist(0, 0, cXD1, cYD1);
  326.       dist2 = dist(0, 0, cXD2, cYD2);
  327.       dist3 = dist(0, 0, cXD3, cYD3);
  328.  
  329.       if (cXD[0] != cXD[1] && cXD[1] != cXD[2] && cXD[2] != cXD[0]) { //if all deltas of X are different, assign west/south/east to min/med/max
  330.         if (onXD == cXD[0]) {
  331.           return "west";
  332.         } else if (onXD == cXD[2]) {
  333.           return "east";
  334.         } else {
  335.           return "north";
  336.         }
  337.       } else if (((cXD[1] == cXD[0]) || (cXD[1] == cXD[2])) && cXD[0] != cXD[2]) { //if 2 are the same, just combine them out of the same port (too complex otherwise), the last one goes out the correct port.
  338.         if (cXD[1] == cXD[0]) {
  339.           if (onXD == cXD[2]) {
  340.             return "east";
  341.           } else {
  342.             return "west";
  343.           }
  344.         } else {
  345.           if (onXD == cXD[0]) {
  346.             return "west";
  347.           } else {
  348.             return "east";
  349.           }
  350.         }
  351.       } else {
  352.         return "north";
  353.       }
  354.     default:
  355.       return "north";
  356.     }
  357.   }
  358.  
  359.   PVector getReceivingPortPosition(Node otherNode) {
  360.     float dX = otherNode.pos.x-pos.x;
  361.     float dY = otherNode.pos.y-pos.y;
  362.  
  363.     if (dY >= 0) {
  364.       if (dX >= 0) {
  365.         return eastPort;
  366.       } else {
  367.         return westPort;
  368.       }
  369.     } else {
  370.       if (abs(dY) > abs(dX)) {
  371.         return northPort;
  372.       } else {
  373.         if (dX >= 0) {
  374.           return eastPort;
  375.         } else {
  376.           return westPort;
  377.         }
  378.       }
  379.     }
  380.   }
  381.  
  382.   float itemRate() {
  383.     if (parents.size() == 0) {
  384.       return infiniteRate;
  385.     } else {
  386.       if (children.size() == 0) {
  387.         return trueQTY;
  388.       } else {
  389.         return trueQTY / float(children.size());
  390.       }
  391.     }
  392.   }
  393. }
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400. class NHandler {
  401.   int NodeIDsCreated;
  402.   ArrayList<Node> nodes;
  403.   ArrayList<PVector> relationships;
  404.  
  405.   Node selected;
  406.   Node movingNode;
  407.  
  408.   float nodeSize;
  409.   float textSize;
  410.  
  411.   boolean deleting;
  412.  
  413.   NHandler() {
  414.     nodes = new ArrayList<Node>();
  415.     NodeIDsCreated = 0;
  416.     relationships = new ArrayList<PVector>();
  417.     nodeSize = 75.0;
  418.     textSize = nodeSize / 4.0;
  419.     deleting = false;
  420.   }
  421.  
  422.   void addNode(int numToAdd) {
  423.     for (int i = 0; i < numToAdd; i++) {
  424.       NodeIDsCreated++;
  425.       nodes.add(new Node(this, 0, 0));
  426.     }
  427.   }
  428.  
  429.   void addNode(int numToAdd, int posx, int posy) {
  430.     for (int i = 0; i < numToAdd; i++) {
  431.       NodeIDsCreated++;
  432.       nodes.add(new Node(this, posx, posy));
  433.     }
  434.   }
  435.  
  436.   boolean validID(int id) {
  437.     boolean temp = false;
  438.     for (Node n : nodes) {
  439.       if (n.nodeID == id && n.valid) {
  440.         temp = true;
  441.         break;
  442.       }
  443.     }
  444.     return temp;
  445.   }
  446.  
  447.   void createRelationship(Node parent, Node child) {
  448.     int pID = parent.nodeID;
  449.     int cID = child.nodeID;
  450.     if (pID != cID) {
  451.  
  452.  
  453.       parent.children.add(cID);
  454.       child.parents.add(pID);
  455.       relationships.add(new PVector(pID, cID));
  456.     }
  457.   }
  458.  
  459.   void createOrRemoveRelationship(int parentID, int childID) {
  460.     if (parentID != childID) {
  461.       if (!containsRelationship(parentID, childID)) {
  462.         getNodeByID(parentID).children.add(childID);
  463.         getNodeByID(childID).parents.add(parentID);
  464.         relationships.add(new PVector(parentID, childID));
  465.       } else {
  466.         breakSpecificRelationship(parentID, childID);
  467.       }
  468.     } else {
  469.       println("Same ID (" + parentID + ", " + childID);
  470.     }
  471.   }
  472.  
  473.   Node getNodeByID(int nID) {
  474.     Node temp = null;
  475.  
  476.     for (Node n : nodes) {
  477.       if (n.nodeID == nID) return n;
  478.     }
  479.  
  480.     return temp;
  481.   }
  482.  
  483.   boolean containsRelationship(int parID, int chiID) {
  484.     for (PVector r : relationships) {
  485.       if (r.x == parID && r.y == chiID) {
  486.         return true;
  487.       }
  488.     }
  489.     return false;
  490.   }
  491.  
  492.   void breakAllRelationshipsOfNode(Node n) {
  493.     for (int i = relationships.size()-1; i >= 0; i--) {
  494.       if (relationships.get(i).x == n.nodeID || relationships.get(i).y == n.nodeID) {
  495.         int parID = int(relationships.get(i).x);
  496.         int chiID = int(relationships.get(i).y);
  497.  
  498.         getNodeByID(parID).tryRemoveChild(chiID);
  499.         getNodeByID(chiID).tryRemoveParent(parID);
  500.         relationships.remove(i);
  501.       }
  502.     }
  503.   }
  504.  
  505.   void breakAllRelationshipsOfNodeID(int nID) {
  506.     for (int i = relationships.size()-1; i >= 0; i--) {
  507.       if (relationships.get(i).x == nID || relationships.get(i).y == nID) {
  508.         int parID = int(relationships.get(i).x);
  509.         int chiID = int(relationships.get(i).y);
  510.  
  511.         getNodeByID(parID).tryRemoveChild(chiID);
  512.         getNodeByID(chiID).tryRemoveParent(parID);
  513.         relationships.remove(i);
  514.       }
  515.     }
  516.   }
  517.  
  518.   void breakSpecificRelationship(int pID, int cID) {
  519.     getNodeByID(pID).tryRemoveChild(cID);
  520.     getNodeByID(cID).tryRemoveParent(pID);
  521.     for (int i = relationships.size()-1; i >= 0; i--) {
  522.       if (relationships.get(i).x == pID && relationships.get(i).y == cID) {
  523.         relationships.remove(i);
  524.       }
  525.     }
  526.   }
  527.  
  528.   void clearAllRelationships() {
  529.     for (Node n : nodes) {
  530.       breakAllRelationshipsOfNode(n);
  531.     }
  532.   }
  533.  
  534.   Node checkLeftClickingNode() {
  535.     Node temp = null;
  536.  
  537.     float distance = width*height;
  538.     int nID = 0;
  539.  
  540.     for (Node n : nodes) {
  541.       if (dist(mouseX, mouseY, n.pos.x, n.pos.y) < distance) {
  542.         distance = dist(mouseX, mouseY, n.pos.x, n.pos.y);
  543.         nID = n.nodeID;
  544.       }
  545.     }
  546.  
  547.     if (distance <= nodeSize/2.0) {
  548.       temp = getNodeByID(nID);
  549.     }
  550.  
  551.     return temp;
  552.   }
  553.  
  554.   void selectNode() {
  555.     float distance = width*height;
  556.     int nID = 0;
  557.  
  558.     for (Node n : nodes) {
  559.       if (dist(mouseX, mouseY, n.pos.x, n.pos.y) < distance) {
  560.         distance = dist(mouseX, mouseY, n.pos.x, n.pos.y);
  561.         nID = n.nodeID;
  562.       }
  563.     }
  564.  
  565.     if (distance <= nodeSize/2.0) {
  566.       selected = getNodeByID(nID);
  567.     }
  568.   }
  569.  
  570.   void processSelection() {
  571.     if (selected == null) {
  572.       selectNode();
  573.     } else {
  574.       tryStartRelationship();
  575.       selected = null;
  576.     }
  577.   }
  578.  
  579.   void tryStartRelationship() {
  580.     float distance = width*height;
  581.     int nID = 0;
  582.  
  583.     for (Node n : nodes) {
  584.       if (dist(mouseX, mouseY, n.pos.x, n.pos.y) < distance) {
  585.         distance = dist(mouseX, mouseY, n.pos.x, n.pos.y);
  586.         nID = n.nodeID;
  587.       }
  588.     }
  589.  
  590.     if (distance <= nodeSize/2.0) {
  591.       createOrRemoveRelationship(selected.nodeID, nID);
  592.     }
  593.   }
  594.  
  595.   void render() {
  596.  
  597.     update();
  598.  
  599.     stroke(255);
  600.     fill(0, 0);
  601.     for (PVector r : relationships) {
  602.       Node parent = getNodeByID(int(r.x));
  603.       Node child = getNodeByID(int(r.y));
  604.  
  605.       constructCurve(this, parent, child);
  606.     }
  607.  
  608.     stroke(0);
  609.     for (Node n : nodes) {
  610.       color fColor;
  611.       if (n == selected) {
  612.         fColor = color(0, 0, 255);
  613.       } else {
  614.         fColor = color(255);
  615.       }
  616.       n.show(fColor);
  617.     }
  618.  
  619.     stroke(0);
  620.     for (PVector r : relationships) {
  621.       PVector p1 = getNodeByID(int(r.x)).pos;
  622.       PVector p2 = getNodeByID(int(r.y)).pos;
  623.  
  624.       PVector arrow = new PVector(p2.x-p1.x, p2.y-p1.y).normalize().mult(nodeSize/2.0);
  625.  
  626.       line(p1.x, p1.y, p1.x+arrow.x, p1.y+arrow.y);
  627.     }
  628.   }
  629.  
  630.   void update() {
  631.     if (deleting) {
  632.       deleteSelected();
  633.     }
  634.     if (movingNode != null) {
  635.       movingNode.pos = new PVector(mouseX - (mouseX % (nodeSize/2.0)), mouseY - (mouseY % (nodeSize/2.0)));
  636.       movingNode.updatePortPositions();
  637.     }
  638.   }
  639.  
  640.   void pulseQTYs() {
  641.     for (Node n : nodes) {
  642.       n.pulseToChildren();
  643.     }
  644.  
  645.     for (Node n : nodes) {
  646.       n.trueQTY = n.reserveQTY1 + n.reserveQTY2;
  647.       n.reserveQTY1 = 0;
  648.       n.reserveQTY2 = 0;
  649.     }
  650.   }
  651.  
  652.   void clearQTYs() {
  653.     for (Node n : nodes) {
  654.       n.trueQTY = 0;
  655.     }
  656.   }
  657.  
  658.   void deleteSelected() {
  659.     if (selected != null) {
  660.       for (int i = nodes.size()-1; i>=0; i--) {
  661.         if (selected.nodeID == nodes.get(i).nodeID) {
  662.           println("deleting");
  663.           breakAllRelationshipsOfNodeID(selected.nodeID);
  664.           selected = null;
  665.           nodes.remove(i);
  666.           deleting = false;
  667.           break;
  668.         }
  669.       }
  670.     }
  671.   }
  672.  
  673.   void scheduleDelete() {
  674.     deleting = true;
  675.   }
  676. }
  677.  
  678. void mousePressed() {
  679.   if (mouseButton == LEFT) {
  680.     if (nodeHandler.checkLeftClickingNode() == null) {
  681.       nodeHandler.addNode(1, mouseX, mouseY);
  682.     } else {
  683.       nodeHandler.movingNode = nodeHandler.checkLeftClickingNode();
  684.     }
  685.   }
  686.  
  687.   if (mouseButton == RIGHT) {
  688.     nodeHandler.processSelection();
  689.   }
  690. }
  691.  
  692. void mouseReleased() {
  693.   if (mouseButton == LEFT) {
  694.     nodeHandler.movingNode = null;
  695.   }
  696. }
  697.  
  698. void keyPressed() {
  699.   if (key == ' ') {
  700.     nodeHandler.pulseQTYs();
  701.   }
  702.   if (key == 'c') {
  703.     nodeHandler.clearQTYs();
  704.   }
  705.  
  706.   if (key == DELETE) {
  707.     println("Attempting Delete");
  708.     nodeHandler.scheduleDelete();
  709.   }
  710. }
  711.  
  712. PVector intersectionPoint(PVector origin, PVector departure, PVector destination, PVector approach) {
  713.   float x1 = origin.x;
  714.   float y1 = origin.y;
  715.   float x2 = destination.x;
  716.   float y2 = destination.y;
  717.   float dx = departure.x;
  718.   float dy = departure.y;
  719.   float ax = approach.x;
  720.   float ay = approach.y;
  721.  
  722.   float denominator = dx * ay - dy * ax;
  723.  
  724.   if (abs(denominator) < 0.00001) {
  725.     return null;
  726.   }
  727.  
  728.   float t = ((x2 - x1) * ay - (y2 - y1) * ax) / denominator;
  729.  
  730.   float intersectionX = x1 + t * dx;
  731.   float intersectionY = y1 + t * dy;
  732.  
  733.   println(intersectionX);
  734.   println(intersectionY);
  735.  
  736.   return new PVector(intersectionX, intersectionY);
  737. }
  738.  
  739.  
  740. void constructCurve(NHandler nh, Node p, Node c) {
  741.   PVector parentPos = p.pos;
  742.   PVector childPos = c.pos;
  743.  
  744.   String parentDirString = p.getSendingPortDirection(c);
  745.   String childDirString = c.getReceivingPortDirection(p);
  746.  
  747.   PVector parentRectLowerBound = null;
  748.   PVector parentRectUpperBound = null;
  749.   PVector childRectLowerBound = null;
  750.   PVector childRectUpperBound = null;
  751.  
  752.   PVector parentPort = null;
  753.   PVector childPort = null;
  754.  
  755.   switch(parentDirString) {
  756.   case "west":
  757.     parentRectUpperBound = new PVector(parentPos.x - nh.nodeSize/2.0, parentPos.y + nh.nodeSize / 2.0);
  758.     parentRectLowerBound = new PVector(parentPos.x - 10000, parentPos.y - nh.nodeSize / 2.0);
  759.     parentPort = new PVector(parentPos.x - nh.nodeSize / 2.0, parentPos.y);
  760.     break;
  761.   case "south":
  762.     parentRectUpperBound = new PVector(parentPos.x + nh.nodeSize / 2.0, parentPos.y + 10000);
  763.     parentRectLowerBound = new PVector(parentPos.x - nh.nodeSize / 2.0, parentPos.y + nh.nodeSize/2.0);
  764.     parentPort = new PVector(parentPos.x, parentPos.y + nh.nodeSize / 2.0);
  765.     break;
  766.   case "east":
  767.     parentRectUpperBound = new PVector(parentPos.x + 10000, parentPos.y + nh.nodeSize / 2.0);
  768.     parentRectLowerBound = new PVector(parentPos.x + nh.nodeSize/2.0, parentPos.y - nh.nodeSize / 2.0);
  769.     parentPort = new PVector(parentPos.x + nh.nodeSize / 2.0, parentPos.y);
  770.     break;
  771.   default:
  772.     parentRectUpperBound = new PVector(parentPos.x + nh.nodeSize / 2.0, parentPos.y + 10000);
  773.     parentRectLowerBound = new PVector(parentPos.x - nh.nodeSize / 2.0, parentPos.y + nh.nodeSize/2.0);
  774.     parentPort = new PVector(parentPos.x, parentPos.y + nh.nodeSize / 2.0);
  775.     break;
  776.   }
  777.  
  778.   switch(childDirString) {
  779.   case "west":
  780.     childRectUpperBound = new PVector(childPos.x - nh.nodeSize/2.0, childPos.y + nh.nodeSize / 2.0);
  781.     childRectLowerBound = new PVector(childPos.x - 10000, childPos.y - nh.nodeSize / 2.0);
  782.     childPort = new PVector(childPos.x - nh.nodeSize / 2.0, childPos.y);
  783.     break;
  784.   case "north":
  785.     childRectUpperBound = new PVector(childPos.x + nh.nodeSize / 2.0, childPos.y - nh.nodeSize/2.0);
  786.     childRectLowerBound = new PVector(childPos.x - nh.nodeSize / 2.0, childPos.y - 10000);
  787.     childPort = new PVector(childPos.x, childPos.y - nh.nodeSize / 2.0);
  788.     break;
  789.   case "east":
  790.     childRectUpperBound = new PVector(childPos.x + 10000, childPos.y + nh.nodeSize / 2.0);
  791.     childRectLowerBound = new PVector(childPos.x + nh.nodeSize/2.0, childPos.y - nh.nodeSize / 2.0);
  792.     childPort = new PVector(childPos.x + nh.nodeSize / 2.0, childPos.y);
  793.     break;
  794.   default:
  795.     childRectUpperBound = new PVector(childPos.x + nh.nodeSize / 2.0, childPos.y - nh.nodeSize/2.0);
  796.     childRectLowerBound = new PVector(childPos.x - nh.nodeSize / 2.0, childPos.y - 10000);
  797.     childPort = new PVector(childPos.x, childPos.y - nh.nodeSize / 2.0);
  798.     break;
  799.   }
  800.  
  801.   //rect(parentRectLowerBound.x, parentRectLowerBound.y, parentRectUpperBound.x-parentRectLowerBound.x, parentRectUpperBound.y-parentRectLowerBound.y);
  802.   //rect(childRectLowerBound.x, childRectLowerBound.y, childRectUpperBound.x-childRectLowerBound.x, childRectUpperBound.y-childRectLowerBound.y);
  803.  
  804.   PVector parentDir = new PVector(parentPort.x - parentPos.x, parentPort.y - parentPos.y).normalize();
  805.   PVector childDir = new PVector(childPort.x - childPos.x, childPort.y - childPos.y).normalize();
  806.  
  807.   boolean overlapping = !(parentRectUpperBound.x <= childRectLowerBound.x || childRectUpperBound.x <= parentRectLowerBound.x || parentRectUpperBound.y <= childRectLowerBound.y || childRectUpperBound.y <= parentRectLowerBound.y);
  808.   float iRate = p.itemRate();
  809.  
  810.   if (overlapping) {
  811.     PVector intersect = intersectionPoint(parentPort, parentDir, childPort, childDir);
  812.     PVector parentCP;
  813.     PVector childCP;
  814.     if (intersect == null) {
  815.       parentCP = new PVector(parentPos.x + parentDir.x * nh.nodeSize, parentPos.y + parentDir.y * nh.nodeSize);
  816.       childCP = new PVector(childPos.x + childDir.x * nh.nodeSize, childPos.y + childDir.y * nh.nodeSize);
  817.     } else {
  818.       parentCP = new PVector(intersect.x, intersect.y);
  819.       childCP = new PVector(intersect.x, intersect.y);
  820.     }
  821.  
  822.  
  823.     println(iRate);
  824.  
  825.  
  826.     float t = ((frameCount+((5000/iRate)))/5000.0*iRate)%1;
  827.     float x1 = bezierPoint(parentPort.x, parentCP.x, childCP.x, childPort.x, t);
  828.     float y1 = bezierPoint(parentPort.y, parentCP.y, childCP.y, childPort.y, t);
  829.     circle(x1, y1, 10);
  830.  
  831.     bezier(parentPort.x, parentPort.y, parentCP.x, parentCP.y, childCP.x, childCP.y, childPort.x, childPort.y);
  832.   } else {
  833.     PVector midPoint = new PVector(parentPort.x + (childPort.x - parentPort.x)/2.0, parentPort.y + (childPort.y - parentPort.y)/2.0);
  834.  
  835.     PVector parentTarget = new PVector(constrain(midPoint.x, parentRectLowerBound.x, parentRectUpperBound.x), constrain(midPoint.y, parentRectLowerBound.y, parentRectUpperBound.y));
  836.     PVector childTarget = new PVector(constrain(midPoint.x, childRectLowerBound.x, childRectUpperBound.x), constrain(midPoint.y, childRectLowerBound.y, childRectUpperBound.y));
  837.  
  838.     midPoint = new PVector(parentTarget.x + (childTarget.x - parentTarget.x)/2.0, parentTarget.y + (childTarget.y - parentTarget.y)/2.0);
  839.  
  840.     PVector parentCPDir = new PVector(parentTarget.x - midPoint.x, parentTarget.y - midPoint.y).normalize();
  841.     PVector childCPDir = new PVector(childTarget.x - midPoint.x, childTarget.y - midPoint.y).normalize();
  842.  
  843.     PVector parentIntersect = intersectionPoint(parentPort, parentDir, parentTarget, parentCPDir);
  844.     PVector childIntersect = intersectionPoint(childPort, childDir, childTarget, childCPDir);
  845.  
  846.     PVector parentCP;
  847.     PVector childCP;
  848.  
  849.     if (parentIntersect == null || childIntersect == null) {
  850.       parentCP = new PVector(parentPos.x + parentDir.x * nh.nodeSize, parentPos.y + parentDir.y * nh.nodeSize);
  851.       childCP = new PVector(childPos.x + childDir.x * nh.nodeSize, childPos.y + childDir.y * nh.nodeSize);
  852.     } else {
  853.       parentCP = new PVector(parentIntersect.x, parentIntersect.y);
  854.       childCP = new PVector(childIntersect.x, childIntersect.y);
  855.     }
  856.  
  857.     float t1 = (((frameCount+((5000/iRate)))/5000.0*iRate))%3;
  858.     float t2 = (((frameCount+((5000/iRate)))/5000.0*iRate)+1)%3;
  859.     float t3 = (((frameCount+((5000/iRate)))/5000.0*iRate)+2)%3;
  860.  
  861.     fill(255, 0);
  862.     bezier(parentPort.x, parentPort.y, parentCP.x, parentCP.y, parentCP.x, parentCP.y, parentTarget.x, parentTarget.y);
  863.     if (0<=t1 && t1<=1) {
  864.       float x1 = bezierPoint(parentPort.x, parentCP.x, parentCP.x, parentTarget.x, t1);
  865.       float y1 = bezierPoint(parentPort.y, parentCP.y, parentCP.y, parentTarget.y, t1);
  866.       circle(x1, y1, 10);
  867.     }
  868.  
  869.  
  870.     bezier(childPort.x, childPort.y, childCP.x, childCP.y, childCP.x, childCP.y, childTarget.x, childTarget.y);
  871.     if (0<=t2 && t2<=1) {
  872.       float x2 = bezierPoint(childTarget.x, childCP.x, childCP.x, childPort.x, t2);
  873.       float y2 = bezierPoint(childTarget.y, childCP.y, childCP.y, childPort.y, t2);
  874.       circle(x2, y2, 10);
  875.     }
  876.  
  877.     bezier(parentTarget.x, parentTarget.y, parentTarget.x + (parentTarget.x - parentCP.x), parentTarget.y + (parentTarget.y - parentCP.y), childTarget.x + (childTarget.x - childCP.x), childTarget.y + (childTarget.y - childCP.y), childTarget.x, childTarget.y);
  878.     if (0<=t3 && t3<=1) {
  879.       float x3 = bezierPoint(parentTarget.x, parentTarget.x + (parentTarget.x - parentCP.x)/2.0, childTarget.x + (childTarget.x - childCP.x)/2.0, childTarget.x, t3);
  880.       float y3 = bezierPoint(parentTarget.y, parentTarget.y + (parentTarget.y - parentCP.y)/2.0, childTarget.y + (childTarget.y - childCP.y)/2.0, childTarget.y, t3);
  881.       circle(x3, y3, 10);
  882.     }
  883.   }
  884. }
  885.  
Add Comment
Please, Sign In to add comment