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

发布于 2024-08-29 13:47:11 字数 150 浏览 2 评论 0原文

我希望在圆柱体和圆锥体上(分别)随机且均匀地生成点。圆柱体由其中心、半径和高度定义。锥体规格相同。我能够获得每个形状的边界框,因此我正在考虑在边界框内生成点。但是,我不确定如何将它们投影到圆柱体/圆锥体上,或者这是否是最好的主意。

有什么建议吗?

谢谢。

I wish to randomly and uniformly generate points on a cylinder and a cone (separately). The cylinder is defined by its center, its radius and height. Same specifications for the cone. I am able to get the bounding box for each shape so I was thinking of generating points within the bounding box. However, I'm not sure how to project them onto the cylinder/cone or if this is the best idea.

Any suggestions?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

海的爱人是光 2024-09-05 13:47:11

气缸外壳是微不足道的。如果半径为r的圆柱体> 0且高度h>1 0 是 (x, y, z) = (r cos φ, r sin φ, z) 在 φ ε [0, 2π[ 和 z ε [-h/2, h/2] 上的图像,然后只需选择 φ和 z 在这些间隔上随机。当然,也可以使用标准参数化来简单地参数化圆锥体,但是面积元素在参数平面上将不是恒定的,因此点的分布将不是随机的。因此,您需要找到不同的参数化。我已经在 我的 AlgoSim 网站 中详细讨论了这个主题。

The cylinder case is trivial. If the cylinder of radius r > 0 and height h > 0 is the image of (x, y, z) = (r cos φ, r sin φ, z) on φ ∈ [0, 2π[ and z ∈ [-h/2, h/2], then simply choose φ and z randomly on these intervals. Of course one can simply parametrise the cone as well using the standard parametrisation, but then the area element will not be constant on the parameter plane, and so the distribution of points will not be random. Thus you need to find a different parametrisation. I have discussed this topic in detail for a sphere at my AlgoSim site.

桜花祭 2024-09-05 13:47:11

一种思考方法是,圆柱体和圆锥体都可以展开成平坦的表面 - 只需从上到下用直线切割每个表面即可。

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

圆锥体展开成一个三角形,底部弯曲,即圆弧(如果包括圆锥体的底部,则添加一个圆盘)。

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

请注意这里的一些其他答案,它们试图在角度和高度方面协调圆锥体。尽管这些点将在角度和高度方面均匀分布,但它们在面积方面不会均匀分布。它们在尖端的分布会更加密集。

One way to think of this is that both the cylinder and the cone can be unwrapped into flat surfaces - just cut each one with a straight line from top to bottom.

The cylinder unwraps to a rectangle (if you're including the top and bottom, then add a couple of disks).

The cone unwraps to a triangle with a curved bottom that is the arc of a circle (if you're including the base of the cone, then add a disk).

It's easy enough to embed these flat surfaces inside a rectangle R on the xy plane. Generate uniformly distributed points in R, and whenever they are inside the flat surfaces, map them back to the original surfaces.

Watch out for some of the other answers here which try to co-ordinatize a cone in terms of angle and height. Although the points will be uniformly distributed with respect to angle and height, they will not be uniformly distributed w.r.t. area. They will be more densely distributed at the tip.

谜兔 2024-09-05 13:47:11

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

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

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

It would be simpler to generate the points directly on the cylinder or cone.

It's been a while since I did this, but parametrise the axis of the cylinder and then for each point parametrise the circle at that height. This will create points on the surface. The radius of the circle is the radius of the cylinder.

For the cone you need to reduce the radius of the circle as you move from the base to the apex.

多彩岁月 2024-09-05 13:47:11

让一个点由坐标rah定义,其中r是“半径”(距离从穿过中心的垂直轴算起),a 是极坐标中的角度,h 是其高度。

对于圆柱体(半径R和高度H):独立选择

  • [0, 2pi)中的a均匀分布,
  • h 在 [0、H] 和
  • r 中均匀,具有“三角密度”:f(r) = 2 r / R 如果 0 <= r <= R,否则为 0(密度为r 应与半径为 r 的圆周长度成正比)。

从这样的三角分布中采样应该不难,因为它的累积分布(二次单项式)很容易可逆(参见

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

  • [0, 2pi)中的a均匀,
  • < em>h,密度由一段抛物线构成:f(h) = 3 (H - h)^ 2 / H^3 如果 0 <= h <= H,否则为 0(h 处的密度> 应与高度 h 处的圆形截面面积成正比,
  • r( h ) = (H - h) R / H(高度 h 处截面的半径);然后选择具有“三角分布”的 r f(r) = 2 r / r( h ) 如果 0 <= r <= r( h ),否则为 0。

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

编辑。如果您的意思是在形状的表面上生成点,那么解决方案更简单:

圆柱:选择

  • [0, 2pi 中的a 均匀),
  • h 统一为 [0, H],
  • r = R

圆锥:选择

  • [0, 2pi)中的a均匀,
  • h,三角形密度:f(h) = 2 (H - h) / H^2 如果 0 <= h <= H,否则为 0(h 处的密度应与高度 h 处的圆周长度成正比)。
  • r = r( h ) = (H - h) R / H = 高度 h 处的半径。

Let a point be defined by coordinates r, a, h, where r is the "radius" (distance from the vertical axis passing from the center), a is the angle as in polar coordinates, and h is its height.

For the cylinder (radius R and height H): choose independently

  • a uniform in [0, 2pi),
  • h uniform in [0, H], and
  • r with a "triangular density": f(r) = 2 r / R if 0 <= r <= R, 0 otherwise (the density at r should be proportional to the length of the circumference of radius r).

It should not be difficult to sample from such triangular distribution, since its cumulative distribution (a quadratic monomial) is easily invertible (see this article). Also, this answer is based on intuition, but it should not be difficult to prove that the distribution you obtain on the cylinder is uniform.

For the cone (radius R and height H): choose

  • a uniform in [0, 2pi),
  • h with a density made with a segment of parabola: f(h) = 3 (H - h)^2 / H^3 if 0 <= h <= H, 0 otherwise (the density at h should be proportional to the area of the circular section at height h),
  • let r( h ) = (H - h) R / H (the radius of the section at height h); then choose r with a "triangular distribution" f(r) = 2 r / r( h ) if 0 <= r <= r( h ), 0 otherwise.

Again, sampling h should be easy, since the cumulative distribution is easily invertible.

EDIT. If you mean to generate points on the surface of the shapes, then the solution is simpler:

Cylinder: choose

  • a uniform in [0, 2pi),
  • h uniform in [0, H],
  • r = R.

Cone: choose

  • a uniform in [0, 2pi),
  • h with a triangular density: f(h) = 2 (H - h) / H^2 if 0 <= h <= H, 0 otherwise (the density at h should be proportional to the length of the circumference at height h).
  • r = r( h ) = (H - h) R / H = radius at height h.
妥活 2024-09-05 13:47:11

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

为此,您可以首先选择点之间的距离。当您沿着圆锥体的轴移动时,您可以计算该高度处的周长,然后将周长除以点之间的线性距离以获得点数。然后将 2pi 弧度(或 360 度,或其他)除以点数即可得到该半径的角距离。

根据您需要的精度,您可以在计算下一个圆时跟踪一个圆的余数。例如,如果连续有两个圆圈需要 xxx.4 点,那么如果单独查看,您会将每个圆圈向下舍入 - 但将它们放在一起查看,您有 xxx.8 点,所以您应该一个向下舍入,另一个向上舍入,以使整体密度尽可能接近正确值。

请注意,虽然不是那么明显,但后者也适用于圆柱体——通常在分配每个点圆时会进行一些舍入。

Other answers have already covered the cylinder case pretty well. For the cone, things are a bit more difficult. To maintain a constant density of points, you need to compensate for the change in radius.

To do that, you can start by picking a distance between the points. As you move along the axis of the cone, you compute the circumference at that height, then divide the circumference the linear distance between the points to get the number of points. You then divide 2pi radians (or 360 degrees, or whatever) by the number of points to get the angular distance for that radius.

Depending on the accuracy you need, you can keep track of the remainder from one circle as you're computing the next circle. For example, if you have two circles in a row that work out to needing xxx.4 points, you'd round each down if looked at in isolation -- but looking at them together, you have xxx.8 points, so you should round one down and the other up to keep the overall density as close as possible to the correct value.

Note that although it's not as obvious, the latter can apply to the cylinder as well -- you'll typically have some rounding in distributing each circle of points.

两人的回忆 2024-09-05 13:47:11

将这些答案放在伪代码中:

对于圆柱体,给定圆柱体半径和圆柱体高度:

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) 将位于圆柱体/圆锥体上。生成足够多的这些点,您可以在圆柱体/圆锥体的表面上生成粒子,但它可能不会产生完全均匀的分布......

To put those answers in pseudocode:

For a cylinder, given cylinderRadius and 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.

For a cone, given 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

Each point (x,y,z) will lie on the cylinder/cone. Generate enough of these points and you can spawn particles on the surface of a cylinder/cone, but it may not make an exactly uniform distribution...

魔法唧唧 2024-09-05 13:47:11

对于半径为 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 )

For uniform points on a circle or cone of radius R, and height/elevation 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 )

Note that if you want a base on your cone, you will need to do it separately from the curved shape. To make sure the density of points is the same for the different parts, an easy way is to calculate the areas of the parts and generate a proportional number of points for each part.

The sqrt(value) is what makes sure the density of your random points is uniform. As other questions have mentioned, you want a triangular distribution for this; taking the sqrt() turns the uniform distribution on [0,1) into a triangular one.

For a cylinder you don't want the sqrt(); the curved part is:

  cylinder_point= point3d( R*cos(angle), R*sin(angle), H*value )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文