簡體   English   中英

在圓柱/圓錐上均勻生成3D點

[英]uniform generation of 3D points on cylinder/cone

我希望隨機均勻地在圓柱體和圓錐體上生成點(單獨)。 圓柱體由其中心,半徑和高度限定。 錐體的規格相同。 我能夠得到每個形狀的邊界框,所以我想在邊界框內生成點。 但是,我不知道如何將它們投射到圓柱/圓錐上或者這是最好的想法。

有什么建議?

謝謝。

氣缸殼是微不足道的。 如果半徑r> 0且高度h> 0的圓柱是φ∈[0,2π[和z∈[-h]上的(x,y,z)=(rcosφ,rsinφ,z)的圖像/ 2,h / 2],然后在這些間隔上隨機選擇φ和z。 當然,也可以使用標准參數化簡單地對錐體進行參數化,但是面積元素在參數平面上不會是恆定的,因此點的分布不是隨機的。 因此,您需要找到不同的參數化。 我已經在AlgoSim網站上詳細討論了這個主題。

直接在圓柱體或圓錐體上生成點會更簡單。

我做了這個已經有一段時間了,但是參數化圓柱體的軸,然后對於每個點參數化該高度處的圓。 這將在表面上創建點。 圓的半徑是圓柱的半徑。

對於錐體,當您從基部移動到頂點時,需要減小圓的半徑。

想到這一點的一種方法是圓柱體和圓錐體都可以打開平面 - 只需從頂部到底部用直線切割每一個。

圓柱體展開為矩形(如果您包括頂部和底部,則添加幾個磁盤)。

圓錐展開到一個三角形,底部是弧形的圓弧(如果你包括圓錐的底部,那么添加一個圓盤)。

將這些平面嵌入xy平面上的矩形R內很容易。 R生成均勻分布的點,只要它們位於平面內,就將它們映射回原始曲面。

注意這里的一些其他答案,試圖在角度和高度方面協調錐形。 盡管這些點在角度和高度方面均勻分布,但它們不會均勻分布在區域內。 它們將在尖端更密集地分布。

設點由坐標rah定義,其中r是“半徑”(距離中心的垂直軸的距離), a是極坐標中的角度, h是其高度。

對於氣缸 (半徑R和高度H ):獨立選擇

  • [0,2pi]中制服,
  • h均勻[0, H ]和
  • r具有“三角形密度”:f( r )= 2 r / R如果0 <= r <= R ,則0(否則r處的密度應與半徑r的圓周長度成比例)。

從這種三角形分布中抽樣應該不難,因為它的累積分布(二次單項式)很容易可逆(見本文 )。 此外,這個答案是基於直覺,但是要證明你在氣缸上獲得的分布是均勻的並不難。

對於錐體 (半徑R和高度H ):選擇

  • [0,2pi]中制服,
  • h用一段拋物線制成的密度:f( h )= 3( H - h )^ 2 / H ^ 3如果0 <= h <= H ,則0(否則h處的密度應與面積成比例)高度為h )的圓形截面,
  • rh )=( H - hR / H (高度為h的截面半徑); 然后選擇具有“三角分布” F(R)= 2 R / R(h)如0 <= R <= R(h) ,否則為0

同樣,采樣h應該很容易,因為累積分布很容易反轉。

編輯。 如果您想在形狀表面上生成點,則解決方案更簡單:

氣缸 :選擇

  • [0,2pi]中制服,
  • h在[0, H ]中均勻,
  • r = R.

:選擇

  • [0,2pi]中制服,
  • h具有三角形密度:f( h )= 2( H - h )/ H ^ 2如果0 <= h <= H ,則否則為0( h處的密度應與高度h處的圓周長度成比例) 。
  • r = rh )=( H - hR / H =高度h處的半徑。

其他答案已經很好地涵蓋了氣缸外殼。 對於錐形,事情有點困難。 要保持恆定的點密度,您需要補償半徑的變化。

要做到這一點,您可以從點之間選擇一個距離開始。 當您沿着圓錐軸移動時,您可以計算該高度的圓周,然后將圓周除以點之間的直線距離以獲得點數。 然后,您將2pi弧度(或360度,或其他)除以點數,以獲得該半徑的角距離。

根據您所需的精度,您可以在計算下一個圓時跟蹤一個圓的余數。 例如,如果連續兩個圓圈需要xxx.4點,那么如果孤立地查看它們就會向下舍入 - 但是一起看它們,你有xxx.8點,所以你應該這樣做第一個向下,另一個向上,以保持整體密度盡可能接近正確的值。

請注意,雖然它不那么明顯,后者也可以應用於圓柱體 - 通常在分布每個圓點時會有一些圓角。

將這些答案放在偽代碼中:

對於圓柱體,給定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)將位於圓柱體/圓錐體上。 生成足夠的這些點,你可以在圓柱/圓錐的表面上產生粒子,但它可能不會產生完全均勻的分布......

對於半徑為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 )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM