我想知道,在數學上,如何在3D表面上的隨機位置生成x個點,知道組成曲面的三角形多邊形的數量(它們的尺寸,位置,法線,等等。)?你會在多少步驟中進行?在任意三維表面上生成隨機點
我想在Maya中創建一個「scatterer」(使用Python和API),但我甚至不知道從概念開始從哪裏開始。我應該先生成點,然後檢查它們是否屬於表面?我應該直接在表面創建點(以及在這種情況下如何)?
編輯:我想在不使用2D投影或UV的情況下儘可能達到此目的。
我想知道,在數學上,如何在3D表面上的隨機位置生成x個點,知道組成曲面的三角形多邊形的數量(它們的尺寸,位置,法線,等等。)?你會在多少步驟中進行?在任意三維表面上生成隨機點
我想在Maya中創建一個「scatterer」(使用Python和API),但我甚至不知道從概念開始從哪裏開始。我應該先生成點,然後檢查它們是否屬於表面?我應該直接在表面創建點(以及在這種情況下如何)?
編輯:我想在不使用2D投影或UV的情況下儘可能達到此目的。
您應計算每個三角形的面積,並將其用作權重來確定每個隨機點的目的地。這可能是最容易做到這一點作爲批處理操作:
def sample_areas(triangles, samples):
# compute and sum triangle areas
totalA = 0.0
areas = []
for t in triangles:
a = t.area()
areas.append(a)
totalA += a
# compute and sort random numbers from [0,1)
rands = sorted([random.random() for x in range(samples)])
# sample based on area
area_limit = 0.0
rand_index = 0
rand_value = rands[rand_index]
for i in range(len(areas)):
area_limit += areas[i]
while rand_value * totalA < area_limit:
# sample randomly over current triangle
triangles[i].add_random_sample()
# advance to next sorted random number
rand_index += 1;
if rand_index >= samples:
return
rand_value = rands[rand_index]
注意,脊或皺地區可能出現有較高的點密度,僅僅是因爲他們有一個更小的空間更多的表面積。
感謝您的回答,我試圖在python代碼中重寫您的僞代碼,但我有問題「翻譯」循環部分,請您給我更多細節或評論來解釋它是如何工作的?再次感謝您 – UKDP
我已經用python重寫了僞代碼。未經測試,所以值得你付出的代價... – comingstorm
這裏是僞代碼,可能是一個很好的起點:
如果約束條件是所有輸出點都在表面上,那麼您需要一種一致的方法來處理曲面本身,而不用擔心點的3d>曲面轉換。這樣做的hacktastic方法是爲你的3D對象創建一個UV貼圖,然後在2維中隨機地散點(扔掉掉在有效的UV殼內的地方)。一旦你的UV殼充滿了你想要的,你可以將你的UV點轉換爲barycentric coordinates將這些2-d點轉換回3-d點:實際上你說「我30%的頂點A,30%頂點B和頂點C的40%,所以我的位置是(.3A + .3B + .4C)
除了簡單之外,使用的另一個優點是UV貼圖可以讓您自定義密度和相對重要性網格的不同部分:較大的UV面會得到大量的散點,而較小的面則會更少 - 即使這與實際大小或面不匹配。因爲你可能無法拿出無拉伸和無縫的UV貼圖,所以你會得到變化因爲你的分散密度。但是對於許多應用來說,這很好,因爲算法非常簡單,並且結果易於手動調整。
我沒有使用過這一個,但這看起來像是基於這種一般方法:http://www.shanemarks.co.za/uncategorized/uv-scatter-script/
如果你需要一個更嚴格的數學方法,你需要的mesh parameterization票友方法:一種方法,把你的三維三角形收集成一個一致的空間。在該領域有許多有趣的工作,但如果不知道應用程序,就很難選擇特定的路徑。
我的醜MEL腳本:
//Select poly and target object
{
$sel = `ls -sl -fl`; select $sel[0];
polyTriangulate -ch 0;
$poly_s = `polyListComponentConversion -toFace`;$poly_s = `ls -fl $poly_s`;//poly flat list
int $numPoly[] = `polyEvaluate -fc`;//max random from number of poly
int $Rand = rand($numPoly[0]);//random number
$vtx_s =`polyListComponentConversion -tv $poly_s[$Rand]`;$vtx_s=`ls- fl $vtx_s`;//3 vertex from random poly flat list
undo; //for polyTriangulate
vector $A = `pointPosition $vtx_s[0]`;
vector $B = `pointPosition $vtx_s[1]`;
vector $C = `pointPosition $vtx_s[2]`;
vector $AB = $B-$A; $AB = $AB/mag($AB); //direction vector and normalize
vector $AC = $A-$C; $AC = $AC/mag($AC); //direction vector and normalize
$R_AB = mag($B-$A) - rand(mag($B-$A)); vector $AB = $A + ($R_AB * $AB);//new position
$R_AC = mag($A-$C) - rand(mag($A-$C)); vector $AC = $C + ($R_AC * $AC);//new position
vector $ABC = $AB-$AC; $ABC = $ABC/mag($ABC); //direction vector and normalize
$R_ABC = mag($AB-$AC) - rand(mag($AB-$AC)); //random
vector $ABC = $AC + ($R_ABC * $ABC);
float $newP2[] = {$ABC.x,$ABC.y,$ABC.z};//back to float
move $newP2[0] $newP2[1] $newP2[2] $sel[1];
select -add $sel[1];
}
PS UV方法更好
如何做表面樣子?我假設你希望這個點是隨機的,與你當地的三角形密度無關。我曾經做過類似的事情,一種方法是產生隨機直線,然後將它們與表面「交叉」,即通過投影到垂直平面上,然後最小化投影距離分量的平方和。現在的事情是,如何生成隨機直線......取決於你所擁有的曲面種類 –