線與線相交、線與矩形相交判斷
阿新 • • 發佈:2018-12-19
///
/// 只要線與矩形有一條線有相交,則線與矩形相交
///
public class LineWithRect : MonoBehaviour
{
public Rect rect = new Rect(0, 0, 100, 100);
public Transform LineStart;
public Transform lineEnd;
Vector3 VecLineStart; Vector3 vecLineEnd; Vector3 leftDown { get { return new Vector2(rect.xMin, rect.yMin); } } Vector3 leftUp { get { return new Vector2(rect.xMin, rect.yMax); } } Vector3 RigtDown { get { return new Vector2(rect.xMax, rect.yMin); } } Vector3 RightUp { get { return new Vector2(rect.xMax, rect.yMax); } } private void OnDrawGizmos() { if (LineStart == null || lineEnd == null) return; VecLineStart = new Vector2(LineStart.position.x, LineStart.position.y); vecLineEnd = new Vector2(lineEnd.position.x, lineEnd.position.y); Gizmos.DrawLine(VecLineStart, vecLineEnd); Gizmos.DrawLine(leftDown, leftUp); Gizmos.DrawLine(leftUp, RightUp); Gizmos.DrawLine(RightUp, RigtDown); Gizmos.DrawLine(RigtDown, leftDown); } private void OnGUI() { string content = "不在矩形內"; if (LineInRect(VecLineStart, vecLineEnd, rect)) content = "在矩形內"; GUILayout.Label(content); content = "不相交"; if (LineIntersectRect(VecLineStart, vecLineEnd, rect)) content = "相交"; GUILayout.Label(content); GUILayout.Label("RightUp:[" + RightUp + "] RigtDown:[" + RigtDown); } // 線是否在矩形內 bool LineInRect(Vector2 lineStart, Vector2 lineEnd, Rect rect) { return rect.Contains(lineStart) || rect.Contains(lineEnd); } // 線與矩形是否相交 bool LineIntersectRect(Vector2 lineStart, Vector2 lineEnd, Rect rect) { if (LineIntersectLine(lineStart, lineEnd, leftDown, leftUp)) return true; if (LineIntersectLine(lineStart, lineEnd, leftUp, RightUp)) return true; if (LineIntersectLine(lineStart, lineEnd, RightUp, RigtDown)) return true; if (LineIntersectLine(lineStart, lineEnd, RigtDown, leftDown)) return true; return false; } // 線與線是否相交 bool LineIntersectLine(Vector2 l1Start, Vector2 l1End, Vector2 l2Start, Vector2 l2End) { return QuickReject(l1Start, l1End, l2Start, l2End) && Straddle(l1Start, l1End, l2Start, l2End); } // 快速排序。 true=通過, false=不通過 bool QuickReject(Vector2 l1Start, Vector2 l1End, Vector2 l2Start, Vector2 l2End) { float l1xMax = Mathf.Max(l1Start.x, l1End.x); float l1yMax = Mathf.Max(l1Start.y, l1End.y); float l1xMin = Mathf.Min(l1Start.x, l1End.x); float l1yMin = Mathf.Min(l1Start.y, l1End.y); float l2xMax = Mathf.Max(l2Start.x, l2End.x); float l2yMax = Mathf.Max(l2Start.y, l2End.y); float l2xMin = Mathf.Min(l2Start.x, l2End.x); float l2yMin = Mathf.Min(l2Start.y, l2End.y); if (l1xMax < l2xMin || l1yMax < l2yMin || l2xMax < l1xMin || l2yMax < l1yMin) return false; return true; } // 跨立實驗 bool Straddle(Vector3 l1Start, Vector3 l1End, Vector3 l2Start, Vector3 l2End) { float l1x1 = l1Start.x; float l1x2 = l1End.x; float l1y1 = l1Start.y; float l1y2 = l1End.y; float l2x1 = l2Start.x; float l2x2 = l2End.x; float l2y1 = l2Start.y; float l2y2 = l2End.y; if ((((l1x1 - l2x1) * (l2y2 - l2y1) - (l1y1 - l2y1) * (l2x2 - l2x1)) * ((l1x2 - l2x1) * (l2y2 - l2y1) - (l1y2 - l2y1) * (l2x2 - l2x1))) > 0 || (((l2x1 - l1x1) * (l1y2 - l1y1) - (l2y1 - l1y1) * (l1x2 - l1x1)) * ((l2x2 - l1x1) * (l1y2 - l1y1) - (l2y2 - l1y1) * (l1x2 - l1x1))) > 0) { return false; } return true; }
}