using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 查询边交点
///
public class FindSideIntersectPoint : UnitFind {
public readonly float FindRange = 0.01f;
/// 板片资产
public ModuleAssets AssetsPlate => ModuleCore.I.AssetsPlate;
/// 查询边交点
public FindSideIntersectPoint() { }
public bool Find(Vector3 position, out SideIntersectPoint sip) {
sip = new SideIntersectPoint();
List plates = AssetsPlate.Datas;
for (int i = 0; i < plates.Count; i++) {
Vector3 localPosition = position - plates[i].dataDesign.position;
sip.side = Find(plates[i], localPosition, out sip.intersectPoint);
sip.intersectPoint += plates[i].dataDesign.position;
if (sip.side != null) { return true; }
}
return false;
}
/// 查询匹配的边
private DataPlateSide Find(DataPlate plate, Vector3 localPosition, out Vector3 intersectPoint) {
intersectPoint = Vector3.zero;
for (int i = 0; i < plate.plateSides.Count; i++) {
DataPlateSide side = Find(plate.plateSides[i], localPosition, out intersectPoint);
if (side != null) { return side; }
}
return null;
}
/// 查询匹配的边
private DataPlateSide Find(DataPlateSide side, Vector3 localPosition, out Vector3 intersectPoint) {
intersectPoint = Vector3.zero;
for (int i = 0; i < side.dataDesign.lines.Length; i++) {
Vector3 a = side.dataDesign.lines[i].a;
Vector3 b = side.dataDesign.lines[i].b;
float distance = ProjectDistance(a, b, localPosition, out intersectPoint);
if (distance < FindRange) { return side; }
}
return null;
}
///
/// 向量投影法
/// 计算点c到线段ab最近的点
///
///
///
///
/// 如果不在线段上返回 float.MaxValue
public static float ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
Vector3 ab = b - a;
Vector3 ac = c - a;
Vector3 p = Vector3.Project(ac, ab);
intersectPoint = p + a;
if (ab.normalized != p.normalized) { return float.MaxValue; }
if (ab.magnitude < p.magnitude) { return float.MaxValue; }
return Vector3.Distance(c, p + a);
}
}
///
/// 边交点
///
public class SideIntersectPoint {
/// 匹配的边
public DataPlateSide side;
/// 交点
public Vector3 intersectPoint;
}