在圆柱/圆锥上均匀生成3D点

时间:2010-04-20 20:47:30

标签: opengl 3d geometry trigonometry particles

我希望随机均匀地在圆柱体和圆锥体上生成点(单独)。圆柱体由其中心,半径和高度限定。锥体的规格相同。我能够得到每个形状的边界框,所以我想在边界框内生成点。但是,我不确定如何将它们投射到圆柱/圆锥上或者这是最好的想法。

有什么建议吗?

感谢。

7 个答案:

答案 0 :(得分:4)

气缸外壳很简单。如果半径为r的圆柱体> 0和高度h> 0是φ∈[0,2π[和z∈[-h / 2,h / 2]的(x,y,z)=(rcosφ,rsinφ,z)的图像,然后简单地选择φ和z在这些间隔上随机。当然,也可以使用标准参数化简单地对锥体进行参数化,但是面积元素在参数平面上不会是恒定的,因此点的分布不是随机的。因此,您需要找到不同的参数化。我已在my AlgoSim site处详细讨论了该主题。

答案 1 :(得分:2)

直接在圆柱体或圆锥上生成点会更简单。

我做了这个已经有一段时间了,但是参数化圆柱体的轴,然后对于每个点参数化该高度处的圆。这将在表面上创建点。圆的半径是圆柱的半径。

对于锥体,当您从基部移动到顶点时,需要减小圆的半径。

答案 2 :(得分:2)

考虑到这一点的一种方法是圆柱体和圆锥体都可以展开成平面 - 只需从顶部到底部用直线切割每一个。

将圆柱展开为矩形(如果包括顶部和底部,则添加几个磁盘)。

圆锥展开到一个三角形,底部是弧形的圆形(如果你包括圆锥底部,那么添加一个圆盘)。

将这些平面嵌入xy平面上的矩形R内很容易。在R中生成均匀分布的点,只要它们位于平面内,就会将它们映射回原始曲面。

注意这里的一些其他答案,试图在角度和高度方面协调锥形。虽然这些点在角度和高度方面均匀分布,但它们不会均匀分布。区域。它们将在尖端更密集地分布。

答案 3 :(得分:0)

让一个点由坐标 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 )。

从这种三角分布中抽样应该不难,因为它的累积分布(二次单项式)很容易可逆(见this article)。此外,这个答案是基于直觉的,但要证明你在气缸上获得的分布是均匀的,应该不难。

对于圆锥(半径 R 和高度 H ):选择

  • [0,2pi]中的制服,
  • h 密度由一段抛物线构成:f( h )= 3( H - h )^ 2 / H ^ 3如果0 <= h &lt; = H ,否则为0(处的密度h 应该与高度 h 的圆形截面的面积成比例,
  • r h )=( H - h R / H (高度 h 的部分半径);然后选择 r ,使用“三角分布”f( r )= 2 r / r h )如果0&lt; = r &lt; = r h ),否则为0。

同样,采样 h 应该很容易,因为累积分布很容易反转。

EDIT。如果你想在形状的表面上生成点,那么解决方案就更简单了:

Cylinder :选择

  • [0,2pi]中的制服,
  • h 在[0, H ]中统一,
  • r = R

Cone :选择

  • [0,2pi]中的制服,
  • h 具有三角形密度:f( h )= 2( H - h )/ <如果0 <= h &lt; = H ,则em> H ^ 2,否则为0( h 处的密度应为0与高度 h )的圆周长度成正比。
  • r = r h )=( H - h R / H =高度半径 h

答案 4 :(得分:0)

其他答案已经很好地涵盖了气缸外壳。对于锥形,事情有点困难。要保持恒定的点密度,您需要补偿半径的变化。

要做到这一点,您可以先从两点之间选择一个距离。当您沿着圆锥轴移动时,您可以计算该高度的圆周,然后将圆周除以点之间的直线距离以获得点数。然后将2pi弧度(或360度,或其他)除以点数,以获得该半径的角距离。

根据您需要的精确度,您可以在计算下一个圆时跟踪一个圆的余数。例如,如果连续两个圆圈需要xxx.4点,那么如果孤立地查看它们就会向下舍入 - 但是一起看它们,你有xxx.8点,所以你应该这样做第一轮向下,另一轮向上,以保持整体密度尽可能接近正确的值。

请注意,虽然它不那么明显,后者也可以应用于圆柱体 - 通常在分配每个圆点时会有一些圆角。

答案 5 :(得分:-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)将位于圆柱体/圆锥体上。生成足够的这些点,你可以在圆柱/圆锥体的表面上产生粒子,但它可能无法完全均匀分布......

答案 6 :(得分:-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(值)是确保随机点密度均匀的原因。正如其他问题所提到的那样,你需要一个三角分布;取sqrt()将[0,1]上的均匀分布变为三角形分布。

对于圆柱体,您不需要sqrt();弯曲的部分是:

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