Генерация точек из 2D фрактального шума - PullRequest
0 голосов
/ 26 апреля 2018

Я использую слоистый шум Перлина для генерации 2D точек, используя метод из https://www.redblobgames.com/maps/terrain-from-noise/#trees. Однако я бы хотел, чтобы координаты точки были не int с, а float с. Для этого я реализовал переменную resolution:

List<Vector2> points = new List<Vector2> ();
int res = 10;
int R = 2;
for (int yc = 0; yc < height*res; yc++) {
    for (int xc = 0; xc < width*res; xc++) {
        float max = 0;
        for (int yn = yc - R; yn <= yc + R; yn++) {
            for (int xn = xc - R; xn <= xc + R; xn++) {
                float e = pointsMap.GetClampedValue((float)xn/res, (float)yn/res);
                if (e > max) { max = e; }
            }
        }
        if (pointsMap.GetClampedValue((float)xc/res, (float)yc/res) == max) {
            points.Add (new Vector2((float)xc/res, (float)yc/res));
        }
    }
}

pointsMap.GetClampedValue() возвращает float от 0-1.

При ширине и высоте 100, разрешении 10 и R = 2 выполняется всего 25 миллионов for циклов. Хотя код внутри циклов далек от оптимизации, он выполняется в разумные сроки с указанными выше настройками. Однако с увеличением разрешения, ширины, высоты и R время выполнения становится слишком большим.

В исходной функции автор оставил комментарий о том, что есть более эффективные алгоритмы, чем этот. Кто-нибудь знает алгоритм, который эффективен, быстр, и где реализация этого разрешения была бы возможна?

1 Ответ

0 голосов
/ 29 апреля 2018

Если вы хотите придерживаться чего-то похожего на учебник, который вы связали, но вам нужны координаты с плавающей точкой, а не десятичные координаты, самое простое решение - просто добавить случайное значение в диапазон [0,1):

Random rng = new Random(regionSeed);
List<Vector2> points = new List<Vector2> ();
for (int yc = 0; yc < height; yc++) {
  for (int xc = 0; xc < width; xc++) {
    double max = 0;
    // there are more efficient algorithms than this
    for (int yn = yc - R; yn <= yc + R; yn++) {
      for (int xn = xc - R; xn <= xc + R; xn++) {
        double e = value[yn][xn];
        if (e > max) { max = e; }
      }
    }
    if (value[yc][xc] == max) {
      list.add( new Vector2(xc+rng.NextDouble(),yc+rng.NextDouble()) );
    }
  }
}
...