Created
January 21, 2012 17:31
-
-
Save thomcc/1653371 to your computer and use it in GitHub Desktop.
voronoi nose
This file contains 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
package com.thomcc.nine.level.gen; | |
import java.awt.Image; | |
import java.awt.geom.Point2D; | |
import java.awt.image.BufferedImage; | |
import java.awt.image.DataBufferInt; | |
import java.util.ArrayList; | |
import java.util.Random; | |
import javax.swing.ImageIcon; | |
import javax.swing.JOptionPane; | |
public class VoronoiNoise { | |
public final int pts; | |
public ArrayList<Point2D> points; | |
private Random _random; | |
public int w, h; | |
public VoronoiNoise(int width, int height, int pts) { | |
this.pts = pts; | |
w = width; | |
h = height; | |
_random = new Random(); | |
points = new ArrayList<Point2D>(); | |
for (int i = 0; i < pts; ++i) { | |
points.add(new Point2D.Double(_random.nextDouble() * width, _random.nextDouble() * height)); | |
} | |
} | |
public Point2D nearest(double x, double y) { | |
return nearest(new Point2D.Double(x, y)); | |
} | |
public Point2D nearest(Point2D p) { | |
Point2D min = points.get(0); | |
double mindist = p.distanceSq(min); | |
for (Point2D pt : points) { | |
double dist = p.distanceSq(pt); | |
if (mindist > dist) { | |
min = pt; | |
mindist = dist; | |
} | |
} | |
return min; | |
} | |
public double[][] calc() { | |
double[][] ary = new double[h][w]; | |
double maxd = -1; | |
for (int y = 0; y < h; ++y) { | |
for (int x = 0; x < w; ++x) { | |
Point2D p = new Point2D.Double(x, y); | |
Point2D n = nearest(p); | |
double d = p.distance(n); | |
if (d > maxd) maxd = d; | |
ary[y][x] = d; | |
} | |
} | |
for (int y = 0; y < h; ++y) { | |
for (int x = 0; x < w; ++x) { | |
ary[y][x] /= maxd; | |
} | |
} | |
return ary; | |
} | |
public static void main(String args[]) { | |
int width = 500; | |
int height = 500; | |
int points = 50; | |
VoronoiNoise vn = new VoronoiNoise(width, height, points); | |
double[][] grid = vn.calc(); | |
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); | |
int[] pix = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); | |
for (int y = 0; y < width; ++y) { | |
for (int x = 0; x < height; ++x) { | |
//int v = (int) (255.0 * Math.sqrt(grid[y][x])); | |
int v = (int) (255.0 * grid[y][x]); | |
if (v < 0) { | |
System.out.format("v is less than zero: %s\n", v); | |
v = 0; | |
} | |
if (v > 255) { | |
System.out.format("v is more than 255: %s\n", v); | |
v = 255; | |
} | |
int c = v << 16 | v << 8 | v; | |
pix[x + y*width] = c; | |
} | |
} | |
JOptionPane.showMessageDialog( | |
null, | |
null, | |
"vnoise", | |
JOptionPane.YES_NO_OPTION, | |
new ImageIcon(img.getScaledInstance(img.getWidth() * 1, | |
img.getHeight() * 1, Image.SCALE_AREA_AVERAGING))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment