This commit is contained in:
MuHua-123
2024-11-25 18:32:05 +08:00
parent 72d1f89b54
commit 84243e75a8
353 changed files with 17666 additions and 3206 deletions
@@ -0,0 +1,58 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
/// <summary>
/// 算法:中心角度排序法
/// 依据:???
/// </summary>
public class AlgorithmEdge : ModuleAlgorithm<DataPlate> {
/// <summary> 算法:中心角度排序法 </summary>
public AlgorithmEdge() { }
public class EdgeAngle {
public float angle;
public Vector3 position;
}
public override void Compute(DataPlate data) {
//List<Vector2> edgePoints = data.edgePoints;
////计算多边形中心点
//float x = edgePoints.Average((v3) => v3.x);
//float y = edgePoints.Average((v3) => v3.y);
//Vector2 center = new Vector2(x, y);
////计算所有点的夹角
//Vector3 direction = edgePoints[0] - center;
//List<EdgeAngle> angleList = new List<EdgeAngle>();
//for (int i = 0; i < edgePoints.Count; i++) {
// Vector3 normal = edgePoints[i] - center;
// EdgeAngle edgeAngle = new EdgeAngle();
// edgeAngle.angle = Angle(direction, normal);
// edgeAngle.position = normal;
// angleList.Add(edgeAngle);
//}
//data.centerOffset = center;
////排序
//angleList.Sort((x, y) => x.angle.CompareTo(y.angle));
////把排序好的边缘点重新添加
//data.edgePoints = new List<Vector2>();
//for (int i = 0; i < angleList.Count; i++) {
// data.edgePoints.Add(angleList[i].position);
//}
}
/// <summary>
/// 计算两点夹角
/// </summary>
/// <param name="direction">0度点位置</param>
/// <param name="position">目标点</param>
/// <returns></returns>
private float Angle(Vector3 direction, Vector3 position) {
float angle = Vector2.SignedAngle(direction, position);
return angle;
}
protected override void Awake() {
throw new System.NotImplementedException();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d17cdf61cce7657489b657640646a786
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 计算位置到边上最近的点
/// </summary>
public class AlgorithmSidePoint : ModuleAlgorithm<DataIntersect> {
protected override void Awake() => ModuleCore.AlgorithmSidePoint = this;
public override void Compute(DataIntersect data) {
Vector3 position = data.position - data.side.plate.designPosition;
for (int i = 0; i < data.side.lines.Length; i++) {
DataLine line = data.side.lines[i];
if (!Compute(line, position, out Vector3 intersectPoint)) { continue; }
data.isIntersect = true;
data.intersectPoint = intersectPoint + data.side.plate.designPosition;
return;
}
}
/// <summary> 查询匹配的边 </summary>
private bool Compute(DataLine line, Vector3 position, out Vector3 intersectPoint) {
return ProjectDistance(line.a, line.b, position, out intersectPoint);
}
/// <summary>
/// 向量投影法
/// 计算点c到线段ab最近的点
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <returns>如果不在线段上返回 false</returns>
public static bool ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
Vector3 ab = b - a;
Vector3 ac = c - a;
Vector3 p = Vector3.Project(ac, ab.normalized);
intersectPoint = p + a;
if (ab.normalized != p.normalized) { return false; }
if (ab.magnitude < p.magnitude) { return false; }
return true;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a76476370cd578b489a2b37297d054f9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 散列点生成简单多边形算法
/// </summary>
public class AlgorithmSimplePolygon : ModuleAlgorithm<DataPlate> {
private UnitAlgorithm<DataPlate> AlgorithmSideSubdivision = new UnitAlgorithmBezier();
private UnitAlgorithm<DataPlate> AlgorithmTriangle = new UnitAlgorithmEarCutting();
private UnitAlgorithm<DataPlate> AlgorithmMergeTriangle = new UnitAlgorithmMergeTriangle();
protected override void Awake() => ModuleCore.AlgorithmSimplePolygon = this;
public override void Compute(DataPlate data) {
//遍历计算边(DataSide)上的细分点(positions)和线(lines)
AlgorithmSideSubdivision.Compute(data);
//计算三角面
AlgorithmTriangle.Compute(data);
//三角面列表转换网格
AlgorithmMergeTriangle.Compute(data);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef8ce839dfa79ff4d825f55925c48e7c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,41 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 细分多边形算法
/// </summary>
public class AlgorithmSubdivisionPolygon : ModuleAlgorithm<DataPlate> {
private UnitAlgorithm<DataPlate> AlgorithmSideSubdivision = new UnitAlgorithmBezier();
private UnitAlgorithm<DataPlate> AlgorithmBorder = new UnitAlgorithmBorder();
private UnitAlgorithm<DataPlate> AlgorithmVertex = new UnitAlgorithmVertex();
private UnitAlgorithm<DataPlate> AlgorithmTriangle = new UnitAlgorithmRhombus();
private UnitAlgorithm<DataPlate> AlgorithmMergeTriangle = new UnitAlgorithmMergeTriangle();
protected override void Awake() => ModuleCore.AlgorithmSubdivisionPolygon = this;
public override void Compute(DataPlate data) {
//遍历计算边(DataSide)上的细分点(positions)和线(lines)
Chronoscope("遍历计算边(DataSide)上的细分点(positions)和线(lines)消耗时间:", () => AlgorithmSideSubdivision.Compute(data));
//计算多边形边界
Chronoscope("计算多边形边界消耗时间:", () => AlgorithmBorder.Compute(data));
//计算顶点
Chronoscope("计算顶点消耗时间:", () => AlgorithmVertex.Compute(data));
//计算三角面
Chronoscope("计算三角面消耗时间:", () => AlgorithmTriangle.Compute(data));
//三角面列表转换网格
Chronoscope("三角面列表转换网格消耗时间:", () => AlgorithmMergeTriangle.Compute(data));
}
/// <summary> 是否启用计时器 </summary>
private readonly bool isEnableTimer = true;
/// <summary> 计时器 </summary>
private void Chronoscope(string content, Action action) {
if (!isEnableTimer) { action?.Invoke(); return; }
float time = Time.realtimeSinceStartup;
action?.Invoke();
float consumed = Time.realtimeSinceStartup - time;
Debug.Log($"{content}{consumed * 1000}");
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2414983cb247d574fad8f47f71c42fdb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,67 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 缝合边算法模块
/// </summary>
public class AlgorithmSutureSide : ModuleAlgorithm<DataSutureSide> {
public class VertexPosition : IComparable<VertexPosition> {
public Vector3 designPosition;
public Vector3 bakingPosition;
public float distance;
public int CompareTo(VertexPosition other) {
return other.distance >= distance ? 1 : -1;
}
}
protected override void Awake() => ModuleCore.AlgorithmSutureSide = this;
public override void Compute(DataSutureSide data) {
//List<VertexPosition> vertexPositions = VertexPositions(data);
data.designPositions = VertexToDesignPositions(data).ToArray();
data.bakingPositions = VertexToBakingPositions(data).ToArray();
}
private List<VertexPosition> VertexPositions(DataSutureSide sutureSide) {
List<VertexPosition> vertexPositions = new List<VertexPosition>();
for (int i = 0; i < sutureSide.Vertices.Length; i++) {
Vector3 design = sutureSide.Vertices[i].design;
Quaternion quaternion = Quaternion.Euler(sutureSide.PlateBakingEulerAngles);
Vector3 baking = quaternion * sutureSide.Vertices[i].design;
VertexPosition vertexPosition = new VertexPosition();
vertexPosition.designPosition = design + sutureSide.PlateDesignPosition;
vertexPosition.bakingPosition = baking + sutureSide.PlateBakingPosition;
vertexPosition.distance = Vector3.Distance(design, sutureSide.side.aPoint.position);
vertexPositions.Add(vertexPosition);
}
//按距离从小到大排序
vertexPositions.Sort();
//是否颠倒
if (sutureSide.isReversal) { vertexPositions.Reverse(); }
return vertexPositions;
}
private List<Vector3> VertexToDesignPositions(DataSutureSide data) {
//转换列表
List<Vector3> positions = new List<Vector3>();
for (int i = 0; i < data.Vertices.Length; i++) {
Vector3 position = data.Vertices[i].design + data.PlateDesignPosition;
positions.Add(position);
}
if (data.isReversal) { positions.Reverse(); }
return positions;
}
private List<Vector3> VertexToBakingPositions(DataSutureSide data) {
//转换列表
List<Vector3> positions = new List<Vector3>();
for (int i = 0; i < data.Vertices.Length; i++) {
Quaternion quaternion = Quaternion.Euler(data.PlateBakingEulerAngles);
Vector3 baking = quaternion * data.Vertices[i].design;
Vector3 position = baking + data.PlateBakingPosition;
positions.Add(position);
}
if (data.isReversal) { positions.Reverse(); }
return positions;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2883f9190b57bdc41a4458a5c9e16f53
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 算法模块
/// </summary>
/// <typeparam name="Data"></typeparam>
public abstract class ModuleAlgorithm<Data> : MonoBehaviour {
/// <summary> 必须要初始化 </summary>
protected abstract void Awake();
/// <summary> 核心模块 </summary>
protected virtual ModuleCore ModuleCore => ModuleCore.I;
/// <summary> 执行算法 </summary>
public abstract void Compute(Data data);
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 080083324a409f24788f08ea7c670304
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: