从中心点分布形状

时间:2015-03-17 10:14:52

标签: java random processing

我试图改进我的方法,从中心点(它具有更有机的外观)在网格表面上以相同的足迹布置数千个形状的位置。网格表面意味着邻居之间的间距相等但我不想通过选择随机x和y坐标(或者在这种情况下x和z为I&)来创建类似补丁的模式。 #39; m在3个维度工作)。我现在的工作原理,但是当我从2,000个物体开始向上移动时,速度非常慢。有更快的方法吗?我像我说的那样避免了补丁效应,以及均匀的循环传播。现在的分布非常像城市一样完美,但是太慢了。

我对整个功能进行了评论,希望它能彻底解释所有内容:

ArrayList buildingCoords; // stores the co-ordinates of occupied spaces
int w = 50 // Footprint dimensions. Width and depth.

PVector generateNewBuildingPosition(PVector coord) {
    float sW = 30; // gap between shapes
    // Starting at a coordinate of 0,0 if this is our 1st go
    // (PVector coord initially feeds 0,0)
    // or the last coordinate that was already taken
    // (this loops with the last coordinate if it fails)
    // we check one of the four spaces next to us with
    // the roll of a dice (in a way...)
    float randomX = random(0,15);
    float randomZ = random(0,15);
    if (randomX >= 10) { 
      randomX = w + sW; 
    } else if (randomX >= 5) { 
      randomX = (w + sW) * -1;
    } else {
      randomX = 0;
    }
      if (randomZ >= 10) { 
      randomZ = w + sW; 
    } else if (randomX >= 5) { 
      randomZ = (w + sW) * -1;
    } else {
      randomZ = 0;
    }

    // We've picked our direction.
    // We have a PVector that acts as a marker for where we're
    // placing. Adding or subtracting the movement of each
    // attempt, one at a time, means the shapes spreads out 
    // more organically from the centre rather than trying
    // to distribute each shape as a random patch.
    PVector newDirection = new PVector(randomX, 0, randomZ);
    coord.add(newDirection);
    // Our marker moves to the new spot, we check if it exists.
    // If it doesn't, we confirm it as this shape's anchor spot.
    // If it does, we loop this function again, feeding it where our
    // marker is.
    if(buildingCoords.contains(coord)) {
      generateNewBuildingPosition(coord);
    } else {
      // add this PVector to the arrayList
      buildingCoords.add(coord);
    }
    // Return the coordinates that just succeeded.
    return coord;
  }

1 个答案:

答案 0 :(得分:1)

此代码基本上立即处理200,000。我不得不猜测一些细节,但它应该接近你想要的东西。

public class Test {

    static Map<Integer, Vector3> buildingCoords;
    public static void main(String[] args) {
        buildingCoords = new HashMap();

        Vector3 start = new Vector3(0,0,0);

        for (int i = 0; i < 200000; i++)
            start = generateNewBuildingPosition(start);

        System.out.print("Done");

    }

    static Vector3 generateNewBuildingPosition(Vector3 coord) {
        int w = 50; // Footprint dimensions. Width and depth.
        float sW = 30; // gap between shapes
        // Starting at a coordinate of 0,0 if this is our 1st go
        // (PVector coord initially feeds 0,0)
        // or the last coordinate that was already taken
        // (this loops with the last coordinate if it fails)
        // we check one of the four spaces next to us with
        // the roll of a dice (in a way...)
        float randomX = (float)random() * 15;
        float randomZ = (float)random() * 15;
        if (randomX >= 10) randomX = w + sW;
        else if (randomX >= 5) randomX = (w + sW) * -1;
        else randomX = 0;

        if (randomZ >= 10) randomZ = w + sW;
        else if (randomX >= 5) randomZ = (w + sW) * -1;
        else randomZ = 0;


        // We've picked our direction.
        // We have a PVector that acts as a marker for where we're
        // placing. Adding or subtracting the movement of each
        // attempt, one at a time, means the shapes spreads out
        // more organically from the centre rather than trying
        // to distribute each shape as a random patch.
        Vector3 newDirection = new Vector3(randomX, 0, randomZ);
        coord.add(newDirection);
        // Our marker moves to the new spot, we check if it exists.
        // If it doesn't, we confirm it as this shape's anchor spot.
        // If it does, we loop this function again, feeding it where our
        // marker is.
        if(buildingCoords.containsKey(coord.hashCode())) {
            generateNewBuildingPosition(coord);
        } else {
            // add this PVector to the arrayList
            buildingCoords.put(coord.hashCode(), coord);
        }
        // Return the coordinates that just succeeded.
        return coord;
    }
}

class Vector3 {

    float x, y, z; // package-private variables; nice encapsulation if you place this in a maths package of something

    Vector3(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Vector3 add(Vector3 vector) {
        x += vector.x;
        y += vector.y;
        z += vector.z;
        return this; // method chaining would be very useful
    }

    @Override
    public int hashCode(){
        return Float.hashCode(x + y + z);
    }

}

编辑:如图所示的hashCode不是很健全,可能会导致问题。你应该阅读:Hashing 2D, 3D and nD vectors