Last active
January 2, 2023 18:14
-
-
Save radiovisual/c8b2f33a660828dec6c94e2260ec70f6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| PImage imageMask; | |
| ArrayList<ArrayList<PVector>> polygons; | |
| final int MAX_RECURSION_DEPTH = 1000; | |
| void setup() { | |
| size(512, 512); | |
| imageMask = loadImage("imageMask.png"); | |
| // Create an empty array to store the polygons | |
| polygons = new ArrayList<ArrayList<PVector>>(); | |
| // Iterate through each pixel in the image | |
| for (int y = 0; y < imageMask.height; y++) { | |
| for (int x = 0; x < imageMask.width; x++) { | |
| // If the pixel is black and hasn't been visited yet, start a new polygon and add it to the polygons array | |
| if (brightness(imageMask.get(x, y)) == 0 && brightness(imageMask.get(x, y)) != 255) { | |
| ArrayList<PVector> polygon = new ArrayList<PVector>(); | |
| polygons.add(polygon); | |
| tracePolygon(polygon, x, y, 0); | |
| } | |
| } | |
| } | |
| // Smooth the polygon outlines | |
| smoothPolygons(); | |
| } | |
| void draw() { | |
| background(255); | |
| for (ArrayList<PVector> polygon : polygons) { | |
| beginShape(); | |
| fill(random(255), 0, 0); | |
| for (PVector point : polygon) { | |
| vertex(point.x, point.y); | |
| } | |
| endShape(CLOSE); | |
| } | |
| } | |
| void tracePolygon(ArrayList<PVector> polygon, int x, int y, int recursionDepth) { | |
| // Add the current point to the polygon | |
| polygon.add(new PVector(x, y)); | |
| // Set the current pixel to white to mark it as visited | |
| imageMask.set(x, y, color(255)); | |
| // Check the pixels around the current point | |
| for (int dx = -1; dx <= 1; dx++) { | |
| for (int dy = -1; dy <= 1; dy++) { | |
| // Skip the current point and pixels outside the image | |
| if (dx == 0 && dy == 0 || x + dx < 0 || x + dx >= imageMask.width || y + dy < 0 || y + dy >= imageMask.height) { | |
| continue; | |
| } | |
| // If the pixel is black and hasn't been visited yet, recursively trace the polygon from that point | |
| if (brightness(imageMask.get(x + dx, y + dy)) == 0 && brightness(imageMask.get(x + dx, y + dy)) != 255) { | |
| // Check if the recursion depth is too large | |
| if (recursionDepth > MAX_RECURSION_DEPTH) { | |
| // If the recursion depth is too large, add a point halfway between the current point and the next point to the polygon | |
| PVector p1 = polygon.get(polygon.size() - 1); | |
| PVector p2 = new PVector(x + dx, y + dy); | |
| PVector p3 = p1.lerp(p2, 0.5); | |
| polygon.add(p3); | |
| } else { | |
| // If the recursion depth is not too large, recursively trace the polygon from the next point | |
| tracePolygon(polygon, x + dx, y + dy, recursionDepth + 1); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void smoothPolygons() { | |
| // Iterate through each polygon | |
| for (ArrayList<PVector> polygon : polygons) { | |
| // Create a new array to store the smoothed points | |
| ArrayList<PVector> smoothedPolygon = new ArrayList<PVector>(); | |
| // Iterate through each point in the polygon | |
| for (int i = 0; i < polygon.size(); i++) { | |
| PVector p1 = polygon.get(i); | |
| PVector p2 = polygon.get((i + 1) % polygon.size()); | |
| PVector p3 = polygon.get((i + 2) % polygon.size()); | |
| // Compute the angle between the three points | |
| float angle = abs(PVector.angleBetween(p2.sub(p1), p3.sub(p2))); | |
| // If the angle is acute, add the middle point to the smoothed polygon | |
| if (angle < PI / 2) { | |
| smoothedPolygon.add(p2); | |
| } else { | |
| // If the angle is obtuse, add a new point halfway between the middle point and the point with the smallest distance | |
| PVector p4 = p2.lerp(dist(p1.x, p1.y, p2.x, p2.y) < dist(p2.x, p2.y, p3.x, p3.y) ? p1 : p3, 0.5); | |
| smoothedPolygon.add(p4); | |
| } | |
| } | |
| // Replace the original polygon with the smoothed polygon | |
| polygon.clear(); | |
| polygon.addAll(smoothedPolygon); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment