Unity 计算任意形状模型物体的体积

Unity 计算任意形状模型物体的体积

  • 基本思想
  • 实现方法
  • 示例演示
  • 参考链接

基本思想

    计算任意模型体积的基本思想是体素化。我们可以首先计算出物体的包围盒大小,然后在包围盒内均匀等间隔的取点,最后计算点落在物体内与采样总点数的比值,即可求出模型的体积。

实现方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;public class Volume : MonoBehaviour
{private int sampleCount = 100;//每个方向选取100个点,包围盒内一共选取了100万个点private void Start(){float volume = CalculateVolume();}//检测点是否在模型内部bool IsInCollider(MeshCollider other, Vector3 center, Vector3 point){Vector3 direction = center - point;RaycastHit[] hits = Physics.RaycastAll(point, direction);foreach (RaycastHit hit in hits){if (hit.collider == other){// we hit it so we were outside itreturn false;}}// no hits probably means we're inside itreturn true;}public float CalculateVolume(){GameObject object1 = GameObject.Find("object1");//更改为场景中要计算体积的物体的名称MeshCollider object1_mc = object1.GetComponent<MeshCollider>();Vector3 object1_center = object1_mc.bounds.center;Matrix4x4 localToWorld_object1 = object1.transform.localToWorldMatrix;Vector3[] vertices_object1 = object1.GetComponent<MeshFilter>().mesh.vertices;float[] x = new float[vertices_object1.Length];float[] y = new float[vertices_object1.Length];float[] z = new float[ vertices_object1.Length];//将局部坐标转换为世界坐标,并传递给数组for (int i = 0; i < vertices_object1.Length; i++){Vector3 world_v = localToWorld_object1.MultiplyPoint3x4(vertices_object1[i]);x[i] = world_v.x;y[i] = world_v.y;z[i] = world_v.z;}//从小到大排序Array.Sort(x);Array.Sort(y);Array.Sort(z);//包围盒三边长度float x_length = x[x.Length - 1] - x[0];float y_length = y[y.Length - 1] - y[0];float z_length = z[z.Length - 1] - z[0];//选点步长float lerp_x = x_length / sampleCount;float lerp_y = y_length / sampleCount;float lerp_z = z_length / sampleCount;int pointInside = 0;for (int i = 0; i < sampleCount; i++){for (int j = 0; j < sampleCount; j++){for (int k = 0; k < sampleCount; k++){Vector3 sampleDot = new Vector3(x[0] + i * lerp_x, y[0] + j * lerp_y, z[0] + k * lerp_z);if (IsInCollider(object1_mc, object1_center, sampleDot)){pointInside++;}}}}//计算模型体积,单位为立方米float volume = (float)pointInside / (sampleCount * sampleCount * sampleCount) * (x_length * y_length * z_length);Debug.Log("Volume:"+ volume);return volume;}private void Update(){}
}

示例演示

在场景中添加一个cube,命名为object1,边长为1,计算得出体积为1,没有误差。在这里插入图片描述
在场景中添加一个椭球体sphere,命名为object1,三个径分别为2,1,0.5,计算得出体积0.495,实际体积0.52,误差4%,误差与体素化的精度有关。
在这里插入图片描述

参考链接

https://zhuanlan.zhihu.com/p/382365328
https://answers.unity.com/questions/1600764/point-inside-mesh.html


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部