Java program to generate Voronoi Diagrams of specified settings, even in high resolutions – tested for 64K with increased Java VM heap size – -Xmx8g option.

Main.java
// 2018 TheFlyingKeyboard and released under MIT License // theflyingkeyboard.net public class Main { public static void main(String[] args) { Voronoi voronoi = new Voronoi(15360, 8640, 2, 100, true); voronoi.generate(); } }
Point2D.java
// 2018 TheFlyingKeyboard and released under MIT License // theflyingkeyboard.net public class Point2D { private int x; private int y; public Point2D(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } }
Point3D.java
// 2018 TheFlyingKeyboard and released under MIT License // theflyingkeyboard.net public class Point3D { private int x; private int y; private int z; public Point3D(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public int getX() { return x; } public int getY() { return y; } public int getZ() { return z; } }
Voronoi.java
import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.File; import java.util.concurrent.ThreadLocalRandom; // 2018 TheFlyingKeyboard and released under MIT License // theflyingkeyboard.net public class Voronoi { private final int width; private final int height; private final double distanceOrder; private final int numberOfPoints; private final Point2D[] points; private final Point3D[] colors; private final int pointSize = 5; private final boolean drawPoints; private BufferedImage bufferedImage; public Voronoi(int width, int height, double distanceOrder, int numberOfPoints, boolean drawPoints) { this.width = width; this.height = height; this.distanceOrder = distanceOrder; this.numberOfPoints = numberOfPoints; this.drawPoints = drawPoints; points = new Point2D[numberOfPoints]; colors = new Point3D[numberOfPoints]; bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int i = 0; i < numberOfPoints; ++i) { points[i] = new Point2D(ThreadLocalRandom.current().nextInt(width), ThreadLocalRandom.current().nextInt(height)); colors[i] = new Point3D(ThreadLocalRandom.current().nextInt(255), ThreadLocalRandom.current().nextInt(255), ThreadLocalRandom.current().nextInt(255)); } } public void generate() { generateVoronoi(); try { ImageIO.write(bufferedImage, "png", new File("Voronoi " + width + "X" + height + " " + " distance order " + distanceOrder + " " + numberOfPoints + " points.png")); } catch (Exception e) { e.printStackTrace(); } } private void generateVoronoi() { //int counter = 0; int index; int[] imagePixelData = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { //System.out.println((counter / (double) (height * width)) * 100 + "%"); index = findClosestPoint(new Point2D(x, y)); imagePixelData[y * width + x] = (colors[index].getX() << 16) | (colors[index].getY() << 8) | colors[index].getZ(); //++counter; } } if (drawPoints) { drawPoints(); } } private void drawPoints() { for (int i = 0; i < numberOfPoints; ++i) { for (int y = -pointSize; y <= pointSize; ++y) { for (int x = -pointSize; x <= pointSize; ++x) { if (x * x + y * y <= pointSize * pointSize && x + points[i].getX() >= 0 && x + points[i].getX() < width && y + points[i].getY() >= 0 && y + points[i].getY() < height) { bufferedImage.setRGB(x + points[i].getX(), y + points[i].getY(), 0); } } } } } private int findClosestPoint(Point2D point) { int index = 0; double minDistance = distance(point, points[index]); double currentDistance; for (int i = 1; i < numberOfPoints; ++i) { currentDistance = distance(point, points[i]); if (currentDistance < minDistance) { minDistance = currentDistance; index = i; } } return index; } private double distance(Point2D pointA, Point2D pointB) { if (distanceOrder == 1.0d) { return Math.abs(pointA.getX() - pointB.getX()) + Math.abs(pointA.getY() - pointB.getY()); } if (distanceOrder == 2.0d) { return Math.sqrt((pointA.getX() - pointB.getX()) * (pointA.getX() - pointB.getX()) + (pointA.getY() - pointB.getY()) * (pointA.getY() - pointB.getY())); } return Math.pow(Math.pow(Math.abs(pointA.getX() - pointB.getX()), distanceOrder) + Math.pow(Math.abs(pointA.getY() - pointB.getY()), distanceOrder), (1.0d / distanceOrder)); } }
Java Voronoi Diagram