using System.Collections; using System.Collections.Generic; using UnityEngine; namespace YKMoon.Math { /// /// 整理的数学公式等等 /// public partial class YKMath { public class Line { public Vector3 p1 = Vector3.zero; public Vector3 p2 = Vector3.zero; public Vector3 dir = Vector3.back; public Line() { } public Line(Vector3 p1, Vector3 p2) { this.p1 = p1; this.p2 = p2; dir = (p2 - p1).normalized; } } public class Plane { public Vector3 normal = Vector3.up; public Vector3 pos = Vector3.zero; } //linePnt - point the line passes through //lineDir - unit vector in direction of line, either direction works //pnt - the point to find nearest on line for public static Vector3 NearestPointOnLine(Vector3 linePnt, Vector3 lineDir, Vector3 pnt) { lineDir.Normalize();//this needs to be a unit vector var v = pnt - linePnt; var d = Vector3.Dot(v, lineDir); return linePnt + lineDir * d; } /// /// 平行于x轴的直线们 /// /// public static List GetTransformHorizontalLines(Transform box) { List result = new List(); BoxCollider col = box.GetComponent(); Vector3 rt = box.TransformPoint(new Vector3(0.5f, 0, 0.5f)); Vector3 rb = box.TransformPoint(new Vector3(0.5f, 0, -0.5f)); Vector3 lb = box.TransformPoint(new Vector3(-0.5f, 0, -0.5f)); Vector3 lt = box.TransformPoint(new Vector3(-0.5f, 0, 0.5f)); result.Add(new Line(lt, rt)); result.Add(new Line(lb, rb)); return result; } /// /// zx平面的直线们 /// /// /// public static List GetTransformLines(Transform box) { List result = new List(); BoxCollider col = box.GetComponent(); Vector3 rt = box.TransformPoint(new Vector3(0.5f, 0, 0.5f)); Vector3 rb = box.TransformPoint(new Vector3(0.5f, 0, -0.5f)); Vector3 lb = box.TransformPoint(new Vector3(-0.5f, 0, -0.5f)); Vector3 lt = box.TransformPoint(new Vector3(-0.5f, 0, 0.5f)); Vector3[] ps = new Vector3[] { rt, rb, lb, lt }; for(int i = 0; i < ps.Length; i++) { GameObject obj = new GameObject(i.ToString()); obj.transform.position = ps[i]; obj.transform.SetParent(box); result.Add(new Line(ps[i], ps[(i + 1) % ps.Length])); } return result; } /// /// 获得zx平面内的transform的四个顶点 /// public static List GetTransformPoints(Transform box) { BoxCollider col = box.GetComponent(); Vector3 rt = box.TransformPoint(new Vector3(0.5f, 0, 0.5f)); Vector3 rb = box.TransformPoint(new Vector3(0.5f, 0, -0.5f)); Vector3 lb = box.TransformPoint(new Vector3(-0.5f, 0, -0.5f)); Vector3 lt = box.TransformPoint(new Vector3(-0.5f, 0, 0.5f)); List result = new List() { rt, rb, lb, lt }; for(int i = 0; i < result.Count; i++) { var t = result[i]; t.y = 0; result[i] = t; } return result; } /// /// 获得zx平面内最接近的transform顶点 /// public static Vector3 GetClosetPositionInRect(Transform trans, Vector3 position, Vector3 dir) { Vector3 result = Vector3.zero; var points = GetTransformPoints(trans); float minDis = float.MaxValue; for(int i = 0; i < points.Count; i++) { var point = points[i]; float dis = Vector3.Cross(dir, point - position).magnitude; if(dis < minDis) { minDis = dis; result = point; } } return result; } /// /// 是否在扇形范围 /// /// 圆心 /// 扇形正方向 /// 半径 /// 左右角度 /// 目标点 /// public static bool IsInSectorYPlane(Vector3 sectorOrigin, Vector3 sectorForward, float sectorRadius, float sectorAngle, Vector3 targetPos) { sectorAngle = MinMaxClamp(sectorAngle, 0, 180); Vector3 dir = GetDirIgnoreYAxis(sectorOrigin, targetPos); Vector3 forward = GetVector3IgnoreYAxis(sectorForward); float dis = GetDistanceIgnoreYAxis(sectorOrigin, targetPos); if(dis > sectorRadius) { return false; } float angle = Vector3.Angle(forward, dir); if(angle <= sectorAngle) { return true; } return false; } } }