【问题标题】:Calculate surface area of a 3D mesh计算 3D 网格的表面积
【发布时间】:2014-10-11 18:25:35
【问题描述】:

我有一个由顶点和三角形定义的 3D 网格。我也有网格的法线。我想计算网格的面积,假设它总是关闭的。我在this question 中找到了一个有趣的 3D 体积计算实现,并将其应用到 C 代码中以构建由 R 调用的函数。代码如下:

double SignedVolumeOfTriangle(double p1X, double p1Y, double p1Z, 
        double p2X, double p2Y, double p2Z, double p3X, double p3Y, double p3Z) {
    double v321 = p3X*p2Y*p1Z;
    double v231 = p2X*p3Y*p1Z;
    double v312 = p3X*p1Y*p2Z;
    double v132 = p1X*p3Y*p2Z;
    double v213 = p2X*p1Y*p3Z;
    double v123 = p1X*p2Y*p3Z;
    return (double)(1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123);
}
void MeshVolume(double *X, double *Y, double *Z, int *numT, int *V1, int *V2, int *V3, double *Volume) {
    int n;          
    *Volume=0;      
    for (n=0; n<*numT; n++) {
        *Volume = *Volume + SignedVolumeOfTriangle(X[V1[n]], Y[V1[n]], Z[V1[n]], X[V2[n]], Y[V2[n]], Z[V2[n]], X[V3[n]], Y[V3[n]], Z[V3[n]]);       
    }
    *Volume = fabs(*Volume);
}

在问题和链接的文章中,我都没有找到计算网格面积的算法。有没有人可以帮帮我?

【问题讨论】:

  • 您咨询过其他来源吗?例如,任何一种“图书馆”......
  • 不,我还没有。但我会以最有效(和最简短)的方式解决问题,可能不使用外部库。
  • ;-) “图书馆”是指他们收集知识的地方之一,例如在过去堆积书籍......
  • :-D 我是一名医生,所以……我经常去的“图书馆”谈论医学、解剖学、生理学等……
  • 尝试从字面上搜索您的问题标题,您会发现一些参考文献,然后返回您的方法,并告诉我们您面临的问题(如果有)...

标签: c r 3d


【解决方案1】:

你有一个封闭的体积,其表面由三角形组成。所有三角形都对外表面有贡献。对吧?

PQR之间的三角形的曲面可以通过:

A = 0.5 * |PQ × PR|
  = 0.5 * |PQ| * |PR| * sin(Ɵ)

在哪里

PQ = Q - P
PR = R - P

× 表示cross productƟ 是向量之间的角度。 (叉积的结果向量的大小是两个原始向量之间的平行四边形的面积。其中一半是三角形的面积。)

对所有三角形的面积求和。不需要取绝对值,因为面积只能为零或正。所以:

double AreaOfTriangle(double p1X, double p1Y, double p1Z, 
        double p2X, double p2Y, double p2Z,
        double p3X, double p3Y, double p3Z)
{
    double ax = p2x - p1x;
    double ay = p2y - p1y;
    double az = p2z - p1z;
    double bx = p3x - p1x;
    double by = p3y - p1y;
    double bz = p3z - p1z;
    double cx = ay*bz - az*by;
    double cy = az*bx - ax*bz;
    double cz = ax*by - ay*bx;

    return 0.5 * sqrt(cx*cx + cy*cy + cz*cz);
}    

void MeshSurface(double *X, double *Y, double *Z,
    int *numT, int *V1, int *V2, int *V3, double *Area)
{
    int n;

    *Area = 0.0;

    for (n=0; n<*numT; n++) {
        *Area += AreaOfTriangle(X[V1[n]], Y[V1[n]], Z[V1[n]],
            X[V2[n]], Y[V2[n]], Z[V2[n]],
            X[V3[n]], Y[V3[n]], Z[V3[n]]);       
    }
}

【讨论】:

  • 谢谢 M Oehm,我还不能投票,但这是我正在寻找的东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 2017-01-02
  • 2016-04-07
相关资源
最近更新 更多