我希望在圆柱体和圆锥体上随机均匀地生成点(分别)。圆柱体由其中心、半径和高度定义。锥体规格相同。我能够获得每个形状的边界框,所以我正在考虑在边界框中生成点。但是,我不确定如何将它们投影到圆柱体/圆锥体上,或者这是否是最好的主意。
有什么建议么?
谢谢。
我希望在圆柱体和圆锥体上随机均匀地生成点(分别)。圆柱体由其中心、半径和高度定义。锥体规格相同。我能够获得每个形状的边界框,所以我正在考虑在边界框中生成点。但是,我不确定如何将它们投影到圆柱体/圆锥体上,或者这是否是最好的主意。
有什么建议么?
谢谢。
气缸壳是微不足道的。如果半径 r > 0 且高度 h > 0 的圆柱体是 (x, y, z) = (r cos φ, r sin φ, z) 在 φ ∈ [0, 2π[ 和 z ∈ [-h /2, h/2],然后简单地在这些区间上随机选择 φ 和 z。当然,也可以使用标准参数化简单地对圆锥进行参数化,但是面积元素在参数平面上不会是恒定的,因此点的分布不会是随机的。因此,您需要找到不同的参数化。我已经在我的 AlgoSim 站点上针对一个球体详细讨论了这个主题。
直接在圆柱体或圆锥体上生成点会更简单。
自从我这样做已经有一段时间了,但是参数化圆柱体的轴,然后为每个点参数化该高度的圆。这将在曲面上创建点。圆的半径是圆柱的半径。
对于圆锥,当您从底部移动到顶点时,您需要减小圆的半径。
想到这一点的一种方法是圆柱体和圆锥体都可以展开成平面 - 只需用一条直线从上到下切割每一个。
圆柱体展开成一个矩形(如果包括顶部和底部,则添加几个磁盘)。
圆锥展开成一个三角形,底部弯曲,是一个圆弧(如果您包括圆锥的底部,则添加一个圆盘)。
R
将这些平面嵌入xy 平面上的矩形内很容易。在 中生成均匀分布的点R
,只要它们在平面内,就将它们映射回原始曲面。
注意这里的一些其他答案,这些答案试图根据角度和高度来协调锥体。尽管这些点在角度和高度方面是均匀分布的,但它们不会在面积上均匀分布。它们将更密集地分布在尖端。
让一个点由坐标r、a、h定义,其中r是“半径”(从中心经过的垂直轴的距离),a是极坐标中的角度,h是它的高度。
对于圆柱体(半径R和高度H):独立选择
从这样的三角分布中采样应该不难,因为它的累积分布(二次单项式)很容易可逆(参见这篇文章)。此外,这个答案是基于直觉的,但不难证明你在圆柱体上获得的分布是均匀的。
对于圆锥(半径R和高度H):选择
同样,采样h应该很容易,因为累积分布很容易反转。
编辑。如果您的意思是在形状的表面上生成点,那么解决方案会更简单:
气缸:选择
锥体:选择
其他答案已经很好地涵盖了圆柱体外壳。对于锥体来说,事情要困难一些。为了保持点的恒定密度,您需要补偿半径的变化。
为此,您可以从选择点之间的距离开始。当您沿着圆锥轴移动时,您计算该高度处的周长,然后将周长除以点之间的线性距离以获得点数。然后,您将 2pi 弧度(或 360 度,或其他)除以点数,以获得该半径的角距离。
根据您需要的精度,您可以在计算下一个圆时跟踪一个圆的余数。例如,如果你有两个连续的圆圈需要 xxx.4 分,如果单独看,你会向下取整——但一起看,你有 xxx.8 分,所以你应该一个向下取整,另一个向上取整,以使整体密度尽可能接近正确值。
请注意,虽然不是很明显,但后者也可以应用于圆柱体——在分布每个圆点时通常会进行一些舍入。
将这些答案放入伪代码中:
对于圆柱体,给定圆柱半径和圆柱高度:
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.
对于圆锥,给定圆锥半径,圆锥高度:
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) 将位于圆柱体/圆锥体上。生成足够多的这些点,您可以在圆柱体/圆锥体的表面上生成粒子,但它可能不会形成完全均匀的分布......
对于半径为 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 )