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);
}
}