city-generation/Game/Assets/Scripts/Model/BuildingLot.cs

126 lines
3.6 KiB
C#
Raw Normal View History

2015-06-03 20:54:22 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransportGame.Business;
2015-06-10 08:49:43 +00:00
using TransportGame.Utils;
2015-06-03 20:54:22 +00:00
namespace TransportGame.Model
{
public class BuildingLot : IPositionable
{
/// <summary>
/// Gets or sets the list of points
/// </summary>
public Vector2[] Points { get; set; }
2015-06-10 08:49:43 +00:00
/// <summary>
/// Gets or sets the size of the lot
/// </summary>
public float Size { get; set; }
/// <summary>
/// Initializes the building lot
/// </summary>
2015-06-03 20:54:22 +00:00
public BuildingLot()
{
Points = new Vector2[4];
}
2015-06-10 08:49:43 +00:00
/// <summary>
/// Initializes lot with given size
/// </summary>
/// <param name="size">size</param>
public BuildingLot(float size)
{
Points = new Vector2[4];
Size = size;
}
/// <summary>
/// Initializes lot with given points and size
/// </summary>
/// <param name="size">Size</param>
/// <param name="points">Points</param>
public BuildingLot(float size, params Vector2[] points)
2015-06-03 20:54:22 +00:00
{
Points = points;
2015-06-10 08:49:43 +00:00
Size = size;
2015-06-03 20:54:22 +00:00
}
2015-06-10 08:49:43 +00:00
/// <summary>
/// Initializes lot with given points and size
/// </summary>
/// <param name="size">Size</param>
/// <param name="points">Points</param>
public BuildingLot(float size, IEnumerable<Vector2> points)
2015-06-03 20:54:22 +00:00
{
Points = points.ToArray();
2015-06-10 08:49:43 +00:00
Size = size;
2015-06-03 20:54:22 +00:00
}
2015-06-10 08:49:43 +00:00
/// <summary>
/// Gets the lot position
/// </summary>
2015-06-03 20:54:22 +00:00
public Vector2 Position
{
get { return Points.Aggregate((x, y) => x + y) / Points.Length; }
}
/// <summary>
/// Tests if two building lots intersect
/// </summary>
/// <param name="a">First lot</param>
/// <param name="b">Second lot</param>
/// <returns></returns>
2015-06-10 08:49:43 +00:00
public static bool DoesIntersect(BuildingLot a, BuildingLot b)
2015-06-03 20:54:22 +00:00
{
2015-06-10 08:49:43 +00:00
return Algorithmss.DoPolygonsIntersect(a.Points, b.Points);
2015-06-03 20:54:22 +00:00
}
/// <summary>
/// Tests if a building lot intersects a line segment (such as a road segment)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
2015-06-10 08:49:43 +00:00
public static bool DoesIntersect(BuildingLot a, LineSegment b)
2015-06-03 20:54:22 +00:00
{
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;
}
2015-06-13 18:36:32 +00:00
/// <summary>
/// Tests if a point is inside the building lot
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
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);
}
2015-06-03 20:54:22 +00:00
}
}