Android画布。如何在随机位置设置圆圈?

时间:2016-12-23 19:28:51

标签: java android canvas collision-detection

生成代码并将位置x y保存到HashMap并检查碰撞两个圆圈;

        HashMap<Integer, Float> posX = new HashMap<>();
        HashMap<Integer, Float> posY = new HashMap<>();

        int numberOfCircle = 8;

        for(int i=0; i < numberOfCircle; i ++){

           // boolean flag = false;
            while (true){

                float x =random.nextInt(width - raduis/2) + raduis/2f;
                float y =random.nextInt(height - raduis/2) + raduis/2f;

                if(!posX.containsValue(x) && !posY.containsValue(y)){

                    if(i == 0){

                        posX.put(i, x);
                        posY.put(i, y);
                        break;
                    }
                    if(i > 0){

                      double distance = Math.sqrt(((posX.get(i - 1) - x) * (posX.get(i - 1) - x)) + ((posY.get(i - 1) - y) * ( posY.get(i - 1) - y)));

                        if (distance > raduis+raduis) {

                            posX.put(i, x);
                            posY.put(i, y);
                            Log.d(TAG, i + " xPos=" + posX.get(i) + " yPos=" + posY.get(i) + " distance=" + distance);
                            break;
                        }

                        if(numberOfCircle == posX.size()) break;
                    }

                }
            }

        }

此代码仅在圆圈数= 2时有效;但是当圈数> 2我发生了碰撞;如何在HashMap中检查每个当前生成的位置?

例如: xPos = {5,10,3} yPos = {10,33,5}

生成位置x = 6,y = 10; 使用Map中的所有位置计算x = 6,y = 10之间的距离。如果距离<半径+半径产生新位置,而距离>半径+半径;

更新========================&gt;

我的代码就像 enter image description here

我想要这样

enter image description here

输出:当前生成位置(X,Y)与先前位置(X,Y)之间的距离相等。我想检查当前生成的x,y与HashMap中所有添加的位置。

D/DEBUG DATA ===>: 1 xPos=432.0 yPos=411.0 distance=390.6430595825299
D/DEBUG DATA ===>: 2 xPos=316.0 yPos=666.0 distance=280.1446055165082
D/DEBUG DATA ===>: 3 xPos=244.0 yPos=83.0 distance=587.4291446634223
D/DEBUG DATA ===>: 4 xPos=214.0 yPos=551.0 distance=468.96055271205915
D/DEBUG DATA ===>: 5 xPos=76.0 yPos=1011.0 distance=480.2540994098853
D/DEBUG DATA ===>: 6 xPos=289.0 yPos=868.0 distance=256.55019002136794
D/DEBUG DATA ===>: 7 xPos=494.0 yPos=988.0 distance=237.53947040439405

P.s抱歉这么差的英语。

3 个答案:

答案 0 :(得分:0)

也许接近这个的东西会奏效吗?我不完全确定它是你想要的还是它会有所帮助,但为了清晰起见,我做了一个快速重写。

HashMap<Integer, Integer> posX = new HashMap<>();
HashMap<Integer, Integer> posY = new HashMap<>();

final int circlesToPlace = 8;

for(int i = 0 ; i < circlesToPlace ; i++){

    // boolean flag = false;
     while (true){
         final int x = ThreadLocalRandom.current().nextInt((radius/2f), width + 1);
         final int y = ThreadLocalRandom.current().nextInt((radius/2f), height + 1);

        // Iterate over all other positions to ensure no circle intersects with
        // the new circle.
        for (int index = 0 ; index < posX.size() ; index++) {
            // Calculate distance where d = sqrt((x2 - x1)^2 + (y2 - y1)^2)
            final int otherX = posX.get(index);
            final int otherY = posY.get(index);

            int differenceX = otherX - x;
            differenceX *= differenceX;

            int differenceY = otherY - y;
            differenceY *= differenceY;

            final double distance = Math.sqrt(differenceX + differenceY);


            if (distance > (radius * 2)) {
                posX.put(i, x);
                posY.put(i, y);
                Log.d(TAG, i + " xPos=" + posX.get(i) + " yPos=" + posY.get(i) + " distance=" + distance);
                break;
            }
        }
     }
 }

答案 1 :(得分:0)

我的变种。你不需要做sqrt比较距离,你可以改为常数(d2在我的情况下)。

    Random random = new Random();
    int numberOfCircle = 8, width = 400, height = 300;
    int diameter = 51;
    final float radius = diameter * 0.5f;
    final float d2 = diameter * diameter;

    List<Float> posX = new ArrayList<>(numberOfCircle);
    List<Float> posY = new ArrayList<>(numberOfCircle);

    while (posX.size() < numberOfCircle) {  // till enough generated

        // generate new coordinates
        float x = random.nextInt(width - diameter) + radius;
        float y = random.nextInt(height - diameter) + radius;

        System.out.printf("Generated [%3.3f, %3.3f] ... ", x, y);

        // verify it does not overlap/touch with previous circles
        int j = 0;
        while (j < posX.size()) {
            float dx = posX.get(j) - x, dy = posY.get(j) - y;
            float diffSquare = (dx * dx) + (dy * dy);
            if (diffSquare <= d2) break;
            ++j;
        }

        // generate another pair of coordinates, if it does touch previous
        if (j != posX.size()) {
            System.out.println("collided.");
            continue;
        }
        System.out.println("added.");

        // not overlapping/touch, add as new circle
        posX.add(x);
        posY.add(y);
    } // while (posX.size() < numberOfCircle)

答案 2 :(得分:0)

我这样解决

#pragma