Mysterious annoying error, IndexOutOfBounds
in
Programming Questions
•
1 year ago
I have continued working on the polygon sketch I shared here a few times but have come up against an error I cannot figure out. To trigger the error:
- Click on a polygon. It will make "selectors" appear, clicking on one of them adds a new polygon in that direction
- If that new polygon (or any new polygon after) is selected and then the mouse clicks on an area that is not a "selector" the error happens
- The error does not happen after new polygons are added if the mouse clicked on a "selector"
Unfortunately Processing doesn't tell me which line caused the error, and I can't seem to figure it out. If anyone could help me figure it out I'd really appreciate it. Some side notes about the sketch:
- Right now if a new polygon is added it is correctly placed. However, if vertices are added / removed it no longer is tangent to its parent polygon. This is not really an error / problem so much as I have not implemented a correction to it yet as I am distracted by the error
- I have not optimized all of the code by the suggestions from earlier threads on this sketch (I promise I will, the suggestions were wonderful, thank you again to everyone that helped)
- float unit = 50;
- float selUnit = unit/4;
- int selected = -1;
- ArrayList<Polygon> polys = new ArrayList<Polygon>();
- ArrayList<Float> selAng = new ArrayList<Float>();
- ArrayList<Float> selX = new ArrayList<Float>();
- ArrayList<Float> selY = new ArrayList<Float>();
- void setup() {
- size(400, 400);
- smooth();
- polys.add(new Polygon(-HALF_PI, width/2, height/2, 3));
- }
- void draw() {
- background(255);
- for (int i = 0; i < polys.size(); i++) {
- Polygon pGet = polys.get(i);
- if (selected == i) {
- fill(255, 0, 0);
- for (int j = 0; j < selAng.size(); j++) ellipse(selX.get(j), selY.get(j), selUnit, selUnit);
- }
- else fill(192, 128);
- beginShape();
- for (int j = 0; j < pGet.verts; j++) vertex(pGet.vx.get(j), pGet.vy.get(j));
- endShape(CLOSE);
- }
- }
- class Polygon {
- float rad, rot, x, y;
- int verts;
- ArrayList<Float> vx = new ArrayList<Float>();
- ArrayList<Float> vy = new ArrayList<Float>();
- Polygon(float inRo, float inX, float inY, int inVe) {
- rot = inRo;
- x = inX;
- y = inY;
- verts = inVe;
- rad = (unit/2)/sin(PI/verts);
- for (int i = 0; i < verts; i++) {
- float vertAngle = rot+TWO_PI/verts*i;
- vx.add(x+cos(vertAngle)*rad);
- vy.add(y+sin(vertAngle)*rad);
- }
- }
- void updateVerts() {
- rad = (unit/2)/sin(PI/verts);
- vx.clear();
- vy.clear();
- for (int i = 0; i < verts; i++) {
- float vertAngle = rot+TWO_PI/verts*i;
- vx.add(x+cos(vertAngle)*rad);
- vy.add(y+sin(vertAngle)*rad);
- }
- }
- }
- boolean pointInPolygon(float x, float y, int id) {
- /* Determine if a point is in a polygon by pretending that neighboring polygon
- vertices are connected to the mouse as triangles and summing the internal angles.
- If the sum is about TWO_PI that polygon is selected */
- Polygon pGet = polys.get(id);
- float sideA = sqrt(sq(x-pGet.vx.get(0))+sq(y-pGet.vy.get(0)));
- float sideB = sqrt(sq(x-pGet.vx.get(pGet.verts-1))+sq(y-pGet.vy.get(pGet.verts-1)));
- float totalAng = acos((sq(sideA)+sq(sideB)-sq(unit))/(2*sideA*sideB));
- for (int j = 0; j < pGet.verts-1; j++) {
- sideA = sqrt(sq(x-pGet.vx.get(j))+sq(y-pGet.vy.get(j)));
- sideB = sqrt(sq(x-pGet.vx.get(j+1))+sq(y-pGet.vy.get(j+1)));
- totalAng += acos((sq(sideA)+sq(sideB)-sq(unit))/(2*sideA*sideB));
- }
- if (totalAng > TWO_PI-0.01 && totalAng < TWO_PI+0.01) return true;
- else return false;
- }
- void setSelectors() {
- selAng.clear();
- selX.clear();
- selY.clear();
- Polygon pGet = polys.get(selected);
- for (int i = 0; i < pGet.verts; i++) {
- float getAngle = pGet.rot+TWO_PI/pGet.verts*i+PI/pGet.verts;
- float getRad = sqrt(sq(pGet.rad)-sq(unit/2))+selUnit;
- float newX = pGet.x+cos(getAngle)*getRad;
- float newY = pGet.y+sin(getAngle)*getRad;
- boolean inPolygon = false;
- for (int j = 0; j < polys.size(); j++) {
- if (pointInPolygon(newX, newY, j)) {
- inPolygon = true;
- break;
- }
- }
- if (!inPolygon) {
- selAng.add(getAngle);
- selX.add(newX);
- selY.add(newY);
- }
- }
- }
- void mousePressed() {
- /* Determine if a polygon adding selector was selected */
- if (selected != -1) {
- Polygon pGet = polys.get(selected);
- for (int i = 0; i < pGet.verts; i++) {
- if (sqrt(sq(mouseX-selX.get(i))+sq(mouseY-selY.get(i))) < selUnit/2) {
- float getRad = sqrt(sq(pGet.rad)-sq(unit/2))*2;
- float getAngle = selAng.get(i);
- float newAngle = pGet.rot+TWO_PI/((pGet.verts%2)+1);
- float newX = pGet.x+cos(getAngle)*getRad;
- float newY = pGet.y+sin(getAngle)*getRad;
- polys.add(new Polygon(newAngle, newX, newY, pGet.verts));
- break;
- }
- }
- }
- /* Determine if a polygon was selected */
- selected = -1;
- for (int i = 0; i < polys.size(); i++) {
- if (pointInPolygon(mouseX, mouseY, i)) {
- selected = i;
- setSelectors();
- break;
- }
- }
- }
- void keyPressed() {
- if (selected != -1 && key == CODED) {
- if (keyCode == UP) {
- Polygon pGet = polys.get(selected);
- pGet.verts++;
- pGet.updateVerts();
- setSelectors();
- }
- if (keyCode == DOWN && polys.get(selected).verts > 3) {
- Polygon pGet = polys.get(selected);
- pGet.verts--;
- pGet.updateVerts();
- setSelectors();
- }
- }
- }
1