判断方法:
-
遍历矢量图形中所有的线段,找出长度大于等于L型建筑物的一条直线段。
-
以该线段的两个端点为起点,分别向左、右、上、下四个方向延伸,找出相邻的线段,并判断其是否与原线段成直角。
-
若找到了符合要求的相邻线段,则继续以该线段的端点为起点,向另一个方向延伸,直到延伸的线段不再与原线段成直角为止。
-
若延伸的线段数量达到了L型建筑物的要求,则判断为L型建筑物。
public bool IsLBuilding(List<Vector2> vertices) { bool isLBuilding = false; foreach (Vector2 vertex in vertices) { foreach (Vector2 neighbor in GetNeighbors(vertex, vertices)) { if (neighbor != vertex) { Vector2 direction = neighbor - vertex; if (direction.magnitude >= LBuildingLength) { Vector2 perpendicular = new Vector2(-direction.y, direction.x); if (IsPerpendicular(vertex, neighbor, perpendicular, vertices)) { if (IsLBuilding(vertex, neighbor, perpendicular, vertices)) { isLBuilding = true; break; } } } } } if (isLBuilding) { break; } } return isLBuilding; } private bool IsLBuilding(Vector2 start, Vector2 end, Vector2 perpendicular, List<Vector2> vertices) { int count = 0; Vector2 current = end; while (count < LBuildingCount) { Vector2 next = GetNextVertex(current, perpendicular, vertices); if (next != Vector2.zero && next != start) { perpendicular = new Vector2(-perpendicular.y, perpendicular.x); count++; current = next; } else { break; } } return count == LBuildingCount; } private bool IsPerpendicular(Vector2 start, Vector2 end, Vector2 perpendicular, List<Vector2> vertices) { bool isPerpendicular = false; foreach (Vector2 vertex in vertices) { if (vertex != start && vertex != end) { Vector2 direction = vertex - start; if (Vector2.Dot(direction, perpendicular) == 0) { float distance = Mathf.Abs(Vector2.Dot(direction, perpendicular.normalized)); if (distance <= LineTolerance) { isPerpendicular = true; break; } } } } return isPerpendicular; } private Vector2 GetNextVertex(Vector2 current, Vector2 direction, List<Vector2> vertices) { Vector2 next = Vector2.zero; foreach (Vector2 vertex in vertices) { if (vertex != current) { Vector2 delta = vertex - current; if (delta.magnitude <= LineTolerance) { Vector2 perpendicular = new Vector2(-delta.y, delta.x); if (Vector2.Dot(perpendicular, direction) == 0) { next = vertex; break; } } } } return next; } private List<Vector2> GetNeighbors(Vector2 vertex, List<Vector2> vertices) { List<Vector2> neighbors = new List<Vector2>(); foreach (Vector2 other in vertices) { if (other != vertex) { Vector2 delta = other - vertex; if (delta.magnitude <= LineTolerance) { neighbors.Add(other); } } } return neighbors; }
其中,
vertices
为矢量图形中所有顶点的列表,LBuildingLength
为L型建筑物的直线段长度,LBuildingCount
为L型建筑物的直线段数量,LineTolerance
为判断两条直线是否垂直或平行的容差值。