diff --git a/Game/Assembly-CSharp-vs.csproj b/Game/Assembly-CSharp-vs.csproj
index 887885f..5ae48f8 100644
--- a/Game/Assembly-CSharp-vs.csproj
+++ b/Game/Assembly-CSharp-vs.csproj
@@ -58,29 +58,29 @@
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/Game/Assembly-CSharp.csproj b/Game/Assembly-CSharp.csproj
index c5ff87b..baac44c 100644
--- a/Game/Assembly-CSharp.csproj
+++ b/Game/Assembly-CSharp.csproj
@@ -58,29 +58,29 @@
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/Game/Assets/Scripts/Business/Generator/BuildingGenerator.cs b/Game/Assets/Scripts/Business/Generator/BuildingGenerator.cs
index 967b41d..45599ca 100644
--- a/Game/Assets/Scripts/Business/Generator/BuildingGenerator.cs
+++ b/Game/Assets/Scripts/Business/Generator/BuildingGenerator.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using TransportGame.Business;
using TransportGame.Model;
+using TransportGame.Primitives;
using TransportGame.Model.Road;
using TransportGame.Utils;
@@ -112,7 +113,7 @@ namespace TransportGame.Generator
foreach (var lot in lotTree.Query(lotArea))
{
- if (BuildingLot.DoesIntersect(lot0, lot))
+ if (Polygon.Intersect(lot0, lot))
return false;
}
diff --git a/Game/Assets/Scripts/Business/Generator/PopulationCentersGenerator.cs b/Game/Assets/Scripts/Business/Generator/PopulationCentersGenerator.cs
index 13edfd5..220cb92 100644
--- a/Game/Assets/Scripts/Business/Generator/PopulationCentersGenerator.cs
+++ b/Game/Assets/Scripts/Business/Generator/PopulationCentersGenerator.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using TransportGame.Model;
using TransportGame.Noise;
+using TransportGame.Primitives;
namespace TransportGame.Generator
{
diff --git a/Game/Assets/Scripts/Business/Generator/RoadGenerator.cs b/Game/Assets/Scripts/Business/Generator/RoadGenerator.cs
index ca86a1c..05b78be 100644
--- a/Game/Assets/Scripts/Business/Generator/RoadGenerator.cs
+++ b/Game/Assets/Scripts/Business/Generator/RoadGenerator.cs
@@ -5,8 +5,9 @@ using System.Text;
using TransportGame.Business;
using TransportGame.Model;
using TransportGame.Model.Road;
+using TransportGame.Primitives;
using TransportGame.Utils;
-using Vector2 = TransportGame.Model.Vector2;
+using Vector2 = TransportGame.Primitives.Vector2;
namespace TransportGame.Generator
{
@@ -259,8 +260,7 @@ namespace TransportGame.Generator
}
// Filter & sort the segments by distance
- segmentIds = segmentIds.Distinct().OrderBy(id =>
- LineSegment.Distance(map.RoadNetwork.ArticulationSegments[id].AsLineSegment(), segment.Terminal2Pos));
+ segmentIds = segmentIds.Distinct().OrderBy(id => map.RoadNetwork.ArticulationSegments[id].AsLineSegment().Distance(segment.Terminal2Pos));
foreach (var segmentId in segmentIds)
{
diff --git a/Game/Assets/Scripts/Business/Generator/TerrainGenerator.cs b/Game/Assets/Scripts/Business/Generator/TerrainGenerator.cs
index 7fd3fe5..68bdf71 100644
--- a/Game/Assets/Scripts/Business/Generator/TerrainGenerator.cs
+++ b/Game/Assets/Scripts/Business/Generator/TerrainGenerator.cs
@@ -47,7 +47,7 @@ namespace TransportGame.Generator
GenerateElevation(map);
// Generate water level
- float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum);
+ float waterAmount = random.NextSingle(map.Biome.Moisture.Min, map.Biome.Moisture.Max);
map.WaterLevel = Mathf.Pow(waterAmount, ConfigManager.Tergen.WaterNonLinearPower) * map.Biome.Height;
return map;
diff --git a/Game/Assets/Scripts/Model/Biome.cs b/Game/Assets/Scripts/Model/Biome.cs
index 269cd3c..3a10021 100644
--- a/Game/Assets/Scripts/Model/Biome.cs
+++ b/Game/Assets/Scripts/Model/Biome.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
+using TransportGame.Primitives;
using TransportGame.Utils;
namespace TransportGame.Model
@@ -33,13 +34,13 @@ namespace TransportGame.Model
/// Value is a probability, should be between 0 and 1.
///
[XmlElement("moisture")]
- public Range Moisture { get; set; }
+ public Interval Moisture { get; set; }
///
/// Gets or sets the vegetation density of the biome
///
[XmlElement("vegetationDensity")]
- public Range VegetationDensity { get; set; }
+ public Interval VegetationDensity { get; set; }
///
/// Gets or sets an array of textures to use
diff --git a/Game/Assets/Scripts/Model/Building.cs b/Game/Assets/Scripts/Model/Building.cs
index 3295b13..cbdf767 100644
--- a/Game/Assets/Scripts/Model/Building.cs
+++ b/Game/Assets/Scripts/Model/Building.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using TransportGame.Primitives;
namespace TransportGame.Model
{
diff --git a/Game/Assets/Scripts/Model/BuildingLot.cs b/Game/Assets/Scripts/Model/BuildingLot.cs
index 2f34cab..91fb7e3 100644
--- a/Game/Assets/Scripts/Model/BuildingLot.cs
+++ b/Game/Assets/Scripts/Model/BuildingLot.cs
@@ -3,17 +3,16 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransportGame.Business;
+using TransportGame.Primitives;
using TransportGame.Utils;
namespace TransportGame.Model
{
- public class BuildingLot : IPositionable
+ ///
+ /// Building lot
+ ///
+ public class BuildingLot : Polygon
{
- ///
- /// Gets or sets the list of points
- ///
- public Vector2[] Points { get; set; }
-
///
/// Gets or sets the size of the lot
///
@@ -23,8 +22,8 @@ namespace TransportGame.Model
/// Initializes the building lot
///
public BuildingLot()
+ : base(new Vector2[4])
{
- Points = new Vector2[4];
}
///
@@ -32,8 +31,8 @@ namespace TransportGame.Model
///
/// size
public BuildingLot(float size)
+ : base(new Vector2[4])
{
- Points = new Vector2[4];
Size = size;
}
@@ -43,8 +42,8 @@ namespace TransportGame.Model
/// Size
/// Points
public BuildingLot(float size, params Vector2[] points)
+ : base(points)
{
- Points = points;
Size = size;
}
@@ -54,30 +53,11 @@ namespace TransportGame.Model
/// Size
/// Points
public BuildingLot(float size, IEnumerable points)
+ : base(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)
///
diff --git a/Game/Assets/Scripts/Model/CityMap.cs b/Game/Assets/Scripts/Model/CityMap.cs
index f78e16b..d379e49 100644
--- a/Game/Assets/Scripts/Model/CityMap.cs
+++ b/Game/Assets/Scripts/Model/CityMap.cs
@@ -4,8 +4,8 @@ using System.Linq;
using System.Text;
using System.Xml.Serialization;
using TransportGame.Model.Road;
+using TransportGame.Primitives;
using TransportGame.Utils;
-using UnityEngine;
namespace TransportGame.Model
{
@@ -256,8 +256,8 @@ namespace TransportGame.Model
if (dist < PopulationCenterRange * PopulationCenterRange)
{
float influence = 1 - (float)dist / (float)(PopulationCenterRange * PopulationCenterRange);
- influence = Mathf.Pow(influence, 6) * 0.7f; // Ease
- value = Mathf.Clamp01(value + influence);
+ influence = (float)Math.Pow(influence, 6) * 0.7f; // Ease
+ value = MathHelper.Clamp01(value + influence);
}
}
diff --git a/Game/Assets/Scripts/Model/IPositionable.cs b/Game/Assets/Scripts/Model/IPositionable.cs
deleted file mode 100644
index 18b684c..0000000
--- a/Game/Assets/Scripts/Model/IPositionable.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace TransportGame.Model
-{
- public interface IPositionable
- {
- Vector2 Position { get; }
- }
-}
diff --git a/Game/Assets/Scripts/Model/LineSegment.cs b/Game/Assets/Scripts/Model/LineSegment.cs
deleted file mode 100644
index 5eb33da..0000000
--- a/Game/Assets/Scripts/Model/LineSegment.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace TransportGame.Model
-{
- public struct LineSegment
- {
- public float X0 { get; private set; }
- public float Y0 { get; private set; }
- public float X1 { get; private set; }
- public float Y1 { get; private set; }
-
- public Vector2 P0
- {
- get
- {
- return new Vector2(X0, Y0);
- }
- }
- public Vector2 P1
- {
- get
- {
- return new Vector2(X1, Y1);
- }
- }
-
- public float Length
- {
- get
- {
- return (P1 - P0).Length;
- }
- }
-
- public float LengthSq
- {
- get
- {
- return (P1 - P0).LengthSq;
- }
- }
-
- public Vector2 Direction
- {
- get
- {
- return (P1 - P0).Normalized;
- }
- }
-
- public LineSegment(Vector2 p0, Vector2 p1)
- : this()
- {
- X0 = p0.X; Y0 = p0.Y;
- X1 = p1.X; Y1 = p1.Y;
- }
-
- public LineSegment(float x0, float y0, float x1, float y1)
- : this()
- {
- X0 = x0; Y0 = y0;
- X1 = x1; Y1 = y1;
- }
-
- public static Vector2? Intersect(LineSegment a, LineSegment b)
- {
- float s1x = a.X1 - a.X0, s1y = a.Y1 - a.Y0;
- float s2x = b.X1 - b.X0, s2y = b.Y1 - b.Y0;
-
- float det = (-s2x * s1y + s1x * s2y);
-
- // Avoid division by zero
- // Note: this is an edge case, the vectors might be parallel or colliniar
- if (det == 0) return null;
-
- float s = (-s1y * (a.X0 - b.X0) + s1x * (a.Y0 - b.Y0)) / det;
- float t = (s2x * (a.Y0 - b.Y0) - s2y * (a.X0 - b.X0)) / det;
-
- // Collision detected
- if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
- return new Vector2(a.X0 + t * s1x, a.Y0 + t * s1y);
-
- // No collision
- return null;
- }
-
- ///
- /// Calculates the distance from point p to line segment
- ///
- /// Line
- /// Point
- /// Distance
- public static float Distance(LineSegment line, Vector2 p)
- {
- float det = (line.Y1 - line.Y0) * p.X - (line.X1 - line.X0) * p.Y
- + line.X1 * line.Y0 - line.Y1 * line.X0;
- return Math.Abs(det) / line.Length;
- }
-
- public override string ToString()
- {
- return string.Format("({0}, {1})->({2}, {3})", X0, Y0, X1, Y1);
- }
- }
-}
diff --git a/Game/Assets/Scripts/Model/Range.cs b/Game/Assets/Scripts/Model/Range.cs
deleted file mode 100644
index 8275306..0000000
--- a/Game/Assets/Scripts/Model/Range.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml.Serialization;
-
-namespace TransportGame.Model
-{
- public class Range
- {
- [XmlAttribute("min")]
- public float Minimum { get; set; }
-
- [XmlAttribute("max")]
- public float Maximum { get; set; }
-
- public Range()
- {
- Minimum = 0;
- Maximum = 1;
- }
-
- public Range(float min, float max)
- {
- Minimum = min;
- Maximum = max;
- }
-
- public override string ToString()
- {
- return String.Format("[{0}, {1}]", Minimum, Maximum);
- }
- }
-}
diff --git a/Game/Assets/Scripts/Model/Rectangle.cs b/Game/Assets/Scripts/Model/Rectangle.cs
deleted file mode 100644
index ecbf0f3..0000000
--- a/Game/Assets/Scripts/Model/Rectangle.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace TransportGame.Model
-{
- public struct Rectangle
- {
- public float Left { get; set; }
- public float Top { get; set; }
- public float Right { get; set; }
- public float Bottom { get; set; }
-
- public Rectangle(float left, float top, float right, float bottom)
- : this()
- {
- Left = left;
- Top = top;
- Right = right;
- Bottom = bottom;
-
- if (left > right)
- throw new ArgumentException("Left must be smaller than right.");
-
- if (top > bottom)
- throw new ArgumentException("Top must be smaller than bottom.");
- }
-
- public float Width
- {
- get
- {
- return Right - Left;
- }
- set
- {
- Right = Left + value;
- }
- }
-
- public float Height
- {
- get
- {
- return Bottom - Top;
- }
- set
- {
- Bottom = Top + value;
- }
- }
-
- public bool Contains(float x, float y)
- {
- return x >= Left && x <= Right && y >= Top && y <= Bottom;
- }
-
- public bool Contains(Vector2 p)
- {
- return Contains(p.X, p.Y);
- }
-
- public static bool Intersects (Rectangle a, Rectangle b)
- {
- return !(b.Left > a.Right ||
- b.Right < a.Left ||
- b.Top > a.Bottom ||
- b.Bottom < a.Top);
- }
-
- public override string ToString()
- {
- return string.Format("({0}, {1}, {2}, {3})", Left, Top, Right, Bottom);
- }
- }
-}
diff --git a/Game/Assets/Scripts/Model/Road/RoadNetwork.cs b/Game/Assets/Scripts/Model/Road/RoadNetwork.cs
index 832aac0..dd8ece2 100644
--- a/Game/Assets/Scripts/Model/Road/RoadNetwork.cs
+++ b/Game/Assets/Scripts/Model/Road/RoadNetwork.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
+using TransportGame.Primitives;
using TransportGame.Utils;
namespace TransportGame.Model.Road
diff --git a/Game/Assets/Scripts/Model/Road/RoadNode.cs b/Game/Assets/Scripts/Model/Road/RoadNode.cs
index 4a9c2d3..c198455 100644
--- a/Game/Assets/Scripts/Model/Road/RoadNode.cs
+++ b/Game/Assets/Scripts/Model/Road/RoadNode.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
+using TransportGame.Primitives;
namespace TransportGame.Model.Road
{
diff --git a/Game/Assets/Scripts/Model/Road/RoadSegment.cs b/Game/Assets/Scripts/Model/Road/RoadSegment.cs
index 4008dd9..ab65f4a 100644
--- a/Game/Assets/Scripts/Model/Road/RoadSegment.cs
+++ b/Game/Assets/Scripts/Model/Road/RoadSegment.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
+using TransportGame.Primitives;
namespace TransportGame.Model.Road
{
diff --git a/Game/Assets/Scripts/Primitives.meta b/Game/Assets/Scripts/Primitives.meta
new file mode 100644
index 0000000..b719ced
--- /dev/null
+++ b/Game/Assets/Scripts/Primitives.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 38c9355be2e20d242ab7047cac952101
+folderAsset: yes
+timeCreated: 1434538689
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Primitives/IPositionable.cs b/Game/Assets/Scripts/Primitives/IPositionable.cs
new file mode 100644
index 0000000..92f2409
--- /dev/null
+++ b/Game/Assets/Scripts/Primitives/IPositionable.cs
@@ -0,0 +1,14 @@
+
+namespace TransportGame.Primitives
+{
+ ///
+ /// Object can be positioned using a point
+ ///
+ public interface IPositionable
+ {
+ ///
+ /// Gets the position of the object
+ ///
+ Vector2 Position { get; }
+ }
+}
diff --git a/Game/Assets/Scripts/Model/IPositionable.cs.meta b/Game/Assets/Scripts/Primitives/IPositionable.cs.meta
similarity index 76%
rename from Game/Assets/Scripts/Model/IPositionable.cs.meta
rename to Game/Assets/Scripts/Primitives/IPositionable.cs.meta
index a28da09..c640240 100644
--- a/Game/Assets/Scripts/Model/IPositionable.cs.meta
+++ b/Game/Assets/Scripts/Primitives/IPositionable.cs.meta
@@ -1,6 +1,6 @@
fileFormatVersion: 2
-guid: cdecfb69b7ca68446910d0a607e934e6
-timeCreated: 1432824088
+guid: b1f8e20ab1416e64aa689620b275d16e
+timeCreated: 1434538689
licenseType: Free
MonoImporter:
serializedVersion: 2
diff --git a/Game/Assets/Scripts/Primitives/Interval.cs b/Game/Assets/Scripts/Primitives/Interval.cs
new file mode 100644
index 0000000..1e283da
--- /dev/null
+++ b/Game/Assets/Scripts/Primitives/Interval.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Xml.Serialization;
+
+namespace TransportGame.Primitives
+{
+ ///
+ /// Interval
+ ///
+ public class Interval
+ {
+ #region Properties
+
+ ///
+ /// Gets the minimum value of the interval
+ ///
+ [XmlAttribute("min")]
+ public float Min { get; set; }
+
+ ///
+ /// Gets the maximum value of the interval
+ ///
+ [XmlAttribute("max")]
+ public float Max { get; set; }
+
+ #endregion
+
+ #region Other properties
+
+ ///
+ /// Gets or sets the length of the interval
+ ///
+ [XmlIgnore]
+ public float Length
+ {
+ get
+ {
+ return Max - Min;
+ }
+ set
+ {
+ Max = Min + value;
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes interval
+ ///
+ public Interval()
+ {
+ Min = 0;
+ Max = 1;
+ }
+
+ ///
+ /// Initializes interval
+ ///
+ /// Minimum value
+ /// Maximum value
+ public Interval(float min, float max)
+ {
+ Min = min;
+ Max = max;
+ }
+
+ #endregion
+
+ #region Operations
+
+ ///
+ /// Tests if interval contains value
+ ///
+ ///
+ ///
+ public bool Contains(float value)
+ {
+ return (value >= Min && value <= Max);
+ }
+
+ #endregion
+
+ #region Object overrides
+
+ ///
+ /// Gets string representation
+ ///
+ ///
+ public override string ToString()
+ {
+ return String.Format("[{0}, {1}]", Min, Max);
+ }
+
+ #endregion
+ }
+}
diff --git a/Game/Assets/Scripts/Utils/Algorithms.cs.meta b/Game/Assets/Scripts/Primitives/Interval.cs.meta
similarity index 52%
rename from Game/Assets/Scripts/Utils/Algorithms.cs.meta
rename to Game/Assets/Scripts/Primitives/Interval.cs.meta
index 8c43c03..205f5ad 100644
--- a/Game/Assets/Scripts/Utils/Algorithms.cs.meta
+++ b/Game/Assets/Scripts/Primitives/Interval.cs.meta
@@ -1,8 +1,12 @@
fileFormatVersion: 2
-guid: 67f24adfb8b21234184d0caf81f424ea
+guid: e3c02b6aafb292640a692c9ea354adb1
+timeCreated: 1434538689
+licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Primitives/LineSegment.cs b/Game/Assets/Scripts/Primitives/LineSegment.cs
new file mode 100644
index 0000000..bbb58c0
--- /dev/null
+++ b/Game/Assets/Scripts/Primitives/LineSegment.cs
@@ -0,0 +1,178 @@
+using System;
+
+namespace TransportGame.Primitives
+{
+ ///
+ /// A line segment
+ ///
+ public struct LineSegment
+ {
+ #region Properties
+
+ ///
+ /// X coordinate of first point
+ ///
+ public float X0 { get; private set; }
+
+ ///
+ /// Y coordinate of first point
+ ///
+ public float Y0 { get; private set; }
+
+ ///
+ /// X coordinate of second point
+ ///
+ public float X1 { get; private set; }
+
+ ///
+ /// Y coordinate of second point
+ ///
+ public float Y1 { get; private set; }
+
+ ///
+ /// Gets the first point
+ ///
+ public Vector2 P0
+ {
+ get
+ {
+ return new Vector2(X0, Y0);
+ }
+ }
+
+ ///
+ /// Gets the second point
+ ///
+ public Vector2 P1
+ {
+ get
+ {
+ return new Vector2(X1, Y1);
+ }
+ }
+
+ ///
+ /// Gets the length of the segment
+ ///
+ public float Length
+ {
+ get
+ {
+ return (P1 - P0).Length;
+ }
+ }
+
+ ///
+ /// Gets the length squared of the segment
+ ///
+ public float LengthSq
+ {
+ get
+ {
+ return (P1 - P0).LengthSq;
+ }
+ }
+
+ ///
+ /// Gets the direction vector of the segment
+ ///
+ public Vector2 Direction
+ {
+ get
+ {
+ return (P1 - P0).Normalized;
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes line segment
+ ///
+ /// First point
+ /// Second point
+ public LineSegment(Vector2 p0, Vector2 p1)
+ : this()
+ {
+ X0 = p0.X; Y0 = p0.Y;
+ X1 = p1.X; Y1 = p1.Y;
+ }
+
+ ///
+ /// Initializes line segment
+ ///
+ /// X coordinate of first segment
+ /// Y coordinate of first segment
+ /// X coordinate of second segment
+ /// Y coordinate of second segment
+ public LineSegment(float x0, float y0, float x1, float y1)
+ : this()
+ {
+ X0 = x0; Y0 = y0;
+ X1 = x1; Y1 = y1;
+ }
+
+ #endregion
+
+ #region Operations
+
+ ///
+ /// Calculates the intersection between two line segments.
+ ///
+ ///
+ /// Ignores case where intersection is a line.
+ ///
+ /// First line segment
+ /// Second line segment
+ /// Intersection point, or null if segments don't intersect.
+ public static Vector2? Intersect(LineSegment a, LineSegment b)
+ {
+ float s1x = a.X1 - a.X0, s1y = a.Y1 - a.Y0;
+ float s2x = b.X1 - b.X0, s2y = b.Y1 - b.Y0;
+
+ float det = (-s2x * s1y + s1x * s2y);
+
+ // Avoid division by zero
+ // Note: this is an edge case, the vectors might be parallel or colliniar
+ if (det == 0) return null;
+
+ float s = (-s1y * (a.X0 - b.X0) + s1x * (a.Y0 - b.Y0)) / det;
+ float t = (s2x * (a.Y0 - b.Y0) - s2y * (a.X0 - b.X0)) / det;
+
+ // Collision detected
+ if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
+ return new Vector2(a.X0 + t * s1x, a.Y0 + t * s1y);
+
+ // No collision
+ return null;
+ }
+
+ ///
+ /// Calculates the distance from a point p to a line segment
+ ///
+ /// Point
+ /// Distance
+ public float Distance(Vector2 p)
+ {
+ float det = (Y1 - Y0) * p.X - (X1 - X0) * p.Y + X1 * Y0 - Y1 * X0;
+ return Math.Abs(det) / Length;
+ }
+
+ #endregion
+
+ #region ToString
+
+ ///
+ /// Gets string representation of line segment
+ ///
+ ///
+ public override string ToString()
+ {
+ return string.Format("({0}, {1})->({2}, {3})", X0, Y0, X1, Y1);
+ }
+
+ #endregion
+ }
+}
diff --git a/Game/Assets/Scripts/Model/LineSegment.cs.meta b/Game/Assets/Scripts/Primitives/LineSegment.cs.meta
similarity index 76%
rename from Game/Assets/Scripts/Model/LineSegment.cs.meta
rename to Game/Assets/Scripts/Primitives/LineSegment.cs.meta
index a68ae4b..8b6ee46 100644
--- a/Game/Assets/Scripts/Model/LineSegment.cs.meta
+++ b/Game/Assets/Scripts/Primitives/LineSegment.cs.meta
@@ -1,6 +1,6 @@
fileFormatVersion: 2
-guid: eaabdeeb068e1dc46a7a9da6fd47f393
-timeCreated: 1432847695
+guid: a6b34c7e4ed62b04fbb44b61fbb7bc23
+timeCreated: 1434538689
licenseType: Free
MonoImporter:
serializedVersion: 2
diff --git a/Game/Assets/Scripts/Model/Polygon.cs b/Game/Assets/Scripts/Primitives/Polygon.cs
similarity index 80%
rename from Game/Assets/Scripts/Model/Polygon.cs
rename to Game/Assets/Scripts/Primitives/Polygon.cs
index 74a5796..50c8006 100644
--- a/Game/Assets/Scripts/Model/Polygon.cs
+++ b/Game/Assets/Scripts/Primitives/Polygon.cs
@@ -1,17 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using TransportGame.Utils;
-namespace TransportGame.Model
+namespace TransportGame.Primitives
{
///
/// Represents a polygon
///
public class Polygon : IPositionable
{
- #region Private types
+ #region Private data types
private struct Edge
{
@@ -26,11 +24,17 @@ namespace TransportGame.Model
#endregion
+ #region Properties
+
///
/// Gets or sets the points that define the polygon
///
public Vector2[] Points { get; set; }
+ #endregion
+
+ #region Other properties
+
///
/// Gets the gravitational center
///
@@ -39,6 +43,10 @@ namespace TransportGame.Model
get { return Points.Aggregate((x, y) => x + y) / Points.Length; }
}
+ #endregion
+
+ #region Constructors
+
///
/// Initializes polygon
///
@@ -65,28 +73,9 @@ namespace TransportGame.Model
Points = points;
}
- ///
- /// Compares angle between two NORMALIZED vectors.
- ///
- ///
- ///
- ///
- private static float CompareAngle(Vector2 a, Vector2 b)
- {
- float sin = Vector2.Cross(a, b);
- float cos = Vector2.Dot(a, b);
+ #endregion
- if (sin >= 0 && cos >= 0)
- return sin;
-
- else if (sin >= 0 && cos <= 0)
- return 1 + Math.Abs(cos);
-
- else if (sin <= 0 && cos <= 0)
- return 2 + Math.Abs(sin);
-
- else return 3 + cos;
- }
+ #region Operations
///
/// Returns the union between given polygons
@@ -173,7 +162,6 @@ namespace TransportGame.Model
union.Add(vertices[v]);
int newV = -1;
- float smallestAngle = -1;
Vector2 smallestDir = Vector2.Zero;
foreach (var edge in edges)
@@ -184,11 +172,9 @@ namespace TransportGame.Model
Vector2 dir = (vertices[otherv] - vertices[v]).Normalized;
// Find smallest angle
- float cmpAngle = CompareAngle(-prev, dir);
- if (cmpAngle < smallestAngle || smallestAngle < 0)
+ if (newV == -1 || Vector2.TrigonometricComparer.Compare(dir, smallestDir) < 0)
{
newV = otherv;
- smallestAngle = cmpAngle;
smallestDir = dir;
}
}
@@ -204,7 +190,13 @@ namespace TransportGame.Model
return new Polygon(union);
}
- public static bool DoPolygonsIntersect(Polygon a, Polygon b)
+ ///
+ /// Tests if two polygons intersect
+ ///
+ ///
+ ///
+ ///
+ public static bool Intersect(Polygon a, Polygon b)
{
foreach (var poly in new[] { a, b })
{
@@ -242,6 +234,42 @@ namespace TransportGame.Model
return true;
}
+ ///
+ /// Tests if polygon contains point
+ ///
+ ///
+ ///
+ public bool Contains(Vector2 point)
+ {
+ // Quick bounding box check
+ Vector2 min = Points[0], max = Points[0];
+ for (int i = 0; i < Points.Length; i++)
+ {
+ min.X = Math.Min(min.X, Points[i].X);
+ min.Y = Math.Min(min.Y, Points[i].Y);
+ max.X = Math.Max(max.X, Points[i].X);
+ max.Y = Math.Max(max.Y, Points[i].Y);
+ }
+
+ if (point.X < min.X || point.Y < min.Y || point.X > max.X || point.Y > max.Y)
+ return false;
+
+ // Ray casting method
+ int j = Points.Length - 1;
+ bool result = false;
+ for (int i = 0; i < Points.Length; i++)
+ {
+ if ((Points[i].Y > point.Y) != (Points[j].Y > point.Y) &&
+ (point.X < (Points[j].X - Points[i].X) * (point.Y - Points[i].Y) / (Points[j].Y - Points[i].Y) + Points[i].X))
+ result = !result;
+
+ j = i;
+ }
+
+ return result;
+ }
+
+ #endregion
}
}
diff --git a/Game/Assets/Scripts/Model/Polygon.cs.meta b/Game/Assets/Scripts/Primitives/Polygon.cs.meta
similarity index 76%
rename from Game/Assets/Scripts/Model/Polygon.cs.meta
rename to Game/Assets/Scripts/Primitives/Polygon.cs.meta
index 52cc98b..fbc2784 100644
--- a/Game/Assets/Scripts/Model/Polygon.cs.meta
+++ b/Game/Assets/Scripts/Primitives/Polygon.cs.meta
@@ -1,6 +1,6 @@
fileFormatVersion: 2
-guid: ee96020375a8f3d4bb7a04e9f7a6b05e
-timeCreated: 1433489979
+guid: 3e0bb5f9b3dd2d84a9996806e2048f9d
+timeCreated: 1434538689
licenseType: Free
MonoImporter:
serializedVersion: 2
diff --git a/Game/Assets/Scripts/Primitives/Rectangle.cs b/Game/Assets/Scripts/Primitives/Rectangle.cs
new file mode 100644
index 0000000..6dee7ea
--- /dev/null
+++ b/Game/Assets/Scripts/Primitives/Rectangle.cs
@@ -0,0 +1,156 @@
+using System;
+
+namespace TransportGame.Primitives
+{
+ ///
+ /// Rectangle
+ ///
+ public struct Rectangle
+ {
+ #region Properties
+
+ ///
+ /// Gets or sets the left boundary
+ ///
+ public float Left { get; set; }
+
+ ///
+ /// Gets or sets the top boundary
+ ///
+ public float Bottom { get; set; }
+
+ ///
+ /// Gets or sets the right boundary
+ ///
+ public float Right { get; set; }
+
+ ///
+ /// Gets or sets the bottom boundary
+ ///
+ public float Top { get; set; }
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Initializes this rectangle
+ ///
+ /// Left boundary
+ /// Bottom boundary
+ /// Right boundary
+ /// Top boundary
+ public Rectangle(float left, float bottom, float right, float top)
+ : this()
+ {
+ Left = left;
+ Bottom = bottom;
+ Right = right;
+ Top = top;
+
+ if (left > right)
+ throw new ArgumentException("Left must be smaller than right.");
+
+ if (bottom > top)
+ throw new ArgumentException("Bottom must be smaller than top.");
+ }
+
+ #endregion
+
+ #region Other properties
+
+ ///
+ /// Gets or sets the width of the rectangle
+ ///
+ public float Width
+ {
+ get
+ {
+ return Right - Left;
+ }
+ set
+ {
+ Right = Left + value;
+ }
+ }
+
+ ///
+ /// Gets or sets the height of the rectangle
+ ///
+ public float Height
+ {
+ get
+ {
+ return Top - Bottom;
+ }
+ set
+ {
+ Top = Bottom + value;
+ }
+ }
+
+ ///
+ /// Gets the area of the rectangle
+ ///
+ public float Area
+ {
+ get
+ {
+ return Width * Height;
+ }
+ }
+
+ #endregion
+
+ #region Operations
+
+ ///
+ /// Tests if rectangle contains given point
+ ///
+ /// x coordinate
+ /// y coordinate
+ /// True if point is inside
+ public bool Contains(float x, float y)
+ {
+ return x >= Left && x <= Right && y >= Bottom && y <= Top;
+ }
+
+ ///
+ /// Tests if rectangle contains given point
+ ///
+ /// Vector
+ /// True if point is inside
+ public bool Contains(Vector2 p)
+ {
+ return Contains(p.X, p.Y);
+ }
+
+ ///
+ /// Tests if two rectangles intersect
+ ///
+ ///
+ ///
+ /// True if rectangles intersect
+ public static bool Intersect (Rectangle a, Rectangle b)
+ {
+ return !(b.Left > a.Right ||
+ b.Right < a.Left ||
+ b.Bottom > a.Top ||
+ b.Top < a.Bottom);
+ }
+ #endregion
+
+ #region Object overrides
+
+ ///
+ /// Gets string representation
+ ///
+ ///
+ public override string ToString()
+ {
+ return string.Format("({0}, {1}, {2}, {3})", Left, Bottom, Right, Top);
+ }
+
+ #endregion
+ }
+}
diff --git a/Game/Assets/Scripts/Model/Rectangle.cs.meta b/Game/Assets/Scripts/Primitives/Rectangle.cs.meta
similarity index 76%
rename from Game/Assets/Scripts/Model/Rectangle.cs.meta
rename to Game/Assets/Scripts/Primitives/Rectangle.cs.meta
index bae31f6..9112362 100644
--- a/Game/Assets/Scripts/Model/Rectangle.cs.meta
+++ b/Game/Assets/Scripts/Primitives/Rectangle.cs.meta
@@ -1,6 +1,6 @@
fileFormatVersion: 2
-guid: 01c02a9fd2c3d0142905c23fb3142b6f
-timeCreated: 1432824087
+guid: 089c6381ade2028499552d764dcdaa25
+timeCreated: 1434538689
licenseType: Free
MonoImporter:
serializedVersion: 2
diff --git a/Game/Assets/Scripts/Model/Vector2.cs b/Game/Assets/Scripts/Primitives/Vector2.cs
similarity index 88%
rename from Game/Assets/Scripts/Model/Vector2.cs
rename to Game/Assets/Scripts/Primitives/Vector2.cs
index 3cb33b6..ef0b5af 100644
--- a/Game/Assets/Scripts/Model/Vector2.cs
+++ b/Game/Assets/Scripts/Primitives/Vector2.cs
@@ -1,13 +1,16 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.Xml.Serialization;
-namespace TransportGame.Model
+namespace TransportGame.Primitives
{
+ ///
+ /// 2D vector
+ ///
public struct Vector2
{
+ #region Constant vectors
+
///
/// Zero vector
///
@@ -18,6 +21,10 @@ namespace TransportGame.Model
///
public static readonly Vector2 Unit = new Vector2(1, 0);
+ #endregion
+
+ #region Properties
+
///
/// Gets the X component
///
@@ -30,6 +37,10 @@ namespace TransportGame.Model
[XmlAttribute("y")]
public float Y { get; set; }
+ #endregion
+
+ #region Constructor
+
///
/// Initializes a vector2
///
@@ -42,6 +53,31 @@ namespace TransportGame.Model
Y = y;
}
+ ///
+ /// Gets the vector corresponding with specified angle (in radians)
+ ///
+ /// Radians
+ /// Vector
+ public static Vector2 FromRadians(float rads)
+ {
+ return new Vector2((float)Math.Cos(rads), (float)Math.Sin(rads));
+ }
+
+ ///
+ /// Gets the vector corresponding with specified angle (in degrees)
+ ///
+ /// Degrees
+ /// Vector
+ public static Vector2 FromDegrees(float degs)
+ {
+ float rads = (degs * (float)Math.PI / 180f);
+ return FromRadians(rads);
+ }
+
+ #endregion
+
+ #region Properties (length, normalized)
+
///
/// Gets the length of the vector
///
@@ -93,6 +129,10 @@ namespace TransportGame.Model
}
}
+ #endregion
+
+ #region Operations
+
///
/// Rotates vector by given number of radians
///
@@ -234,33 +274,25 @@ namespace TransportGame.Model
{
return Math.Abs(Cross(a, b)) < 1e-12;
}
+
+ #endregion
+
+ #region Object overrides
///
- /// Gets the vector corresponding with specified angle (in radians)
+ /// Gets string representation of vector2
///
- /// Radians
- /// Vector
- public static Vector2 FromRadians(float rads)
- {
- return new Vector2((float)Math.Cos(rads), (float)Math.Sin(rads));
- }
-
- ///
- /// Gets the vector corresponding with specified angle (in degrees)
- ///
- /// Degrees
- /// Vector
- public static Vector2 FromDegrees(float degs)
- {
- float rads = (degs * (float)Math.PI / 180f);
- return FromRadians(rads);
- }
-
+ ///
public override string ToString()
{
return String.Format("({0}, {1})", X, Y);
}
+ ///
+ /// Tests if two vectors are equal.
+ ///
+ ///
+ ///
public override bool Equals(object obj)
{
if (obj is Vector2)
@@ -272,11 +304,19 @@ namespace TransportGame.Model
return false;
}
+ ///
+ /// Gets hash code of vector2
+ ///
+ ///
public override int GetHashCode()
{
- return X.GetHashCode() * 7 + Y.GetHashCode();
+ return X.GetHashCode() * 29 + Y.GetHashCode();
}
+ #endregion
+
+ #region Comparers
+
private class LengthComparerImpl : IComparer
{
public int Compare(Vector2 a, Vector2 b)
@@ -338,7 +378,16 @@ namespace TransportGame.Model
}
}
- public static IComparer LengthComparer = new LengthComparerImpl();
- public static IComparer TrigonomicComparer = new TrigonometricComparerImpl();
+ ///
+ /// Length comparer - compares vectors by length
+ ///
+ public static readonly IComparer LengthComparer = new LengthComparerImpl();
+
+ ///
+ /// Trigonometric comparer - compares vectors by angle
+ ///
+ public static readonly IComparer TrigonometricComparer = new TrigonometricComparerImpl();
+
+ #endregion
}
}
diff --git a/Game/Assets/Scripts/Model/Vector2.cs.meta b/Game/Assets/Scripts/Primitives/Vector2.cs.meta
similarity index 76%
rename from Game/Assets/Scripts/Model/Vector2.cs.meta
rename to Game/Assets/Scripts/Primitives/Vector2.cs.meta
index 050e95e..6e8773d 100644
--- a/Game/Assets/Scripts/Model/Vector2.cs.meta
+++ b/Game/Assets/Scripts/Primitives/Vector2.cs.meta
@@ -1,6 +1,6 @@
fileFormatVersion: 2
-guid: 94117dad82214b44382141a14825994e
-timeCreated: 1432281052
+guid: e100b9a2be8bd3243b55552195f6ce14
+timeCreated: 1434538689
licenseType: Free
MonoImporter:
serializedVersion: 2
diff --git a/Game/Assets/Scripts/Unity/RoadMeshGenerator.cs b/Game/Assets/Scripts/Unity/RoadMeshGenerator.cs
index 75468b2..ab35997 100644
--- a/Game/Assets/Scripts/Unity/RoadMeshGenerator.cs
+++ b/Game/Assets/Scripts/Unity/RoadMeshGenerator.cs
@@ -8,7 +8,7 @@ using TransportGame.Model;
using TransportGame.Model.Road;
using TransportGame.Utils;
using UnityEngine;
-using Vector2 = TransportGame.Model.Vector2;
+using Vector2 = TransportGame.Primitives.Vector2;
//#define DEBUG_ROAD_MESH_GENERATOR
@@ -144,7 +144,7 @@ namespace TransportGame.Unity
vindex += 1;
// Sort adjacent segments in trigonometric order
- var segs = node.ArticulationSegments.OrderBy(segment => DirectionFrom(segment, node), Vector2.TrigonomicComparer).ToArray();
+ var segs = node.ArticulationSegments.OrderBy(segment => DirectionFrom(segment, node), Vector2.TrigonometricComparer).ToArray();
Vector2[] sideCrns = new Vector2[segs.Length];
Vector2[] strCrns = new Vector2[segs.Length];
diff --git a/Game/Assets/Scripts/Utils/Algorithms.cs b/Game/Assets/Scripts/Utils/Algorithms.cs
deleted file mode 100644
index 012ce7e..0000000
--- a/Game/Assets/Scripts/Utils/Algorithms.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using TransportGame.Model;
-
-namespace TransportGame.Utils
-{
- public static class Algorithmss
- {
- public static bool DoPolygonsIntersect(Vector2[] a, Vector2[] b)
- {
- foreach (var poly in new[] {a, b})
- {
- for (int i = 0; i < poly.Length; i++)
- {
- int j = (i + 1) % poly.Length;
-
- var normal = new Vector2(poly[j].Y - poly[i].Y, poly[i].X - poly[j].X);
-
- double? minA = null, maxA = null;
- foreach (var p in a)
- {
- var projected = Vector2.Dot(normal, p);
- if (minA == null || projected < minA)
- minA = projected;
- if (maxA == null || projected > maxA)
- maxA = projected;
- }
-
- double? minB = null, maxB = null;
- foreach (var p in b)
- {
- var projected = Vector2.Dot(normal, p);
- if (minB == null || projected < minB)
- minB = projected;
- if (maxB == null || projected > maxB)
- maxB = projected;
- }
-
- if (maxA <= minB || maxB <= minA)
- return false;
- }
- }
-
- return true;
- }
- }
-}
diff --git a/Game/Assets/Scripts/Utils/MathHelper.cs b/Game/Assets/Scripts/Utils/MathHelper.cs
new file mode 100644
index 0000000..7156fd5
--- /dev/null
+++ b/Game/Assets/Scripts/Utils/MathHelper.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace TransportGame.Utils
+{
+ public static class MathHelper
+ {
+ ///
+ /// Clamps given value in the [0,1] interval
+ ///
+ /// Value
+ /// Clamped value
+ public static float Clamp01(float value)
+ {
+ return Clamp(value, 0, 1);
+ }
+
+ ///
+ /// Clamps given value in the [min,max] interval
+ ///
+ /// Value
+ /// Minimum value
+ /// Maximum value
+ /// Clamped value
+ public static float Clamp(float value, float min, float max)
+ {
+ if (value < min)
+ return min;
+
+ if (value > max)
+ return max;
+
+ return value;
+ }
+ }
+}
diff --git a/Game/Assets/Scripts/Model/Range.cs.meta b/Game/Assets/Scripts/Utils/MathHelper.cs.meta
similarity index 52%
rename from Game/Assets/Scripts/Model/Range.cs.meta
rename to Game/Assets/Scripts/Utils/MathHelper.cs.meta
index 6692273..b28e372 100644
--- a/Game/Assets/Scripts/Model/Range.cs.meta
+++ b/Game/Assets/Scripts/Utils/MathHelper.cs.meta
@@ -1,8 +1,12 @@
fileFormatVersion: 2
-guid: b436281f9c7d49f4d935ae009d4559a8
+guid: 29212ca52a4f0a64bbc8cffe74a3f4b7
+timeCreated: 1434538689
+licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Utils/QuadTree.cs b/Game/Assets/Scripts/Utils/QuadTree.cs
index 642ee67..8bbd532 100644
--- a/Game/Assets/Scripts/Utils/QuadTree.cs
+++ b/Game/Assets/Scripts/Utils/QuadTree.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransportGame.Model;
+using TransportGame.Primitives;
namespace TransportGame.Utils
{
@@ -62,12 +63,12 @@ namespace TransportGame.Utils
private void Subdivide()
{
float midx = Boundary.Left + Boundary.Width / 2f;
- float midy = Boundary.Top + Boundary.Height / 2f;
+ float midy = Boundary.Bottom + Boundary.Height / 2f;
- NorthWest = new QuadTree(Boundary.Left, Boundary.Top, midx, midy);
- NorthEast = new QuadTree(midx, Boundary.Top, Boundary.Right, midy);
- SouthEast = new QuadTree(midx, midy, Boundary.Right, Boundary.Bottom);
- SouthWest = new QuadTree(Boundary.Left, midy, midx, Boundary.Bottom);
+ NorthWest = new QuadTree(Boundary.Left, Boundary.Bottom, midx, midy);
+ NorthEast = new QuadTree(midx, Boundary.Bottom, Boundary.Right, midy);
+ SouthEast = new QuadTree(midx, midy, Boundary.Right, Boundary.Top);
+ SouthWest = new QuadTree(Boundary.Left, midy, midx, Boundary.Top);
foreach (var point in points)
Add(point);
@@ -258,7 +259,7 @@ namespace TransportGame.Utils
public IEnumerable Query(Rectangle rect)
{
// No intersection
- if (!Rectangle.Intersects(rect, Boundary))
+ if (!Rectangle.Intersect(rect, Boundary))
return Enumerable.Empty();
if (NorthWest == null)
diff --git a/Game/Game-csharp.sln b/Game/Game-csharp.sln
index 2d38414..9012803 100644
--- a/Game/Game-csharp.sln
+++ b/Game/Game-csharp.sln
@@ -23,7 +23,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
+ GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Assembly-CSharp.csproj
Policies = $0
$0.TextStylePolicy = $1
diff --git a/Game/Game.sln b/Game/Game.sln
index 5c83234..584f99b 100644
--- a/Game/Game.sln
+++ b/Game/Game.sln
@@ -29,7 +29,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
+ GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Assembly-CSharp.csproj
Policies = $0
$0.TextStylePolicy = $1
diff --git a/Game/UnityVS.Game.CSharp.csproj b/Game/UnityVS.Game.CSharp.csproj
index d11fc8f..d02f2fd 100644
--- a/Game/UnityVS.Game.CSharp.csproj
+++ b/Game/UnityVS.Game.CSharp.csproj
@@ -85,26 +85,26 @@
-
-
+
+
-
-
-
+
+
+
-
+
-
+
@@ -118,5 +118,6 @@
+
\ No newline at end of file