/
GeekNerd
/
ServerModelingProject
Обзор
Документация
Войти
/
GeekNerd
/
ServerModelingProject
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Assets/Scripts/RoomBuilding/PolygonValidator.cs
122 строки
4 KB
Gorney-Alex
Init
30 май 2026, 19:05
30 май 2026, 19:05
3cdcc49
Код
Авторство
О чём код?
using System.Collections.Generic; using UnityEngine; namespace RoomBuilding { public class PolygonValidator { public const float MinArea = 14f; public const float MinEdgeLength = 0.1f; public bool Validate(IReadOnlyList<Vector2> vertices, out string error) { error = string.Empty; if (vertices == null || vertices.Count < 3) { error = "Polygon must have at least 3 vertices."; return false; } for (int i = 0; i < vertices.Count; i++) { var a = vertices[i]; var b = vertices[(i + 1) % vertices.Count]; if ((b - a).magnitude <= MinEdgeLength) { error = $"Degenerate edge detected at index {i}."; return false; } } if (HasSelfIntersections(vertices)) { error = "Polygon has self intersections."; return false; } var area = Mathf.Abs(SignedPolygonArea(vertices)); if (area <= MinArea) { error = $"Polygon area is too small: {area:F2} m2."; return false; } return true; } public static float SignedPolygonArea(IReadOnlyList<Vector2> vertices) { float area = 0f; for (int i = 0; i < vertices.Count; i++) { var a = vertices[i]; var b = vertices[(i + 1) % vertices.Count]; area += a.x * b.y - b.x * a.y; } return area * 0.5f; } public static bool IsPointInPolygon(IReadOnlyList<Vector2> polygon, Vector2 point) { bool inside = false; for (int i = 0, j = polygon.Count - 1; i < polygon.Count; j = i++) { var pi = polygon[i]; var pj = polygon[j]; bool intersects = ((pi.y > point.y) != (pj.y > point.y)) && (point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y + 1e-6f) + pi.x); if (intersects) { inside = !inside; } } return inside; } private static bool HasSelfIntersections(IReadOnlyList<Vector2> vertices) { for (int i = 0; i < vertices.Count; i++) { var a1 = vertices[i]; var a2 = vertices[(i + 1) % vertices.Count]; for (int j = i + 1; j < vertices.Count; j++) { if (Mathf.Abs(i - j) <= 1 || (i == 0 && j == vertices.Count - 1)) { continue; } var b1 = vertices[j]; var b2 = vertices[(j + 1) % vertices.Count]; if (SegmentsIntersect(a1, a2, b1, b2)) { return true; } } } return false; } private static bool SegmentsIntersect(Vector2 p1, Vector2 p2, Vector2 q1, Vector2 q2) { float o1 = Orientation(p1, p2, q1); float o2 = Orientation(p1, p2, q2); float o3 = Orientation(q1, q2, p1); float o4 = Orientation(q1, q2, p2); return o1 * o2 < 0f && o3 * o4 < 0f; } private static float Orientation(Vector2 a, Vector2 b, Vector2 c) { return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } } }