【问题标题】:How calculate a volume of this mesh 3D?如何计算这个网格 3D 的体积?
【发布时间】:2014-12-18 01:15:54
【问题描述】:

我在做一个项目。我们生成了一个 3D 网格,我需要计算一个 3D 对象的几个体积。

我不知道如何计算,我认为数学知识太少了。有没有办法计算这个

EDTI:我不是在寻找所有代码,而是在寻找方向或伪代码

【问题讨论】:

  • 在此处发布您的代码/信息。没有人愿意去外部网站帮忙
  • @JonathonReinhart 图片添加

标签: 3d kinect


【解决方案1】:

我相信你会通过一个要求计算胸部体积的标题得到更多回应:)。

首先,为了计算网格的体积,它应该是一个封闭的网格。所以我认为你需要选择你不需要的面/顶点并将它们从网格中删除。 比找到关闭音量的方法:

  • 在 Meshlab 中:尝试点集下的泊松选项
  • 或使用即 Blender 手动关闭音量

一旦完成,根据this paper 就变得容易了。

诀窍是计算四面体的有符号体积 - 基于您的三角形并在原点处达到顶峰。体积的符号来自你的三角形是否指向原点的方向。 (三角形的法线本身取决于顶点的顺序,这就是为什么下面没有明确引用它的原因。)

这一切都归结为以下简单的功能:

float signedVolumeOfTriangle(pcl::PointXYZ p1, pcl::PointXYZ p2, pcl::PointXYZ p3) 
{
    float v321 = p3.x*p2.y*p1.z;
    float v231 = p2.x*p3.y*p1.z;
    float v312 = p3.x*p1.y*p2.z;
    float v132 = p1.x*p3.y*p2.z;
    float v213 = p2.x*p1.y*p3.z;
    float v123 = p1.x*p2.y*p3.z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

然后是计算网格体积的函数:

float volumeOfMesh(pcl::PolygonMesh mesh) 
{
    float vols = 0.0;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPointCloud2(mesh.cloud,*cloud);
    for(int triangle=0;triangle<mesh.polygons.size();triangle++)
    {
        pcl::PointXYZ pt1 = cloud->points[mesh.polygons[triangle].vertices[0]];
        pcl::PointXYZ pt2 = cloud->points[mesh.polygons[triangle].vertices[1]];
        pcl::PointXYZ pt3 = cloud->points[mesh.polygons[triangle].vertices[2]];
        vols += signedVolumeOfTriangle(pt1, pt2, pt3);
    }
    return Math.Abs(vols.Sum());
}

我没有测试代码,不知道您是否可以使用 PCL,但这应该可以帮助您入门。

【讨论】:

  • 只有我今天无法访问他们的网站。应该重新开始工作。
【解决方案2】:

我已经用ubuntu-18.04的pcl-1.8.1完成了@Deepfreeze的代码。论文 url 链接更新,click here. 注意代码应该是“pcl::fromPCLPointCloud2”

main.cpp

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/obj_io.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/conversions.h>
#include <cmath>
float signedVolumeOfTriangle (pcl::PointXYZ p1, pcl::PointXYZ p2, pcl::PointXYZ p3) 
{
    float v321 = p3.x*p2.y*p1.z;
    float v231 = p2.x*p3.y*p1.z;
    float v312 = p3.x*p1.y*p2.z;
    float v132 = p1.x*p3.y*p2.z;
    float v213 = p2.x*p1.y*p3.z;
    float v123 = p1.x*p2.y*p3.z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

float volumeOfMesh(pcl::PolygonMesh mesh) 
{
    float vols = 0.0;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
    for(int triangle=0;triangle<mesh.polygons.size();triangle++)
    {
        pcl::PointXYZ pt1 = cloud->points[mesh.polygons[triangle].vertices[0]];
        pcl::PointXYZ pt2 = cloud->points[mesh.polygons[triangle].vertices[1]];
        pcl::PointXYZ pt3 = cloud->points[mesh.polygons[triangle].vertices[2]];
        vols += signedVolumeOfTriangle(pt1, pt2, pt3);
    }
    return abs(vols);
}

int main(int argc, char **argv) {
    pcl::PolygonMesh mesh;
    pcl::io::loadOBJFile(argv[1], mesh);
    std::cout << volumeOfMesh(mesh) << std::endl;
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(mesh_volume)

find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (${PROJECT_NAME} main.cpp)
target_link_libraries (${PROJECT_NAME} ${PCL_LIBRARIES})

【讨论】:

  • 虽然六年过去了,但我们仍然努力争取获得胸部的大小。在我看来,它们不亚于 B 杯。
猜你喜欢
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
相关资源
最近更新 更多