2010-04-20 3 views
6

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

Любые предложения?

Спасибо.

+1

Похоже, что соотношение составляет от 1,5 до 0,5. Вероятно, вам понадобится отношение = (max_y-y)/cone-> Height(). – comingstorm

+1

Кроме того, чтобы остановить ваши точки от группировки вокруг вершины, вы хотите, чтобы y = (max_y-min_y) * (1-sqrt (RandomNumber())) + min_y – comingstorm

+0

выглядит как вопрос в вашем EDIT был дан ответ. Можете ли вы его очистить или добавить еще один EDIT, чтобы указать, что на него ответили? – brainjam

ответ

4

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

2

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

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

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

-1

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

Для цилиндра, учитывая cylinderRadius и cylinderHeight:

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) будет лежать на цилиндре/конусе. Генерируйте достаточное количество этих точек, и вы можете наносить частицы на поверхность цилиндра/конуса, но это может быть не совсем равномерное распределение ...

+0

Проблема * есть *, чтобы найти равномерное распределение, и это не относится к вашему коду для конуса. –

2

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

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

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

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

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

0

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

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

  • равномерное на [0, 2ПИ),
  • ч форму в [0 , H], и
  • r с "треугольной плотности": F (г) = 2 г/R, если 0 < = г < = R, 0 в противном случае (плотность при г должна быть пропорциональна длине от окружности радиуса r).

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

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

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

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

EDIT. Если вы имеете в виду, чтобы создавать точки на поверхности из форм, то решение проще:

Цилиндр: выбрать

  • в форму в [0, 2р),
  • ч равномерна в [0, Н],
  • г = R.

Конус: выбор

  • равномерна в [0, 2ПИ),
  • ч с треугольной плотностью: F (ч) = 2 (Н - h)/H^2, если 0 < = ч < = Н, 0 в противном случае (плотность в ч должна быть пропорциональна длине окружности на высоте ч).
  • г = г (ч) = (Н - ч) R/Н = радиус по высоте ч.
+0

Я думаю, он хочет, чтобы точки * на * цилиндре, а не внутри него. –

+0

Упс. Вы имеете в виду на поверхности? –

+0

Да, для определения цилиндр (и конус) является поверхностью в пространстве, а не твердым объектом. И я думаю, что ОП действительно использует это математическое определение, потому что он использует предлог «на», а не «внутри». –

-1

Для однородных точек на окружности или конуса с радиусом 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 (value) - это то, что гарантирует плотность ваших случайных точек. Как и другие вопросы, вы хотите получить треугольное распределение ; взятие sqrt() превращает равномерное распределение на [0,1) в треугольное.

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

cylinder_point= point3d(R*cos(angle), R*sin(angle), H*value) 
0

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

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

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

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

Смежные вопросы