BridsonのアルゴリズムPoisson-DiskSamplingの実装が無限ループに陥っているようです

GiveMe30Dollars

Sebastion Lagueによるビデオは、Bridsonのアルゴリズムを非常によく説明しています。

単純化しすぎると、

  1. radius / sqrt(2)の辺を持つセルグリッドを作成します。

  2. 最初のポイントを配置し、スポーンポイントとしてリストします。

  3. ポイントをグリッドのセルに配置します。

  4. スポーンポイントについては、半径と2 *半径の間のポイントをスポーンします。

  5. 新しい点のセルから2単位離れたセルを見てください。

  6. 他の点が含まれている場合は、距離を比較します。

  7. 半径よりも新しい点に近い点がある場合、新しい点は無効です。

  8. 新しいポイントが有効な場合、新しいポイントはスポーンポイントとしてリストされ、グリッドのセルに配置されます。

  9. スポーンポイントがスポーンする無効なポイントが多すぎると、スポーンポイントが削除されてポイントに変わります。

  10. スポーンポイントがなくなるまで繰り返します。

  11. リターンポイント。

基本的にPython3.7.2とpygame1.7〜で同じことを書き留めましたが、タイトルで述べたように、再帰的な煉獄で立ち往生しています。

このアルゴリズムに1つのPoint()クラスを使用しました。これは、pygame.Vector2()が存在することを考えると冗長に見えるかもしれませんが、このクラスが機能する必要がある別のアルゴリズム(無限の頂点を持つDelaunay)にいくつかの要素が必要でした。

簡単にするために、Delaunay固有の要素をすべて切り取り、このアルゴリズムに必要なこのクラスの最低限の要素を示します。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def DistanceToSquared(self,other):
        return (self.x-other.x)**2 + (self.y-other.y)**2

Bridsonのアルゴリズムに関連するコードは次のとおりです。

def PoissonDiskSampling(width, height, radius, startPos = None, spawnAttempts = 10):

    if startPos == None:
        startPos = [width//2,height//2]

    cellSize = radius / math.sqrt(2)
    cellNumberX = int(width // cellSize + 1)  # Initialise a cells grid for optimisation
    cellNumberY = int(height // cellSize + 1)
    cellGrid = [[None for x in range(cellNumberX)] for y in range(cellNumberY)]

    startingPoint = Point(startPos[0],startPos[1]) # Add an iniial point for spawning purposes
    cellGrid[startingPoint.x//radius][startingPoint.y//radius] = startingPoint

    points = [startingPoint] # Initialise 2 lists tracking all points and active points
    spawnpoints = [startingPoint]

    while len(spawnpoints) > 0:

        spawnIndex = random.randint(0,len(spawnpoints)-1)
        spawnpoint = spawnpoints[spawnIndex]

        spawned = False
        for i in range(spawnAttempts):

            r = random.uniform(radius,2*radius)
            radian = random.uniform(0,2*math.pi)
            newPoint = Point(spawnpoint.x + r*math.cos(radian),
                            spawnpoint.y + r*math.sin(radian))
            if 0 <= newPoint.x <= width and 0 <= newPoint.y <= height:
                isValid = True
            else:
                continue

            newPointIndex = [int(newPoint.x//cellSize), int(newPoint.y//cellSize)]
            neighbours = FindNeighbours(cellNumberX,cellNumberY,newPointIndex,cellGrid)

            for neighbour in neighbours:
                if newPoint.DistanceToSquared(neighbour) < radius**2:
                    isValid = False
                    break

            if isValid:
                points.append(newPoint)
                spawnpoints.append(newPoint)
                spawned = True
                break
            else:
                continue

        if spawned == False:
            spawnpoints.remove(spawnpoint)

    return points

def FindNeighbours(cellNumberX, cellNumberY, index, cellGrid):
    neighbours = []
    for cellX in range(max(0,(index[0]-2)), min(cellNumberX,(index[1]+2))):
        for cellY in range(max(0,(index[0]-2)), min(cellNumberY,(index[1]+2))):
            if cellGrid[cellX][cellY] != None:
                neighbours.append(cellGrid[cellX][cellY])
    return neighbours

助けてください。

Rabbid76

おそらく最も重要なステップがコードにありません。

  1. 新しいポイントが有効な場合、新しいポイントはスポーンポイントとしてリストされ、グリッドのセルに配置されます。

cellGrid有効な場合は、ポイントを追加することをお勧めします。

if isValid:

    cellGrid[newPointIndex[0]][newPointIndex[1]] = newPoint

    points.append(newPoint)
    spawnpoints.append(newPoint)
    spawned = True
    break

さらに、newPointIndexポイントを追加する前に、インデックスのあるセルがまだ占有されていないかどうかを確認する必要があります。

newPointIndex = [int(newPoint.x/cellSize), int(newPoint.y/cellSize)]
if cellGrid[newPointIndex[0]][newPointIndex[1]] != None:
    continue

neighbours = FindNeighbours(cellNumberX,cellNumberY,newPointIndex,cellGrid)

最後に、関数に問題がありますFindNeighboursrange(start, stop)のxの範囲を作成しますstart <= x < stop
したがって、停止はでindex[0]+3はなくする必要がありindex[0]+2ます。

さらに2つのネストされた制御範囲forループは、両方から実行x-2するy+2よりもむしろからx-2x+2それぞれからy-2y+2

for cellX in range(max(0,(index[0]-2)), min(cellNumberX,(index[1]+2))):
   for cellY in range(max(0,(index[0]-2)), min(cellNumberY,(index[1]+2)))

固定関数は次のとおりである必要があります。

def FindNeighbours(cellNumberX, cellNumberY, index, cellGrid):
    neighbours = []
    for cellX in range(max(0, index[0]-2), min(cellNumberX, index[0]+3)):
        for cellY in range(max(0, index[1]-2), min(cellNumberY, index[1]+3)):
            if cellGrid[cellX][cellY] != None:
                neighbours.append(cellGrid[cellX][cellY])
    return neighbours

サイズが300x 300、半径が15の場合は、結果を参照してください。


spawnpointsランダムな点ではなく、常に最初の点を使用すると、さらに良い結果が得られます

# spawnIndex = random.randint(0,len(spawnpoints)-1)
spawnIndex = 0 # 0 rather than random
spawnpoint = spawnpoints[spawnIndex] 

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

SMOアルゴリズムが無限ループに陥っていますか?

分類Dev

リーダーが無限ループに陥っているのはなぜですか

分類Dev

効果が無限ループに陥っている-Ngrx / Effects

分類Dev

Cが無限ループに陥っている

分類Dev

Javaで半効率的なハッシュテーブルを作成しようとしていますが、無限ループに陥っています

分類Dev

PackBitsアルゴリズムの実装

分類Dev

CRCアルゴリズムの実装

分類Dev

RSAアルゴリズムの実装

分類Dev

Haskellでのプリムのアルゴリズムの実装

分類Dev

Javaでのプリムのアルゴリズムの実装

分類Dev

アセンブリ言語プログラムが無限ループに陥っている

分類Dev

バイナリ検索アルゴリズムの実装の何が問題になっていますか?

分類Dev

独自のHPSアルゴリズムを実装するにはどうすればよいですか?

分類Dev

app.factoryで無限ループに陥っています-AngularJS

分類Dev

VSTS-新しい既存のローカルプロジェクトを公開するという無限ループに陥っています

分類Dev

K-Daneアルゴリズムの実装の何が問題になっていますか?

分類Dev

補間検索アルゴリズムの実装の何が問題になっていますか?

分類Dev

自分でアルゴリズムを学ぶ、Javaでタプルをどのように実装しますか?

分類Dev

Sumアルゴリズムがループに陥る/非常に長い時間がかかるのはなぜですか?

分類Dev

アルゴリズムの実行数

分類Dev

Javaでのスター(A *)アルゴリズムの実装

分類Dev

MIPSでのソートアルゴリズムの実装

分類Dev

cでのソートアルゴリズムの実装

分類Dev

cのアルゴリズムからforループを実装する

分類Dev

アルゴリズムの出力の混乱

分類Dev

Excelのアルゴリズムの「IF」式

分類Dev

lodashのfindKeyのアルゴリズム

分類Dev

C ++でマトリックスを「ぼかし」ようとしています。欠陥のあるアルゴリズムまたはコード?

分類Dev

JavaでのPetersonアルゴリズム?

Related 関連記事

  1. 1

    SMOアルゴリズムが無限ループに陥っていますか?

  2. 2

    リーダーが無限ループに陥っているのはなぜですか

  3. 3

    効果が無限ループに陥っている-Ngrx / Effects

  4. 4

    Cが無限ループに陥っている

  5. 5

    Javaで半効率的なハッシュテーブルを作成しようとしていますが、無限ループに陥っています

  6. 6

    PackBitsアルゴリズムの実装

  7. 7

    CRCアルゴリズムの実装

  8. 8

    RSAアルゴリズムの実装

  9. 9

    Haskellでのプリムのアルゴリズムの実装

  10. 10

    Javaでのプリムのアルゴリズムの実装

  11. 11

    アセンブリ言語プログラムが無限ループに陥っている

  12. 12

    バイナリ検索アルゴリズムの実装の何が問題になっていますか?

  13. 13

    独自のHPSアルゴリズムを実装するにはどうすればよいですか?

  14. 14

    app.factoryで無限ループに陥っています-AngularJS

  15. 15

    VSTS-新しい既存のローカルプロジェクトを公開するという無限ループに陥っています

  16. 16

    K-Daneアルゴリズムの実装の何が問題になっていますか?

  17. 17

    補間検索アルゴリズムの実装の何が問題になっていますか?

  18. 18

    自分でアルゴリズムを学ぶ、Javaでタプルをどのように実装しますか?

  19. 19

    Sumアルゴリズムがループに陥る/非常に長い時間がかかるのはなぜですか?

  20. 20

    アルゴリズムの実行数

  21. 21

    Javaでのスター(A *)アルゴリズムの実装

  22. 22

    MIPSでのソートアルゴリズムの実装

  23. 23

    cでのソートアルゴリズムの実装

  24. 24

    cのアルゴリズムからforループを実装する

  25. 25

    アルゴリズムの出力の混乱

  26. 26

    Excelのアルゴリズムの「IF」式

  27. 27

    lodashのfindKeyのアルゴリズム

  28. 28

    C ++でマトリックスを「ぼかし」ようとしています。欠陥のあるアルゴリズムまたはコード?

  29. 29

    JavaでのPetersonアルゴリズム?

ホットタグ

アーカイブ