一半君的总结纸

听话只听一半君

#90 如何得知一个多边形的面是不是平面?

下面的 MEL 代码可以用来检测一个多边形的面是不是平面.

下面贴出来的代码只有部分错误检查. 下载的版本里有更多的错误检查.(源文件已经不知所踪了,以后如果找到我会加上来)

global proc int isPlanar( string $mesh, int $face )
{
  // 得到这个面上的所有点
  string $vertices[] = `polyListComponentConversion -toVertex ( $mesh + ".f[" + $face + "]" )`;

  // 因为 -toVertex 返回的结果是没有展开的,也就是说可能会有[1:3],所以下面先选择这些点,然后展开他们

  select -r $vertices;
  $vertices = `filterExpand -sm 31 -ex true`;

  // 如果这个平面是三角面(只有3个顶点), 废话那他显然是平面.
  if ( size( $vertices ) == 3 )
    return true;

  // 找到平面上的前3个点ABC
  float $f0[3] = `xform -ws -q -t $vertices[0]`;
  float $f1[3] = `xform -ws -q -t $vertices[1]`;
  float $f2[3] = `xform -ws -q -t $vertices[2]`;

  // 随便算两个矢量(比如下面就得到了BA 和 CA)
  vector $v1 = << $f1[0], $f1[1], $f1[2] >> - << $f0[0], $f0[1], $f0[2] >>;
  vector $v2 = << $f2[0], $f2[1], $f2[2] >> - << $f0[0], $f0[1], $f0[2] >>;

  // BA和CA叉乘一下就得到了这三个点组成的平面的法线方向(初中数学)
  vector $normal = unit( $v1 ^ $v2 );

  // 从第4个点开始,假设是D,那下面首先算了DA这个矢量,如果DA点乘上面算出的面法线矢量是0,那说明DA和normal是垂直的(也就是说D是在上面的ABC平面里的)
  for ( $v = 3; $v < size( $vertices ); $v++ )
  {
    float $f[3] = `xform -ws -q -t $vertices[$v]`;
    vector $vp  = << $f[0] - $f0[0], $f[1] - $f0[1], $f[2] - $f0[2] >>;

    // 把上面的矢量和法线点乘一下
    float $dot = $vp * $normal;

    // 如果点乘结果不等于0, 那说明点D不在ABC平面里
    if ( $dot != 0 )
      return false;
  }

  // 此平面是平的
  return true;
}

Tuesday, December 05, 2000

好吧,pymel虽然卡,但有时候还是挺短的,比如这里:

def isPlanar(mesh, face):
    f = pm.PyNode('%s.f[%d]' % (mesh, face))
    return f.isPlanar()

我就不把第一段翻译成python了,感觉没啥意义

Related How-To’s

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: