Point in polygon optimization
in
Programming Questions
•
1 year ago
I wrote a sketch where I can select among regular polygons on the screen accurately with the mouse. Right now the selection is done with the mouse, but in a future sketch it will probably be performed many times by an AI planning tessellations. The code highlighted in red below works but I want to make sure it is optimized before I write something that will use that test many times.
On a side note, the method below (again, in red) is the only way I could think of to accurately select the area of a regular polygon. If someone knows of a better way I'd love to know:
- float unit = 50;
- boolean somethingSelected = false;
- int selected = 0;
- ArrayList<Polygon> polys = new ArrayList<Polygon>();
- void setup() {
- size(800, 400);
- smooth();
- polys.add(new Polygon(-HALF_PI, width/5, height/2, 3));
- polys.add(new Polygon(-HALF_PI, width/2, height/2, 4));
- polys.add(new Polygon(-HALF_PI, width-width/5, height/2, 5));
- }
- void draw() {
- background(255);
- for (int i = 0; i < polys.size(); i++) {
- if (somethingSelected && selected == i) fill(255, 0, 0);
- else fill(255);
- Polygon pGet = polys.get(i);
- float rad = (unit/2)/sin(PI/pGet.verts);
- beginShape();
- for (int j = 0; j < pGet.verts; j++) {
- vertex(pGet.x+cos(pGet.rot+TWO_PI/pGet.verts*j)*rad,
- pGet.y+sin(pGet.rot+TWO_PI/pGet.verts*j)*rad);
- }
- endShape(CLOSE);
- }
- }
- class Polygon {
- float rot, x, y;
- int verts;
- Polygon(float inRo, float inX, float inY, int inVe) {
- rot = inRo;
- x = inX;
- y = inY;
- verts = inVe;
- }
- }
- void mousePressed() {
- /* Determine which polygon is selected 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 */
- somethingSelected = false;
- for (int i = 0; i < polys.size(); i++) {
- Polygon pGet = polys.get(i);
- float rad = (unit/2)/sin(PI/pGet.verts);
- ArrayList<Float> vx = new ArrayList<Float>();
- ArrayList<Float> vy = new ArrayList<Float>();
- for (int j = 0; j < pGet.verts; j++) {
- vx.add(pGet.x+cos(pGet.rot+TWO_PI/pGet.verts*j)*rad);
- vy.add(pGet.y+sin(pGet.rot+TWO_PI/pGet.verts*j)*rad);
- }
- float sideA = sqrt(sq(mouseX-vx.get(0))+sq(mouseY-vy.get(0)));
- float sideB = sqrt(sq(mouseX-vx.get(pGet.verts-1))+sq(mouseY-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(mouseX-vx.get(j))+sq(mouseY-vy.get(j)));
- sideB = sqrt(sq(mouseX-vx.get(j+1))+sq(mouseY-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) {
- selected = i;
- somethingSelected = true;
- break;
- }
- }
- }
- void keyPressed() {
- if (somethingSelected && key == CODED) {
- if (keyCode == UP) polys.get(selected).verts++;
- if (keyCode == DOWN && polys.get(selected).verts > 3) polys.get(selected).verts--;
- }
- }
1