在任意三维su上生成随机点

2024-09-28 05:26:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我在想,从数学上讲,你如何在一个3D曲面上随机生成x点,知道组成曲面的三角形多边形的数量(它们的尺寸、位置、法线等)?你将分几步进行?在

我试图在Maya中创建一个“散射体”(使用Python和API),但我甚至不知道从概念上从哪里开始。我应该先生成点,然后检查它们是否属于曲面吗?我是否应该直接在曲面上创建点(在这种情况下,如何创建点)?在

编辑:我希望尽可能不使用2D投影或UV来实现这一点。在


Tags: api概念编辑数量尺寸情况数学多边形
3条回答

如果约束条件是所有输出点都在曲面上,则需要使用一致的方法来处理曲面本身,而不是担心点的三维曲面转换。在

hacktastic的方法是为你的3d对象创建一个UV贴图,然后在2维中随机散布点(丢弃那些没有落在有效的UV壳中的点)。一旦UV壳被尽可能多地填满,就可以将UV点转换为barycentric coordinates以将这些二维点转换回三维点:实际上,你说“我是30%的顶点A,30%的顶点B和40%的顶点C,所以我的位置是(.3A+.3B+.4C)

除了简单之外,使用“UV贴图”的另一个优点是,它允许您自定义网格不同部分的密度和相对重要性:较大的UV面将获得大量散射点,而较小的UV面将减少散射点,即使这与物理大小或面不匹配。在

使用2D将引入一些瑕疵,因为您可能无法获得既无拉伸又无接缝的UV贴图,因此您将获得散射密度的变化。然而对于许多应用来说,这是很好的,因为算法非常简单,结果也很容易手工调整。在

我没有使用过这个方法,但是看起来它是基于这个通用方法:http://www.shanemarks.co.za/uncategorized/uv-scatter-script/

如果你需要一个数学上更严格的方法,你需要一个更奇特的方法mesh parameterization:一种将你的三维三角形集合转换成一致空间的方法。在这个领域有很多有趣的工作,但是在不了解应用程序的情况下很难选择特定的路径。在

你应该计算每个三角形的面积,并用这些作为权重来确定每个随机点的目的地。作为批处理操作执行此操作可能最简单:

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]

请注意,起皱或起皱区域可能看起来具有更高的点密度,这只是因为它们在较小的空间中具有更多的表面积。在

  1. 从随机三角形中随机选取2条边。在
  2. 在边上创建2个随机点。在
  3. 在它们之间创建新的随机点。在

我丑陋的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法较好

相关问题 更多 >

    热门问题