123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- using System.Collections.Generic;
- using UnityEngine;
- namespace VLB
- {
- public class PolygonHelper : MonoBehaviour
- {
- public struct Plane2D
- {
- public Vector2 normal;
- public float distance;
- public float Distance(Vector2 point) { return Vector2.Dot(normal, point) + distance; }
- public Vector2 ClosestPoint(Vector2 pt) { return pt - normal * Distance(pt); }
- public Vector2 Intersect(Vector2 p1, Vector2 p2)
- {
- float denominator = Vector2.Dot(normal, p1 - p2);
- if (Utils.IsAlmostZero(denominator))
- return (p1 + p2) * 0.5f;
- float u = (normal.x * p1.x + normal.y * p1.y + distance) / denominator;
- return (p1 + u * (p2 - p1));
- }
- public bool GetSide(Vector2 point) { return Distance(point) > 0.0f; }
- public static Plane2D FromPoints(Vector3 p1, Vector3 p2)
- {
- var v = (p2 - p1).normalized;
- return new Plane2D
- {
- normal = new Vector2(v.y, -v.x),
- distance = (-v.y * p1.x + v.x * p1.y)
- };
- }
- public static Plane2D FromNormalAndPoint(Vector3 normalizedNormal, Vector3 p1)
- {
- return new Plane2D
- {
- normal = normalizedNormal,
- distance = (-normalizedNormal.x * p1.x - normalizedNormal.y * p1.y)
- };
- }
- public void Flip() { normal = -normal; distance = -distance; }
- public Vector2[] CutConvex(Vector2[] poly)
- {
- Debug.Assert(poly.Length >= 3);
- var polyOut = new List<Vector2>(poly.Length);
- Vector2 startingPoint = poly[poly.Length - 1];
- foreach (var endPoint in poly)
- {
- var startingSide = GetSide(startingPoint);
- var endSide = GetSide(endPoint);
- if (startingSide && endSide)
- {
- polyOut.Add(endPoint);
- }
- else if (startingSide && !endSide)
- {
- polyOut.Add(Intersect(startingPoint, endPoint));
- }
- else if (!startingSide && endSide)
- {
- polyOut.Add(Intersect(startingPoint, endPoint));
- polyOut.Add(endPoint);
- }
- startingPoint = endPoint;
- }
- return polyOut.ToArray();
- }
- public override string ToString() { return string.Format("{0} x {1} + {2}", normal.x, normal.y, distance); }
- }
- }
- }
|