有什么建议吗?
谢谢。
直接在圆柱体或圆锥体上生成点会更简单。
虽然我已经有一段时间没有这样做了,但是可以将圆柱轴参数化,并对每个点参数化其高度处的圆。这将在表面创建点。圆的半径为圆柱的半径。
对于圆锥体,需要随着从底部到顶部的移动减小圆的半径。
定义一个点的坐标为r,a,h,其中r是“半径”(从中心垂直轴线的距离),a是极坐标中的角度,h是其高度。
对于圆柱体(半径R和高度H):独立选择
从这样的三角形分布中进行抽样不应该很困难,因为它的累积分布(一个二次单项式)很容易可逆(参见this article)。此外,这个答案是基于直觉的,但证明你在圆柱体上获得的分布是均匀的也不应该很困难。
对于圆锥(半径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
对于半径为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 )
cylinder_point= point3d( R*cos(angle), R*sin(angle), H*value )