diff --git a/Game/Assets/Scripts/Model/LineSegment.cs b/Game/Assets/Scripts/Model/LineSegment.cs
new file mode 100644
index 0000000..65d2606
--- /dev/null
+++ b/Game/Assets/Scripts/Model/LineSegment.cs
@@ -0,0 +1,100 @@
+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 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/LineSegment.cs.meta b/Game/Assets/Scripts/Model/LineSegment.cs.meta
new file mode 100644
index 0000000..a68ae4b
--- /dev/null
+++ b/Game/Assets/Scripts/Model/LineSegment.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: eaabdeeb068e1dc46a7a9da6fd47f393
+timeCreated: 1432847695
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Model/Rectangle.cs b/Game/Assets/Scripts/Model/Rectangle.cs
new file mode 100644
index 0000000..ecbf0f3
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Rectangle.cs
@@ -0,0 +1,77 @@
+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/Rectangle.cs.meta b/Game/Assets/Scripts/Model/Rectangle.cs.meta
new file mode 100644
index 0000000..bae31f6
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Rectangle.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 01c02a9fd2c3d0142905c23fb3142b6f
+timeCreated: 1432824087
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Game/Assets/Scripts/Model/Vector2.cs b/Game/Assets/Scripts/Model/Vector2.cs
new file mode 100644
index 0000000..710319c
--- /dev/null
+++ b/Game/Assets/Scripts/Model/Vector2.cs
@@ -0,0 +1,230 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+
+namespace TransportGame.Model
+{
+ public struct Vector2
+ {
+ ///
+ /// Zero vector
+ ///
+ public static readonly Vector2 Zero = new Vector2(0, 0);
+
+ ///
+ /// Unit vector
+ ///
+ public static readonly Vector2 Unit = new Vector2(1, 0);
+
+ ///
+ /// Gets the X component
+ ///
+ public float X { get; private set; }
+
+ ///
+ /// Gets the Y component
+ ///
+ public float Y { get; private set; }
+
+ ///
+ /// Initializes a vector2
+ ///
+ /// X component
+ /// Y component
+ public Vector2(float x, float y)
+ : this()
+ {
+ X = x;
+ Y = y;
+ }
+
+ ///
+ /// Gets the length of the vector
+ ///
+ public float Length
+ {
+ get
+ {
+ return (float)Math.Sqrt(LengthSq);
+ }
+ }
+
+ ///
+ /// Gets the length of the vector squared
+ ///
+ public float LengthSq
+ {
+ get
+ {
+ return X * X + Y * Y;
+ }
+ }
+
+ ///
+ /// Gets the normalized vector
+ ///
+ /// Normalized vector
+ public Vector2 Normalized
+ {
+ get
+ {
+ float len = Length;
+ return new Vector2(X / len, Y / len);
+ }
+ }
+
+ ///
+ /// Rotates vector by given number of radians
+ ///
+ ///
+ ///
+ public Vector2 Rotate(float radians)
+ {
+ float sin = (float)Math.Sin(radians);
+ float cos = (float)Math.Cos(radians);
+
+ return new Vector2(X * cos - Y * sin, X * sin + Y * cos);
+ }
+
+ ///
+ /// Rotates vector by given number of degrees
+ ///
+ ///
+ ///
+ public Vector2 RotateDeg(float degrees)
+ {
+ return Rotate(degrees * (float)Math.PI / 180f);
+ }
+
+ ///
+ /// Sum operator
+ ///
+ /// First vector
+ /// Second vector
+ /// Result of addition
+ public static Vector2 operator +(Vector2 a, Vector2 b)
+ {
+ return new Vector2(a.X + b.X, a.Y + b.Y);
+ }
+
+ ///
+ /// Subtract operator
+ ///
+ /// First vector
+ /// Second vector
+ /// Result of subtraction
+ public static Vector2 operator -(Vector2 a, Vector2 b)
+ {
+ return new Vector2(a.X - b.X, a.Y - b.Y);
+ }
+
+ ///
+ /// Multiply by constant
+ ///
+ /// Vector
+ /// Constant
+ /// Result
+ public static Vector2 operator *(Vector2 a, float c)
+ {
+ return new Vector2(a.X * c, a.Y * c);
+ }
+
+ ///
+ /// Multiply by constant
+ ///
+ /// Constant
+ /// Vector
+ /// Result
+ public static Vector2 operator *(float c, Vector2 a)
+ {
+ return new Vector2(a.X * c, a.Y * c);
+ }
+
+ ///
+ /// Divide by constant
+ ///
+ /// Vector
+ /// Constant
+ /// Result
+ public static Vector2 operator /(Vector2 a, float c)
+ {
+ return new Vector2(a.X / c, a.Y / c);
+ }
+
+ ///
+ /// Equality operator
+ ///
+ /// First vector
+ /// Second vector
+ /// True if vectors are equal
+ public static bool operator ==(Vector2 a, Vector2 b)
+ {
+ return a.X == b.X && a.Y == b.Y;
+ }
+ ///
+ /// Inequality operator
+ ///
+ /// First vector
+ /// Second vector
+ /// True if vectors are not equal
+ public static bool operator !=(Vector2 a, Vector2 b)
+ {
+ return a.X != b.X || a.Y != b.Y;
+ }
+
+ ///
+ /// Calculates dot product of two vectors
+ ///
+ /// First vector
+ /// Second vector
+ /// Dot product
+ public static float Dot(Vector2 a, Vector2 b)
+ {
+ return a.X * b.X + a.Y * b.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);
+ }
+
+ public override string ToString()
+ {
+ return String.Format("({0}, {1})", X, Y);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Vector2)
+ {
+ Vector2 other = (Vector2)obj;
+ return X == other.X && Y == other.Y;
+ }
+
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return X.GetHashCode() * 7 + Y.GetHashCode();
+ }
+ }
+}
diff --git a/Game/Assets/Scripts/Model/Point.cs.meta b/Game/Assets/Scripts/Model/Vector2.cs.meta
similarity index 100%
rename from Game/Assets/Scripts/Model/Point.cs.meta
rename to Game/Assets/Scripts/Model/Vector2.cs.meta