基本思想
????计算任意模型体积的基本思想是体素化。我们可以首先计算出物体的包围盒 大小,然后在包围盒内均匀等间隔的取点,最后计算点落在物体内与采样总点数的比值 ,即可求出模型的体积。
实现方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Volume : MonoBehaviour
{
private int sampleCount = 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)
{
return false;
}
}
return 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
|