Я хочу случайным образом и однородно генерирую точки на цилиндре и конусе (отдельно). Цилиндр определяется его центром, его радиусом и высотой. Те же спецификации для конуса. Я могу получить ограничительную рамку для каждой формы, таким образом, я думал о генерации точек в ограничительной рамке. Однако я не уверен, как спроектировать их на цилиндр/конус или если это - лучшая идея.
Какие-либо предложения?
Спасибо.
Корпус цилиндра тривиален. Если цилиндр радиуса r> 0 и высоты h> 0 является образом (x, y, z) = (r cos φ, r sin φ, z) на φ ∈ [0, 2π [и z ∈ [-h / 2, h / 2], то просто выбираем φ и z случайным образом на этих интервалах. Конечно, можно просто параметризовать конус, используя стандартную параметризацию, но тогда элемент площади не будет постоянным на плоскости параметров, и поэтому распределение точек не будет случайным. Таким образом, вам нужно найти другую параметризацию. Я подробно обсуждал эту тему для сферы на моем сайте AlgoSim .
Было бы проще создавать точки непосредственно на цилиндре или конусе.
Прошло некоторое время с тех пор, как я сделал это, но параметризовал ось цилиндра, а затем для каждой точки параметризировал окружность на этой высоте. Это создаст точки на поверхности. Радиус круга - это радиус цилиндра.
Для конуса вам нужно уменьшить радиус круга по мере продвижения от основания к вершине.
Один из способов представить это: и цилиндр, и конус можно развернуть на плоские поверхности - просто разрежьте каждую из них прямой линией сверху вниз. Нижний.
Цилиндр разворачивается в прямоугольник (если вы включаете верх и низ, добавьте пару дисков).
Конус разворачивается в треугольник с изогнутым дном, который представляет собой дугу окружности (если вы включаете основание конуса, добавьте диск).
Достаточно легко встроить эти плоские поверхности внутрь прямоугольника R
на плоскости xy. Создайте равномерно распределенные точки в R
, и всякий раз, когда они находятся внутри плоских поверхностей, сопоставьте их с исходными поверхностями.
Не упустите некоторые другие ответы здесь, которые пытаются скоординировать конус с точки зрения угла и высоты.Хотя точки будут равномерно распределены по углу и высоте, они не будут равномерно распределены по высоте. площадь. Они будут более плотно распределены на кончике.
Чтобы поместить эти ответы в псевдокоде:
Для цилиндр, заданный цилиндр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) будет лежать на цилиндре / конусе. Создайте достаточное количество этих точек, и вы сможете создавать частицы на поверхности цилиндра / конуса, но это может не дать точно равномерного распределения ...
Другие ответы уже довольно хорошо касались корпуса цилиндра. С конусом дела обстоят немного сложнее. Чтобы поддерживать постоянную плотность точек, нужно компенсировать изменение радиуса.
Для этого вы можете начать с выбора расстояния между точками. Двигаясь вдоль оси конуса, вы вычисляете длину окружности на этой высоте, а затем делите длину окружности на линейное расстояние между точками, чтобы получить количество точек. Затем вы делите радианы 2pi (или 360 градусов, или что-то еще) на количество точек, чтобы получить угловое расстояние для этого радиуса.
В зависимости от необходимой точности, вы можете отслеживать остаток от одного круга при вычислении следующего круга. Например, если у вас есть два круга в ряду, которые требуют ххх,4 балла, вы бы округлили каждый в меньшую сторону, если бы смотрели по отдельности, но, глядя на них вместе, у вас есть ххх,8 балла, поэтому вам следует округлите одно вниз, а другое вверх, чтобы общая плотность была как можно ближе к правильному значению.
Обратите внимание, что, хотя это не так очевидно, последнее может быть применимо и к цилиндру - обычно у вас будет некоторое округление при распределении каждого круга точек.
Пусть точка определяется координатами r , a , h , где r - это «радиус» (расстояние от вертикальной оси, проходящей из центра), a - угол, как в полярных координатах, и h - его высота. .
Для цилиндра (радиус R и высота H ): выберите независимо
Сделать выборку из такого треугольного распределения не составит труда, поскольку его кумулятивное распределение (квадратичный моном) легко обратимо (см. , эту статью ). Кроме того, этот ответ основан на интуиции, но нетрудно доказать, что распределение, которое вы получаете на цилиндре, является равномерным.
Для конуса (радиус R и высота H ): выберите
Опять же, выборка h должна быть простой, поскольку кумулятивное распределение легко обратимо.
РЕДАКТИРОВАТЬ.Если вы хотите создать точки на поверхности фигур, то решение будет проще:
Цилиндр : выберите
Конус : выберите
Для однородных точек на окружности или конусе с радиусом 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 )