универсальное поколение 3D точек на цилиндре/конусе

Я хочу случайным образом и однородно генерирую точки на цилиндре и конусе (отдельно). Цилиндр определяется его центром, его радиусом и высотой. Те же спецификации для конуса. Я могу получить ограничительную рамку для каждой формы, таким образом, я думал о генерации точек в ограничительной рамке. Однако я не уверен, как спроектировать их на цилиндр/конус или если это - лучшая идея.

Какие-либо предложения?

Спасибо.

7
задан Myx 25 April 2010 в 22:38
поделиться

7 ответов

Корпус цилиндра тривиален. Если цилиндр радиуса r> 0 и высоты h> 0 является образом (x, y, z) = (r cos φ, r sin φ, z) на φ ∈ [0, 2π [и z ∈ [-h / 2, h / 2], то просто выбираем φ и z случайным образом на этих интервалах. Конечно, можно просто параметризовать конус, используя стандартную параметризацию, но тогда элемент площади не будет постоянным на плоскости параметров, и поэтому распределение точек не будет случайным. Таким образом, вам нужно найти другую параметризацию. Я подробно обсуждал эту тему для сферы на моем сайте AlgoSim .

5
ответ дан 7 December 2019 в 07:42
поделиться

Было бы проще создавать точки непосредственно на цилиндре или конусе.

Прошло некоторое время с тех пор, как я сделал это, но параметризовал ось цилиндра, а затем для каждой точки параметризировал окружность на этой высоте. Это создаст точки на поверхности. Радиус круга - это радиус цилиндра.

Для конуса вам нужно уменьшить радиус круга по мере продвижения от основания к вершине.

2
ответ дан 7 December 2019 в 07:42
поделиться

Один из способов представить это: и цилиндр, и конус можно развернуть на плоские поверхности - просто разрежьте каждую из них прямой линией сверху вниз. Нижний.

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

Конус разворачивается в треугольник с изогнутым дном, который представляет собой дугу окружности (если вы включаете основание конуса, добавьте диск).

Достаточно легко встроить эти плоские поверхности внутрь прямоугольника R на плоскости xy. Создайте равномерно распределенные точки в R , и всякий раз, когда они находятся внутри плоских поверхностей, сопоставьте их с исходными поверхностями.

Не упустите некоторые другие ответы здесь, которые пытаются скоординировать конус с точки зрения угла и высоты.Хотя точки будут равномерно распределены по углу и высоте, они не будут равномерно распределены по высоте. площадь. Они будут более плотно распределены на кончике.

2
ответ дан 7 December 2019 в 07:42
поделиться

Чтобы поместить эти ответы в псевдокоде:

Для цилиндр, заданный цилиндрRadius и cylHeight:

angle = random number between 0 & 360

x = cos(pi/180*angle)*cylinderRadius
y = sin(pi/180*angle)*cylinderRadius
z = random number between 0 and cylinderHeight.

Для конуса, заданный coneRadius, coneHeight:

angle = random number between 0 & 360

z = random number between 0 and coneHeight

thisRadius = coneRadius * (1-(z/coneHeight)); //This gives a decreasing radius as height increases.

x = cos(pi/180*angle)*thisRadius
y = sin(pi/180*angle)*thisRadius

Каждая точка (x, y, z) будет лежать на цилиндре / конусе. Создайте достаточное количество этих точек, и вы сможете создавать частицы на поверхности цилиндра / конуса, но это может не дать точно равномерного распределения ...

-1
ответ дан 7 December 2019 в 07:42
поделиться

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

Для этого вы можете начать с выбора расстояния между точками. Двигаясь вдоль оси конуса, вы вычисляете длину окружности на этой высоте, а затем делите длину окружности на линейное расстояние между точками, чтобы получить количество точек. Затем вы делите радианы 2pi (или 360 градусов, или что-то еще) на количество точек, чтобы получить угловое расстояние для этого радиуса.

В зависимости от необходимой точности, вы можете отслеживать остаток от одного круга при вычислении следующего круга. Например, если у вас есть два круга в ряду, которые требуют ххх,4 балла, вы бы округлили каждый в меньшую сторону, если бы смотрели по отдельности, но, глядя на них вместе, у вас есть ххх,8 балла, поэтому вам следует округлите одно вниз, а другое вверх, чтобы общая плотность была как можно ближе к правильному значению.

Обратите внимание, что, хотя это не так очевидно, последнее может быть применимо и к цилиндру - обычно у вас будет некоторое округление при распределении каждого круга точек.

0
ответ дан 7 December 2019 в 07:42
поделиться

Пусть точка определяется координатами r , a , h , где r - это «радиус» (расстояние от вертикальной оси, проходящей из центра), a - угол, как в полярных координатах, и h - его высота. .

Для цилиндра (радиус R и высота H ): выберите независимо

  • униформу в [0, 2pi),
  • ​​h равномерно в [0, H ] и
  • r с «треугольной плотностью»: f ( r ) = 2 r / R , если 0 <= r <= R , 0 в противном случае (плотность в r должна быть пропорциональна длина окружности радиуса r ).

Сделать выборку из такого треугольного распределения не составит труда, поскольку его кумулятивное распределение (квадратичный моном) легко обратимо (см. , эту статью ). Кроме того, этот ответ основан на интуиции, но нетрудно доказать, что распределение, которое вы получаете на цилиндре, является равномерным.

Для конуса (радиус R и высота H ): выберите

  • однородный в [0, 2pi),
  • h с плотностью, составленной из сегмента параболы: f ( h ) = 3 ( H - h ) ^ 2 / H ^ 3, если 0 <= h <= H , 0 в противном случае (плотность на h должна быть пропорциональна площади круглого сечения на высоте ч ),
  • пусть r ( h ) = ( H - h ) R / H (радиус сечения на высоте h ); затем выберите r с «треугольным распределением» f ( r ) = 2 r / r ( h ), если 0 <= r <= r ( h ), 0 в противном случае.

Опять же, выборка h должна быть простой, поскольку кумулятивное распределение легко обратимо.

РЕДАКТИРОВАТЬ.Если вы хотите создать точки на поверхности фигур, то решение будет проще:

Цилиндр : выберите

  • равномерное в [0, 2pi),
  • h равномерный в [0, H ],
  • r = R .

Конус : выберите

  • a равномерный в [0, 2pi),
  • h с треугольной плотностью: f ( h ) = 2 ( H - h ) / H ^ 2, если 0 <= h <= H , 0 в противном случае ( плотность на h должна быть пропорциональна длине окружности на высоте h ).
  • r = r ( h ) = ( H - h ) R / H = радиус на высоте h .
0
ответ дан 7 December 2019 в 07:42
поделиться

Для однородных точек на окружности или конусе с радиусом R и высотой / возвышением H:

generate:
  angle= uniform_random(0,2*pi)
  value= uniform_random(0,1)

in either case, let:
  r= R * sqrt(value)

then (using separate random numbers for each):
  circle_point= point3d( r*cos(angle), r*sin(angle), H )
or:
  cone_point= point3d( r*cos(angle), r*sin(angle), r*H )

Обратите внимание, что если вам нужно основание на конусе, вам нужно будет сделать это отдельно от изогнутой формы. Чтобы убедиться, что плотность точек одинакова для разных частей, простой способ - вычислить площади частей и сгенерировать пропорциональное количество точек для каждой части.

sqrt (значение) - это то, что обеспечивает однородность плотности ваших случайных точек. Как уже упоминалось в других вопросах, для этого вам нужно треугольное распределение ; использование sqrt () превращает равномерное распределение на [0,1) в треугольное.

Для цилиндра вам не нужна sqrt (); изогнутая часть:

  cylinder_point= point3d( R*cos(angle), R*sin(angle), H*value )
-1
ответ дан 7 December 2019 в 07:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: