mirror of
https://github.com/Xevion/procedural-placement.git
synced 2025-12-09 02:08:12 -06:00
improved bridson's algorithm attempt
This commit is contained in:
@@ -83,4 +83,52 @@ public static class PointGeneration {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static List<Vector2> improved_poisson_sampling(int numPoints, Vector2 regionSize, float radius,
|
||||
int attempts = 30) {
|
||||
float cellSize = radius / Mathf.Sqrt(2);
|
||||
|
||||
// A grid for
|
||||
int[,] grid = new int[Mathf.CeilToInt(regionSize.x / cellSize), Mathf.CeilToInt(regionSize.y / cellSize)];
|
||||
List<Vector2> points = new List<Vector2>();
|
||||
List<Vector2> spawnPoints = new List<Vector2>();
|
||||
|
||||
spawnPoints.Add(regionSize / 2);
|
||||
while (spawnPoints.Count > 0) {
|
||||
int spawnIndex = Random.Range(0, spawnPoints.Count);
|
||||
Vector2 spawnCenter = spawnPoints[spawnIndex];
|
||||
bool candidateAccepted = false;
|
||||
|
||||
float seed = Random.value;
|
||||
float epsilon = 0.000001f;
|
||||
|
||||
for (int i = 0; i < attempts; i++) {
|
||||
// float angle = Random.value * Mathf.PI * 2; // Random radian angle
|
||||
// Vector2 dir = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle));
|
||||
// Vector2 candidate = spawnCenter + dir * Random.Range(radius, radius * 2);
|
||||
float theta = 2 * Mathf.PI * (seed + i / attempts);
|
||||
float r = (radius * 2) + epsilon;
|
||||
Vector2 dir = new Vector2(Mathf.Sin(theta), Mathf.Cos(theta));
|
||||
Vector2 candidate = spawnCenter + r * dir;
|
||||
// Vector2 candidate = new Vector2(
|
||||
// spawnCenter.x + r * Mathf.Sin(theta),
|
||||
// spawnCenter.y + r * Mathf.Cos(theta)
|
||||
// );
|
||||
|
||||
if (poisson_valid(candidate, regionSize, cellSize, points, grid, radius)) {
|
||||
points.Add(candidate);
|
||||
spawnPoints.Add(candidate);
|
||||
grid[(int) (candidate.x / cellSize), (int) (candidate.y / cellSize)] = points.Count;
|
||||
candidateAccepted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!candidateAccepted) {
|
||||
spawnPoints.RemoveAt(spawnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,8 @@ using UnityEngine.Serialization;
|
||||
|
||||
public enum SamplingTypes {
|
||||
Random,
|
||||
Poisson
|
||||
Poisson,
|
||||
Improved_Poisson
|
||||
};
|
||||
|
||||
public class PointRendering : MonoBehaviour {
|
||||
@@ -53,6 +54,10 @@ public class PointRendering : MonoBehaviour {
|
||||
_points = PointGeneration.poisson_sampling(numPoints, regionSize, radius, retryAttempts);
|
||||
numPoints = _points.Count;
|
||||
break;
|
||||
case SamplingTypes.Improved_Poisson:
|
||||
_points = PointGeneration.improved_poisson_sampling(numPoints, regionSize, radius, retryAttempts);
|
||||
numPoints = _points.Count;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user