Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/TriangleNet/Tools/QualityMeasure.cs
2026-03-04 10:03:45 +08:00

271 lines
5.5 KiB
C#

using System;
using TriangleNet.Geometry;
using TriangleNet.Topology;
namespace TriangleNet.Tools
{
public class QualityMeasure
{
private class AreaMeasure
{
public double area_min = double.MaxValue;
public double area_max = double.MinValue;
public double area_total;
public int area_zero;
public void Reset()
{
area_min = double.MaxValue;
area_max = double.MinValue;
area_total = 0.0;
area_zero = 0;
}
public double Measure(Point a, Point b, Point c)
{
double num = 0.5 * Math.Abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
area_min = Math.Min(area_min, num);
area_max = Math.Max(area_max, num);
area_total += num;
if (num == 0.0)
{
area_zero++;
}
return num;
}
}
private class AlphaMeasure
{
public double alpha_min;
public double alpha_max;
public double alpha_ave;
public double alpha_area;
public void Reset()
{
alpha_min = double.MaxValue;
alpha_max = double.MinValue;
alpha_ave = 0.0;
alpha_area = 0.0;
}
private double acos(double c)
{
if (c <= -1.0)
{
return Math.PI;
}
if (1.0 <= c)
{
return 0.0;
}
return Math.Acos(c);
}
public double Measure(double ab, double bc, double ca, double area)
{
double val = double.MaxValue;
double num = ab * ab;
double num2 = bc * bc;
double num3 = ca * ca;
double val2;
double val3;
double val4;
if (ab != 0.0 || bc != 0.0 || ca != 0.0)
{
val2 = ((ca != 0.0 && ab != 0.0) ? acos((num3 + num - num2) / (2.0 * ca * ab)) : Math.PI);
val3 = ((ab != 0.0 && bc != 0.0) ? acos((num + num2 - num3) / (2.0 * ab * bc)) : Math.PI);
val4 = ((bc != 0.0 && ca != 0.0) ? acos((num2 + num3 - num) / (2.0 * bc * ca)) : Math.PI);
}
else
{
val2 = Math.PI * 2.0 / 3.0;
val3 = Math.PI * 2.0 / 3.0;
val4 = Math.PI * 2.0 / 3.0;
}
val = Math.Min(val, val2);
val = Math.Min(val, val3);
val = Math.Min(val, val4);
val = val * 3.0 / Math.PI;
alpha_ave += val;
alpha_area += area * val;
alpha_min = Math.Min(val, alpha_min);
alpha_max = Math.Max(val, alpha_max);
return val;
}
public void Normalize(int n, double area_total)
{
if (n > 0)
{
alpha_ave /= n;
}
else
{
alpha_ave = 0.0;
}
if (0.0 < area_total)
{
alpha_area /= area_total;
}
else
{
alpha_area = 0.0;
}
}
}
private class Q_Measure
{
public double q_min;
public double q_max;
public double q_ave;
public double q_area;
public void Reset()
{
q_min = double.MaxValue;
q_max = double.MinValue;
q_ave = 0.0;
q_area = 0.0;
}
public double Measure(double ab, double bc, double ca, double area)
{
double num = (bc + ca - ab) * (ca + ab - bc) * (ab + bc - ca) / (ab * bc * ca);
q_min = Math.Min(q_min, num);
q_max = Math.Max(q_max, num);
q_ave += num;
q_area += num * area;
return num;
}
public void Normalize(int n, double area_total)
{
if (n > 0)
{
q_ave /= n;
}
else
{
q_ave = 0.0;
}
if (area_total > 0.0)
{
q_area /= area_total;
}
else
{
q_area = 0.0;
}
}
}
private AreaMeasure areaMeasure;
private AlphaMeasure alphaMeasure;
private Q_Measure qMeasure;
private Mesh mesh;
public double AreaMinimum => areaMeasure.area_min;
public double AreaMaximum => areaMeasure.area_max;
public double AreaRatio => areaMeasure.area_max / areaMeasure.area_min;
public double AlphaMinimum => alphaMeasure.alpha_min;
public double AlphaMaximum => alphaMeasure.alpha_max;
public double AlphaAverage => alphaMeasure.alpha_ave;
public double AlphaArea => alphaMeasure.alpha_area;
public double Q_Minimum => qMeasure.q_min;
public double Q_Maximum => qMeasure.q_max;
public double Q_Average => qMeasure.q_ave;
public double Q_Area => qMeasure.q_area;
public QualityMeasure()
{
areaMeasure = new AreaMeasure();
alphaMeasure = new AlphaMeasure();
qMeasure = new Q_Measure();
}
public void Update(Mesh mesh)
{
this.mesh = mesh;
areaMeasure.Reset();
alphaMeasure.Reset();
qMeasure.Reset();
Compute();
}
private void Compute()
{
int num = 0;
foreach (Triangle triangle in mesh.triangles)
{
num++;
Point point = triangle.vertices[0];
Point point2 = triangle.vertices[1];
Point point3 = triangle.vertices[2];
double num2 = point.x - point2.x;
double num3 = point.y - point2.y;
double ab = Math.Sqrt(num2 * num2 + num3 * num3);
double num4 = point2.x - point3.x;
num3 = point2.y - point3.y;
double bc = Math.Sqrt(num4 * num4 + num3 * num3);
double num5 = point3.x - point.x;
num3 = point3.y - point.y;
double ca = Math.Sqrt(num5 * num5 + num3 * num3);
double area = areaMeasure.Measure(point, point2, point3);
alphaMeasure.Measure(ab, bc, ca, area);
qMeasure.Measure(ab, bc, ca, area);
}
alphaMeasure.Normalize(num, areaMeasure.area_total);
qMeasure.Normalize(num, areaMeasure.area_total);
}
public int Bandwidth()
{
if (mesh == null)
{
return 0;
}
int num = 0;
int num2 = 0;
foreach (Triangle triangle in mesh.triangles)
{
for (int i = 0; i < 3; i++)
{
int id = triangle.GetVertex(i).id;
for (int j = 0; j < 3; j++)
{
int id2 = triangle.GetVertex(j).id;
num2 = Math.Max(num2, id2 - id);
num = Math.Max(num, id - id2);
}
}
}
return num + 1 + num2;
}
}
}