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;
}
}
}