2010-12-03 3 views
3

Я заинтересован в создании точек, которые «равномерно» (и неслучайно) распределены вокруг сферы, подобно ямочкам мяча для гольфа или вершинам шестиугольников на футбольном мяче , Есть ли определенные алгоритмы для этого?Создание точек равномерно на сфере

Примечание: Я знаю, что точки на самом деле не «равномерно» распределены по сфере, но распределены таким образом, что распределение точек выглядит одинаково с любого направления, которое смотрит прямо на любую из точек - это что меня интересует.

+3

Ниже приведен соответствующий поиск по Google (http://www.google.com/search?q=distribute+points+on+a+sphere&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla: де-DE: неофициальный и клиент = Iceweasel-а). Первый хит включает даже реализации на C++ и Java. – 2010-12-03 20:51:15

+0

Я не знаю, что существует равномерное распределение, в вашем смысле, для произвольного числа точек. Количество ямок на мяче для гольфа фиксировано (хотя я не помню число), а также количество вершин шестиугольника на футбольном мяче. – 2010-12-03 20:54:58

ответ

1

Подразделение октаэдра и нормализация вершин впоследствии дает очень хорошие результаты. Look here для более подробной информации. У Пола Бурка много интересного.

Вот некоторые псевдо C++ код, который я написал в пять минут в настоящее время:

/* Assume 'data' initially holds vertices for eight triangles (an octahedron) */ 
void GenerateSphere(float radius, std::vector<Vector3f>& data, int accum=10) 
{ 
    assert(!(data.size() % 3)); 

    std::vector<Vector3f> newData; 

    for(int i=0; i<data.size(); i+=3){ 
     /* Tesselate each triangle into three new ones */ 
     Vector3f centerPoint = (data[i] + data[i+1] + data[i+2])/3.0f; 

     /* triangle 1*/ 
     newData.push_back(data[i+0]); 
     newData.push_back(data[i+1]); 
     newData.push_back(centerPoint); 
     /* triangle 2*/ 
     newData.push_back(data[i+1]); 
     newData.push_back(data[i+2]); 
     newData.push_back(centerPoint); 
     /* triangle 3*/ 
     newData.push_back(centerPoint); 
     newData.push_back(data[i+2]); 
     newData.push_back(data[i+0]); 
    } 
    data = newData; 
    if(!accum){ 
     /* We're done. Normalize the vertices, 
      multiply by the radius and return. */ 
     for(int i=0; i<data.size(); ++i){ 
      data[i].normalize(); 
      data[i] *= radius; 
     } 
    } else { 
     /* Decrease recursion counter and iterate again */ 
     GenerateSphere(radius, data, accum-1); 
    } 
    return; 
} 

Этот код будет работать с любым многогранник из против часовой стрелки треугольников, но октаэдры лучше.

0

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

http://mathworld.wolfram.com/SpherePointPicking.html

0

Вот простой способ сделать это.

  1. Произвольно, проба из единичного куба, [0, 1]^3

  2. Тест для включения в сферу. Отклонить, если выбранная точка находится не в сфере диаметра 1, которая содержится в единичном кубе, и переходите к этапу 1.

  3. Нормализовать точку, которая должна быть на поверхности сферы, проецируя точку наружу от центр сферы.

Это, как правило, будет успешным после нескольких образцов. Если вы хотите, вы можете также отклонить образцы, которые находятся вблизи центра сферы, чтобы свести к минимуму ошибки округления и помочь приблизить распределение до однородности.

0

если ты в порядке с наличием только некоторые допустимые числа вершин, то методы деления выше, безусловно, путь.если вы хотите произвольно заданное количество вершин, тогда я рекомендую:

сначала распределяет точки случайным образом и равномерно по сфере. Я подробно расскажу об этом на http://elenzil.com/progs/randompoints. Я считаю, что мой метод, по крайней мере, настолько же эффективен, как и у worlfram.

Во-вторых, «расслабьте» распределение, обрабатывая точки как систему частиц, где каждая частица отталкивает каждую другую частицу. сложность здесь заключается в том, что система не становится неустойчивой и решает, когда остановиться. У меня есть пример этого здесь: http://elenzil.com/progs/separate К сожалению, это были дни, прежде чем я включил исходный код с моими проектами, чтобы код был потерян.

0

Я попробовал один раз следующий алгоритм:

  • начать с правильного тетраэдра с подаёт на сфере.
  • выбрать один из треугольников с самой большой поверхностью (первоначально это будет любая из 4 сторон)
  • заменить выбранную грань на трехгранную пирамиду, где 4-я точка - это высота центра лица до поверхности сферы.
  • повторить до тех пор, пока не будет создано достаточное количество баллов.

Это работает до тех пор, пока точность не разрушает однородность. Результирующие точки образуют фигуры, похожие на геодезику.

Вам не нужно вычислять любую поверхность, так как каждый новый треугольник не превосходит всех предыдущих. Просто обрабатывайте их в порядке FIFO.