#if UNITY_EDITOR using UnityEngine; using System.Collections.Generic; namespace O3DWB { public class Polygon3D { #region Private Variables private Vector3 _normal; private List _pointsOnPolygonPlane = new List(); private List _edges = new List(); #endregion #region Public Properties public Vector3 Normal { get { return _normal; } } public Plane Plane { get { return NumberOfPoints != 0 ? new Plane(Normal, _pointsOnPolygonPlane[0]) : new Plane(); } } public List PointsOnPolygonPlane { get { return new List(_pointsOnPolygonPlane); } } // Note: In no particular order! public List Edges { get { return new List(_edges); } } // Note: In no particular order! public int NumberOfPoints { get { return _pointsOnPolygonPlane.Count; } } #endregion #region Public Static Functions public static Plane GetPolygonEdgePlane(Segment3D polyEdge, Vector3 polyNormal) { Vector3 planeNormal = Vector3.Cross(polyEdge.Direction, polyNormal); planeNormal.Normalize(); return new Plane(planeNormal, polyEdge.StartPoint); } #endregion #region Public Methods public List GetEdgeRays() { if (NumberOfPoints < 3) return new List(); var rays = new List(NumberOfPoints); foreach(var segment in _edges) { rays.Add(new Ray3D(segment.StartPoint, segment.Direction)); } return rays; } public void SetPointsOnPolygonPlaneAndNormal(List pointsOnPolygonPlane, Vector3 polygonNormal) { _normal = polygonNormal; _normal.Normalize(); var quickHull = new Polygon3DQuickHull(pointsOnPolygonPlane, polygonNormal); _edges = quickHull.Calculate(); _pointsOnPolygonPlane.Clear(); foreach(var edge in _edges) { _pointsOnPolygonPlane.Add(edge.StartPoint); _pointsOnPolygonPlane.Add(edge.EndPoint); } Vector3Extensions.EliminateDuplicatePoints(_pointsOnPolygonPlane); } public bool ContainsAnyPoint(List points) { foreach(Vector3 point in points) { if (ContainsPoint(point)) return true; } return false; } public bool ContainsPoint(Vector3 point) { if(NumberOfPoints < 3) return false; if (!Plane.IsPointOnPlane(point)) return false; foreach(var edge in _edges) { Plane edgePlane = GetPolygonEdgePlane(edge, _normal); if (edgePlane.IsPointInFront(point)) return false; } return true; } #endregion } } #endif