Является ли мой бесшовный алгоритм отбора проб пуассона?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Является ли мой бесшовный алгоритм отбора проб пуассона?

Сообщение Anonymous »

Недавно мне пришлось разработать функцию отбора проб Пуассона для проекта Годота, над которым я работал, в C#. Я следовал учебному пособию Себастьяна Лаг, который основан на этой статье. Все работало нормально, алгоритм правильно сгенерировал список позиций, распределенных на прямоугольнике. Тем не менее, мне также необходимо было беспрепятственно сгенерированный «шум», что означает, что положения на двух параллельных краях прямоугольника все еще сохраняли одинаковое минимальное расстояние между друг другу. Я искал в Интернете ресурсы о том, как добиться этого, но не удалось, так как у меня нет необходимых знаний для правильного чтения и понимания более продвинутых документов. Именно в этот момент я решил совершить то, что некоторые назвали бы самым серьезным грехом: попросите Chatgpt придумать решение для меня. К моему удивлению, он фактически генерировал алгоритм, который работает и работает быстро, используя тороидальный домен вместо прямоугольника. Я боюсь, что код может иметь очень скрытую ошибку или проблему переносимости, и я недостаточно осведомлен, чтобы полностью понять алгоритм, который он написал. Поэтому я хотел бы спросить, может ли кто -нибудь просмотреть этот код и выяснить, хорошо ли он в использовании или нет. < /P>

Код: Выделить всё

private List GenerateRandomPositions()
{
// Poisson Disc Sampling on a toroidal (seamless) domain

float cellSize = _spacing / Mathf.Sqrt2;
int width = Mathf.CeilToInt(_areaSize.X / cellSize);
int height = Mathf.CeilToInt(_areaSize.Y / cellSize);
int[,] cells = new int[width, height];
List positions = new List();
List frontierPositions = new List();

// Seed algorithm at center
Vector2 seed = _halfAreaSize;
frontierPositions.Add(seed);
positions.Add(seed);
cells[(int)(seed.X / cellSize), (int)(seed.Y / cellSize)] = 1;

// Start position generation loop
while (frontierPositions.Count > 0)
{
int spawnIndex = (int)(GD.Randf() * frontierPositions.Count);
Vector2 spawnCenter = frontierPositions[spawnIndex];
bool candidateAccepted = false;

for (int i = 0; i < _samplesBeforeRejection; i++) // Try _sampleBeforeRejection times to find a valid candidate
{
float angle = GD.Randf() * Mathf.Tau;
Vector2 direction = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle));
Vector2 candidatePosition = spawnCenter + direction * (float)GD.RandRange(_spacing, _spacing * 2);

// wrap candidate into tile
candidatePosition.X = (candidatePosition.X % _areaSize.X + _areaSize.X) % _areaSize.X;
candidatePosition.Y = (candidatePosition.Y % _areaSize.Y + _areaSize.Y) % _areaSize.Y;

if (IsValid(candidatePosition)) // Accept candidate if it's valid
{
positions.Add(candidatePosition);
frontierPositions.Add(candidatePosition);
int cx = (int)(candidatePosition.X / cellSize) % width;
int cy = (int)(candidatePosition.Y / cellSize) % height;
cells[cx, cy] = positions.Count;
candidateAccepted = true;
break;
}
}

if (!candidateAccepted) // Remove candidate if it is not valid
frontierPositions.RemoveAt(spawnIndex);
}

// center around origin
for (int i = 0; i < positions.Count; i++)
positions[i] -= _halfAreaSize;

return positions;

bool IsValid(Vector2 candidatePosition)
{
// assume candidate already wrapped
int cellX = (int)(candidatePosition.X / cellSize) % width;
int cellY = (int)(candidatePosition.Y / cellSize) % height;
int startX = cellX - 2;
int endX = cellX + 2;
int startY = cellY - 2;
int endY = cellY + 2;

for (int x = startX; x  _areaSize.Y * 0.5f) dy = _areaSize.Y - dy;
float toroidalDistance = dx * dx + dy * dy;

if (toroidalDistance < _spacing * _spacing)
return false;
}
}
}
return true;
}
}
Если вам нужна дополнительная информация, gd.randf () возвращает случайное значение с плавающей точкой от 0,0 до 1,0 (включительно), в то время как gd.randrange (float, float) Возвращает случайное значение плавающей точки между и (включительно).>

Подробнее здесь: https://stackoverflow.com/questions/795 ... rithm-fine
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»