improved bridson's algorithm attempt

This commit is contained in:
Xevion
2020-05-06 00:23:59 -05:00
parent 1c6c997db9
commit 0e0154e10e
2 changed files with 56 additions and 3 deletions

View File

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

View File

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