我想知道,在数学上,如何在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方法更好
如何做表面样子?我假设你希望这个点是随机的,与你当地的三角形密度无关。我曾经做过类似的事情,一种方法是产生随机直线,然后将它们与表面“交叉”,即通过投影到垂直平面上,然后最小化投影距离分量的平方和。现在的事情是,如何生成随机直线......取决于你所拥有的曲面种类 –