using System; using System.Collections.Generic; using System.Linq; using System.Text; using TransportGame.Business; using TransportGame.Utils; namespace TransportGame.Model { public class BuildingLot : IPositionable { /// /// Gets or sets the list of points /// public Vector2[] Points { get; set; } /// /// Gets or sets the size of the lot /// public float Size { get; set; } /// /// Initializes the building lot /// public BuildingLot() { Points = new Vector2[4]; } /// /// Initializes lot with given size /// /// size public BuildingLot(float size) { Points = new Vector2[4]; Size = size; } /// /// Initializes lot with given points and size /// /// Size /// Points public BuildingLot(float size, params Vector2[] points) { Points = points; Size = size; } /// /// Initializes lot with given points and size /// /// Size /// Points public BuildingLot(float size, IEnumerable points) { Points = points.ToArray(); Size = size; } /// /// Gets the lot position /// public Vector2 Position { get { return Points.Aggregate((x, y) => x + y) / Points.Length; } } /// /// Tests if two building lots intersect /// /// First lot /// Second lot /// public static bool DoesIntersect(BuildingLot a, BuildingLot b) { return Algorithmss.DoPolygonsIntersect(a.Points, b.Points); } /// /// Tests if a building lot intersects a line segment (such as a road segment) /// /// /// /// public static bool DoesIntersect(BuildingLot a, LineSegment b) { for (int i = 0; i < a.Points.Length; i++) { int j = (i + 1 >= a.Points.Length) ? 0 : i + 1; LineSegment s = new LineSegment(a.Points[i], a.Points[j]); if (LineSegment.Intersect(s, b).HasValue) return true; } return false; } /// /// Tests if a point is inside the building lot /// /// /// public bool IsInside(Vector2 point) { return IsInsideTriangle(point, Points[0], Points[1], Points[2]) || IsInsideTriangle(point, Points[0], Points[2], Points[3]); } private static float Sign(Vector2 a, Vector2 b, Vector2 c) { return (a.X - c.X) * (b.Y - c.Y) - (b.X - c.X) * (a.Y - c.Y); } private static bool IsInsideTriangle(Vector2 pt, Vector2 a, Vector2 b, Vector2 c) { bool b1 = Sign(pt, a, b) < 0; bool b2 = Sign(pt, b, c) < 0; bool b3 = Sign(pt, c, a) < 0; return (b1 == b2) && (b2 == b3); } } }