Java 程序生成的Voronoi道路
我正在使用一个受启发的噪波函数来尝试生成道路。(见下文)Java 程序生成的Voronoi道路,java,random,noise,voronoi,procedural-generation,Java,Random,Noise,Voronoi,Procedural Generation,我正在使用一个受启发的噪波函数来尝试生成道路。(见下文) 公共类voronoise{ 专用静态最终双SQRT_2=1.4142135623730950488; 私人静态最终双SQRT_3=1.7320508075688772935; 私人长种子; 私密短距离法; 私人最终双频; 公共Voronoise(长种子、双频、短距离法){ 这个种子=种子; this.distance方法=distance方法; 这个频率=频率; } 专用双getDistance(双xDist、双zDist){ 开关(距离
公共类voronoise{
专用静态最终双SQRT_2=1.4142135623730950488;
私人静态最终双SQRT_3=1.7320508075688772935;
私人长种子;
私密短距离法;
私人最终双频;
公共Voronoise(长种子、双频、短距离法){
这个种子=种子;
this.distance方法=distance方法;
这个频率=频率;
}
专用双getDistance(双xDist、双zDist){
开关(距离法){
案例0://欧几里德-长度
返回Math.sqrt(xDist*xDist+zDist*zDist)/sqrt_2;
案例1://???
返回xDist+zDist;
案例2://???
返回Math.pow(Math.E,Math.sqrt(xDist*xDist+zDist*zDist)/sqrt_2)/Math.E;
案例3://曼哈顿
返回Math.abs(xDist)+Math.abs(zDist);
案例4://切比切夫
返回Math.max(Math.abs(xDist)、Math.abs(zDist));
案例5://MINKOVSKI
返回Math.pow(Math.pow(Math.abs(xDist),Math.PI)+Math.pow(Math.abs(zDist),Math.PI),(1/Math.PI));
案例6://MINKOVSKI4
返回Math.pow(xDist*xDist*xDist*xDist+zDist*zDist*zDist*zDist,0.25);
违约:
返回1.0;
}
}
专用双getDistance(双xDist、双yDist、双zDist){
开关(距离法){
案例0:
返回Math.sqrt(xDist*xDist+yDist*yDist+zDist*zDist)/sqrt_3;
案例1:
返回xDist+yDist+zDist;
违约:
返回1.0;
}
}
公共短getDistanceMethod(){
返回距离法;
}
公共长getSeed(){
返回种子;
}
公共双噪声(双x,双z){
x*=频率;
z*=频率;
int xInt=(x>0?(int)x:(int)x-1);
int-zInt=(z>0?(int)z:(int)z-1);
双重正念者=32000000.0;
双xCandidate=0;
双zCandidate=0;
双xCandidate2=0;
双zCandidate2=0;
随机随机=新随机(种子);
long xSeed=random.nextLong();
long zSeed=random.nextLong();
对于(int-zCur=zInt-2;zCur.0?(int)y:(int)y-1);
int-zInt=(z>0?(int)z:(int)z-1);
双重正念者=32000000.0;
双xCandidate=0;
双yCandidate=0;
双zCandidate=0;
随机rand=新随机(种子);
对于(intzcur=zInt-2;zCur>13)^n;
返回1.0-((双)((n*(n*n*60493+19990303)+1376312589)和0x7fffffff)/1073741824.0);
}
}
正如你所见,我一直在计算距离21——第一个点减去第二个最近点的距离。我一直在用这个和欧几里得距离计算来生成一个噪声贴图。以下是我得到的:
然后,我一直在检查噪音是否低于某个值(黑色),并使用该值设置道路。一个问题是,一些电池是黑色的,一些比道路更黑,导致大量道路。此外,道路宽度超过1个单位,这对于我来说是不可接受的
下面是不同类型的voronoi噪声的图表。
我想知道是否有一种算法可以按程序产生这样的噪音
除了给定一个种子、一个频率和一个点(x,y)之外,无论顶点是否通过该点,它都将返回true或false。
创建线条
作为最后手段,我将使用重复的、静态的图像
编辑:我通过检查该点周围的4个点是否有不同的最近点,成功地完成了我设定的任务
我仍然想知道这是否可能是其他不太密集的方式
public class VoronoiNoise {
private static final double SQRT_2 = 1.4142135623730950488;
private static final double SQRT_3 = 1.7320508075688772935;
private long seed;
private short distanceMethod;
private final double frequency;
public VoronoiNoise(long seed, double frequency, short distanceMethod) {
this.seed = seed;
this.distanceMethod = distanceMethod;
this.frequency = frequency;
}
private double getDistance(double xDist, double zDist) {
switch(distanceMethod) {
case 0: //EUCLIDIAN - Length
return Math.sqrt(xDist * xDist + zDist * zDist) / SQRT_2;
case 1: //???
return xDist + zDist;
case 2: //???
return Math.pow(Math.E, Math.sqrt(xDist * xDist + zDist * zDist) / SQRT_2)/Math.E;
case 3: //MANHATTAN
return Math.abs(xDist) + Math.abs(zDist);
case 4: //CHEBYCHEV
return Math.max(Math.abs(xDist), Math.abs(zDist));
case 5: //MINKOVSKI
return Math.pow(Math.pow(Math.abs(xDist), Math.PI) + Math.pow(Math.abs(zDist), Math.PI), (1 / Math.PI));
case 6: //MINKOVSKI4
return Math.pow(xDist*xDist*xDist*xDist+zDist*zDist*zDist*zDist,0.25);
default:
return 1.0;
}
}
private double getDistance(double xDist, double yDist, double zDist) {
switch(distanceMethod) {
case 0:
return Math.sqrt(xDist * xDist + yDist * yDist + zDist * zDist) / SQRT_3;
case 1:
return xDist + yDist + zDist;
default:
return 1.0;
}
}
public short getDistanceMethod() {
return distanceMethod;
}
public long getSeed() {
return seed;
}
public double noise(double x, double z) {
x *= frequency;
z *= frequency;
int xInt = (x > .0? (int)x: (int)x - 1);
int zInt = (z > .0? (int)z: (int)z - 1);
double minDist = 32000000.0;
double xCandidate = 0;
double zCandidate = 0;
double xCandidate2 = 0;
double zCandidate2 = 0;
Random random = new Random(seed);
long xSeed = random.nextLong();
long zSeed = random.nextLong();
for(int zCur = zInt - 2; zCur <= zInt + 2; zCur++) {
for(int xCur = xInt - 2; xCur <= xInt + 2; xCur++) {
double xPos = xCur + valueNoise2D(xCur, zCur, xSeed);
double zPos = zCur + valueNoise2D(xCur, zCur, zSeed);
double xDist = xPos - x;
double zDist = zPos - z;
double dist = xDist * xDist + zDist * zDist;
if(dist < minDist) {
xCandidate2 = xCandidate;
zCandidate2 = zCandidate;
xCandidate = xPos;
zCandidate = zPos;
minDist = dist;
}
}
}
double xDist = xCandidate - x;
double zDist = zCandidate - z;
//return getDistance(xDist, zDist);
return getDistance(xCandidate2 - x, zCandidate2 - z) - getDistance(xCandidate - x, zCandidate - z);
}
public double noise(double x, double y, double z) {
x *= frequency;
y *= frequency;
z *= frequency;
int xInt = (x > .0? (int)x: (int)x - 1);
int yInt = (y > .0? (int)y: (int)y - 1);
int zInt = (z > .0? (int)z: (int)z - 1);
double minDist = 32000000.0;
double xCandidate = 0;
double yCandidate = 0;
double zCandidate = 0;
Random rand = new Random(seed);
for(int zCur = zInt - 2; zCur <= zInt + 2; zCur++) {
for(int yCur = yInt - 2; yCur <= yInt + 2; yCur++) {
for(int xCur = xInt - 2; xCur <= xInt + 2; xCur++) {
double xPos = xCur + valueNoise3D (xCur, yCur, zCur, seed);
double yPos = yCur + valueNoise3D (xCur, yCur, zCur, rand.nextLong());
double zPos = zCur + valueNoise3D (xCur, yCur, zCur, rand.nextLong());
double xDist = xPos - x;
double yDist = yPos - y;
double zDist = zPos - z;
double dist = xDist * xDist + yDist * yDist + zDist * zDist;
if(dist < minDist) {
minDist = dist;
xCandidate = xPos;
yCandidate = yPos;
zCandidate = zPos;
}
}
}
}
double xDist = xCandidate - x;
double yDist = yCandidate - y;
double zDist = zCandidate - z;
return getDistance(xDist, yDist, zDist);
}
public void setDistanceMethod(short distanceMethod) {
this.distanceMethod = distanceMethod;
}
public void setSeed(long seed) {
this.seed = seed;
}
public static double valueNoise2D (int x, int z, long seed) {
long n = (1619 * x + 6971 * z + 1013 * seed) & 0x7fffffff;
n = (n >> 13) ^ n;
return 1.0 - ((double)((n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
public static double valueNoise3D (int x, int y, int z, long seed) {
long n = (1619 * x + 31337 * y + 6971 * z + 1013 * seed) & 0x7fffffff;
n = (n >> 13) ^ n;
return 1.0 - ((double)((n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
}