Implemented vector2, rectangle, line segment.
This commit is contained in:
parent
22f1905b1b
commit
4e957167ed
100
Game/Assets/Scripts/Model/LineSegment.cs
Normal file
100
Game/Assets/Scripts/Model/LineSegment.cs
Normal file
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the distance from point p to line segment
|
||||
/// </summary>
|
||||
/// <param name="line">Line</param>
|
||||
/// <param name="p">Point</param>
|
||||
/// <returns>Distance</returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
12
Game/Assets/Scripts/Model/LineSegment.cs.meta
Normal file
12
Game/Assets/Scripts/Model/LineSegment.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eaabdeeb068e1dc46a7a9da6fd47f393
|
||||
timeCreated: 1432847695
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
77
Game/Assets/Scripts/Model/Rectangle.cs
Normal file
77
Game/Assets/Scripts/Model/Rectangle.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
12
Game/Assets/Scripts/Model/Rectangle.cs.meta
Normal file
12
Game/Assets/Scripts/Model/Rectangle.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01c02a9fd2c3d0142905c23fb3142b6f
|
||||
timeCreated: 1432824087
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
230
Game/Assets/Scripts/Model/Vector2.cs
Normal file
230
Game/Assets/Scripts/Model/Vector2.cs
Normal file
@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TransportGame.Model
|
||||
{
|
||||
public struct Vector2
|
||||
{
|
||||
/// <summary>
|
||||
/// Zero vector
|
||||
/// </summary>
|
||||
public static readonly Vector2 Zero = new Vector2(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Unit vector
|
||||
/// </summary>
|
||||
public static readonly Vector2 Unit = new Vector2(1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the X component
|
||||
/// </summary>
|
||||
public float X { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Y component
|
||||
/// </summary>
|
||||
public float Y { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a vector2
|
||||
/// </summary>
|
||||
/// <param name="x">X component</param>
|
||||
/// <param name="y">Y component</param>
|
||||
public Vector2(float x, float y)
|
||||
: this()
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the vector
|
||||
/// </summary>
|
||||
public float Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (float)Math.Sqrt(LengthSq);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the vector squared
|
||||
/// </summary>
|
||||
public float LengthSq
|
||||
{
|
||||
get
|
||||
{
|
||||
return X * X + Y * Y;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the normalized vector
|
||||
/// </summary>
|
||||
/// <returns>Normalized vector</returns>
|
||||
public Vector2 Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
float len = Length;
|
||||
return new Vector2(X / len, Y / len);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotates vector by given number of radians
|
||||
/// </summary>
|
||||
/// <param name="radians"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotates vector by given number of degrees
|
||||
/// </summary>
|
||||
/// <param name="degrees"></param>
|
||||
/// <returns></returns>
|
||||
public Vector2 RotateDeg(float degrees)
|
||||
{
|
||||
return Rotate(degrees * (float)Math.PI / 180f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sum operator
|
||||
/// </summary>
|
||||
/// <param name="a">First vector</param>
|
||||
/// <param name="b">Second vector</param>
|
||||
/// <returns>Result of addition</returns>
|
||||
public static Vector2 operator +(Vector2 a, Vector2 b)
|
||||
{
|
||||
return new Vector2(a.X + b.X, a.Y + b.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract operator
|
||||
/// </summary>
|
||||
/// <param name="a">First vector</param>
|
||||
/// <param name="b">Second vector</param>
|
||||
/// <returns>Result of subtraction</returns>
|
||||
public static Vector2 operator -(Vector2 a, Vector2 b)
|
||||
{
|
||||
return new Vector2(a.X - b.X, a.Y - b.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply by constant
|
||||
/// </summary>
|
||||
/// <param name="a">Vector</param>
|
||||
/// <param name="c">Constant</param>
|
||||
/// <returns>Result</returns>
|
||||
public static Vector2 operator *(Vector2 a, float c)
|
||||
{
|
||||
return new Vector2(a.X * c, a.Y * c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply by constant
|
||||
/// </summary>
|
||||
/// <param name="c">Constant</param>
|
||||
/// <param name="a">Vector</param>
|
||||
/// <returns>Result</returns>
|
||||
public static Vector2 operator *(float c, Vector2 a)
|
||||
{
|
||||
return new Vector2(a.X * c, a.Y * c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divide by constant
|
||||
/// </summary>
|
||||
/// <param name="a">Vector</param>
|
||||
/// <param name="c">Constant</param>
|
||||
/// <returns>Result</returns>
|
||||
public static Vector2 operator /(Vector2 a, float c)
|
||||
{
|
||||
return new Vector2(a.X / c, a.Y / c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equality operator
|
||||
/// </summary>
|
||||
/// <param name="a">First vector</param>
|
||||
/// <param name="b">Second vector</param>
|
||||
/// <returns>True if vectors are equal</returns>
|
||||
public static bool operator ==(Vector2 a, Vector2 b)
|
||||
{
|
||||
return a.X == b.X && a.Y == b.Y;
|
||||
}
|
||||
/// <summary>
|
||||
/// Inequality operator
|
||||
/// </summary>
|
||||
/// <param name="a">First vector</param>
|
||||
/// <param name="b">Second vector</param>
|
||||
/// <returns>True if vectors are not equal</returns>
|
||||
public static bool operator !=(Vector2 a, Vector2 b)
|
||||
{
|
||||
return a.X != b.X || a.Y != b.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates dot product of two vectors
|
||||
/// </summary>
|
||||
/// <param name="a">First vector</param>
|
||||
/// <param name="b">Second vector</param>
|
||||
/// <returns>Dot product</returns>
|
||||
public static float Dot(Vector2 a, Vector2 b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vector corresponding with specified angle (in radians)
|
||||
/// </summary>
|
||||
/// <param name="rads">Radians</param>
|
||||
/// <returns>Vector</returns>
|
||||
public static Vector2 FromRadians(float rads)
|
||||
{
|
||||
return new Vector2((float)Math.Cos(rads), (float)Math.Sin(rads));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vector corresponding with specified angle (in degrees)
|
||||
/// </summary>
|
||||
/// <param name="degs">Degrees</param>
|
||||
/// <returns>Vector</returns>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user