最近无意中拓展出这个东西,基于之前写的2D多边形检测:
http://www.cnblogs.com/hont/p/6105997.html
而判断两条线相交的方法也替换成了我后来写的差乘判断:
http://www.cnblogs.com/hont/p/6106043.html
应用还是比较广泛的,特别是多边形选区和地形处理上
代码:
using UnityEngine; using System.Linq; using System.Collections; public class Test : MonoBehaviour { public Transform testComparePoint; public Transform[] pointsArray; public float height = 4; public bool IsInRange(Vector3 comparePoint) { if (comparePoint != null) { var flag = true; flag &= comparePoint.y <= height; flag &= comparePoint.y >= -height; flag &= IsConcaveContain2D(pointsArray, comparePoint); if (flag) return true; } return false; } public bool IsConcaveContain2D(Transform[] points, Vector3 compare) { const float VIRTUAL_RAYCAST_LEN = 100000; var comparePoint = (points[1].localPosition + points[0].localPosition) * 0.5f; var originPoint = compare; comparePoint += (comparePoint - originPoint).normalized * VIRTUAL_RAYCAST_LEN; int count = 0; for (int i = 0; i < points.Length; i++) { var a = points[i % points.Length]; var b = points[(i + 1) % points.Length]; var r = IsLineSegmentIntersection(a.localPosition, b.localPosition, originPoint, comparePoint); if (r) count++; } return count % 2 == 1; } public bool IsLineSegmentIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d) { var crossA = Mathf.Sign(Vector3.Cross(d - c, a - c).y); var crossB = Mathf.Sign(Vector3.Cross(d - c, b - c).y); if (crossA == crossB) return false; var crossC = Mathf.Sign(Vector3.Cross(b - a, c - a).y); var crossD = Mathf.Sign(Vector3.Cross(b - a, d - a).y); if (crossC == crossD) return false; return true; } void OnDrawGizmos() { if (pointsArray == null) return; if (testComparePoint != null) { var comparePoint = transform.InverseTransformPoint(testComparePoint.transform.position); if (IsInRange(comparePoint)) { Gizmos.color = Color.red; } } var cacheMatrix = Gizmos.matrix; Gizmos.matrix = transform.localToWorldMatrix; for (int i = 0; i < pointsArray.Length; i++) { var a = pointsArray[i]; var b = pointsArray[(i + 1) % pointsArray.Length]; if (a == null) continue; if (b == null) continue; var minA = a.localPosition; var minB = b.localPosition; var maxA = a.localPosition; var maxB = b.localPosition; minA.y = -height; minB.y = -height; maxA.y = height; maxB.y = height; Gizmos.DrawLine(minA, minB); Gizmos.DrawLine(maxA, maxB); Gizmos.DrawLine(minA, maxA); Gizmos.DrawLine(minB, maxB); } Gizmos.color = Color.clear; Gizmos.matrix = cacheMatrix; } }
时间: 2024-10-13 21:03:31