using System;
using UnityEngine;
namespace ProceduralToolkit
{
///
/// Vector extensions
///
public static class VectorE
{
#region Vector2
///
/// Returns a new vector with zero Y component
///
public static Vector2 ToVector2X(this Vector2 vector)
{
return new Vector2(vector.x, 0);
}
///
/// Returns a new vector with zero X component
///
public static Vector2 ToVector2Y(this Vector2 vector)
{
return new Vector2(0, vector.y);
}
///
/// Projects the vector onto the three dimensional XY plane
///
public static Vector3 ToVector3XY(this Vector2 vector)
{
return new Vector3(vector.x, vector.y, 0);
}
///
/// Projects the vector onto the three dimensional XZ plane
///
public static Vector3 ToVector3XZ(this Vector2 vector)
{
return new Vector3(vector.x, 0, vector.y);
}
///
/// Projects the vector onto the three dimensional YZ plane
///
public static Vector3 ToVector3YZ(this Vector2 vector)
{
return new Vector3(0, vector.x, vector.y);
}
///
/// Returns true if vectors lie on the same line, false otherwise
///
public static bool IsCollinear(this Vector2 vector, Vector2 other)
{
return Mathf.Abs(PerpDot(vector, other)) < Geometry.Epsilon;
}
///
/// Returns a new vector rotated counterclockwise by 90°
///
///
/// Hill, F. S. Jr. "The Pleasures of 'Perp Dot' Products."
/// Ch. II.5 in Graphics Gems IV (Ed. P. S. Heckbert). San Diego: Academic Press, pp. 138-148, 1994
///
public static Vector2 Perp(this Vector2 vector)
{
return new Vector2(-vector.y, vector.x);
}
///
/// Returns a perp dot product of vectors
///
///
/// Hill, F. S. Jr. "The Pleasures of 'Perp Dot' Products."
/// Ch. II.5 in Graphics Gems IV (Ed. P. S. Heckbert). San Diego: Academic Press, pp. 138-148, 1994
///
public static float PerpDot(Vector2 a, Vector2 b)
{
return a.x*b.y - a.y*b.x;
}
///
/// Returns a signed clockwise angle in degrees [-180, 180] between from and to
///
/// The angle extends round from this vector
/// The angle extends round to this vector
public static float SignedAngle(Vector2 from, Vector2 to)
{
return Mathf.Atan2(PerpDot(to, from), Vector2.Dot(to, from))*Mathf.Rad2Deg;
}
///
/// Returns a clockwise angle in degrees [0, 360] between from and to
///
/// The angle extends round from this vector
/// The angle extends round to this vector
public static float Angle360(Vector2 from, Vector2 to)
{
float angle = SignedAngle(from, to);
while (angle < 0)
{
angle += 360;
}
return angle;
}
///
/// Calculates the linear parameter t that produces the interpolant value within the range [a, b].
///
public static Vector2 InverseLerp(Vector2 a, Vector2 b, Vector2 value)
{
return new Vector2(
Mathf.InverseLerp(a.x, b.x, value.x),
Mathf.InverseLerp(a.y, b.y, value.y));
}
///
/// Returns a new vector rotated clockwise by the specified angle
///
public static Vector2 RotateCW(this Vector2 vector, float degrees)
{
float radians = degrees*Mathf.Deg2Rad;
float sin = Mathf.Sin(radians);
float cos = Mathf.Cos(radians);
return new Vector2(
vector.x*cos + vector.y*sin,
vector.y*cos - vector.x*sin);
}
///
/// Returns a new vector rotated counterclockwise by the specified angle
///
public static Vector2 RotateCCW(this Vector2 vector, float degrees)
{
float radians = degrees*Mathf.Deg2Rad;
float sin = Mathf.Sin(radians);
float cos = Mathf.Cos(radians);
return new Vector2(
vector.x*cos - vector.y*sin,
vector.y*cos + vector.x*sin);
}
///
/// Returns a new vector rotated clockwise by 45°
///
public static Vector2 RotateCW45(this Vector2 vector)
{
return new Vector2((vector.x + vector.y)*PTUtils.Sqrt05, (vector.y - vector.x)*PTUtils.Sqrt05);
}
///
/// Returns a new vector rotated counterclockwise by 45°
///
public static Vector2 RotateCCW45(this Vector2 vector)
{
return new Vector2((vector.x - vector.y)*PTUtils.Sqrt05, (vector.y + vector.x)*PTUtils.Sqrt05);
}
///
/// Returns a new vector rotated clockwise by 90°
///
public static Vector2 RotateCW90(this Vector2 vector)
{
return new Vector2(vector.y, -vector.x);
}
///
/// Returns a new vector rotated counterclockwise by 90°
///
public static Vector2 RotateCCW90(this Vector2 vector)
{
return new Vector2(-vector.y, vector.x);
}
public static string ToString(this Vector2 vector, string format, IFormatProvider formatProvider)
{
return string.Format("({0}, {1})", vector.x.ToString(format, formatProvider), vector.y.ToString(format, formatProvider));
}
#endregion Vector2
#region Vector2Int
///
/// Returns a perp of vector
///
///
/// Hill, F. S. Jr. "The Pleasures of 'Perp Dot' Products."
/// Ch. II.5 in Graphics Gems IV (Ed. P. S. Heckbert). San Diego: Academic Press, pp. 138-148, 1994
///
public static Vector2Int Perp(this Vector2Int vector)
{
return new Vector2Int(-vector.y, vector.x);
}
///
/// Returns a perp dot product of vectors
///
///
/// Hill, F. S. Jr. "The Pleasures of 'Perp Dot' Products."
/// Ch. II.5 in Graphics Gems IV (Ed. P. S. Heckbert). San Diego: Academic Press, pp. 138-148, 1994
///
public static int PerpDot(Vector2Int a, Vector2Int b)
{
return a.x*b.y - a.y*b.x;
}
#endregion Vector2Int
#region Vector3
///
/// Returns a new vector with zero Y and Z components
///
public static Vector3 ToVector3X(this Vector3 vector)
{
return new Vector3(vector.x, 0, 0);
}
///
/// Returns a new vector with zero X and Z components
///
public static Vector3 ToVector3Y(this Vector3 vector)
{
return new Vector3(0, vector.y, 0);
}
///
/// Returns a new vector with zero X and Y components
///
public static Vector3 ToVector3Z(this Vector3 vector)
{
return new Vector3(0, 0, vector.z);
}
///
/// Returns a new vector with zero Z component
///
public static Vector3 ToVector3XY(this Vector3 vector)
{
return new Vector3(vector.x, vector.y, 0);
}
///
/// Returns a new vector with zero Y component
///
public static Vector3 ToVector3XZ(this Vector3 vector)
{
return new Vector3(vector.x, 0, vector.z);
}
///
/// Returns a new vector with zero X component
///
public static Vector3 ToVector3YZ(this Vector3 vector)
{
return new Vector3(0, vector.y, vector.z);
}
///
/// Returns a new Vector2 made from X and Y components of this vector
///
public static Vector2 ToVector2XY(this Vector3 vector)
{
return new Vector2(vector.x, vector.y);
}
///
/// Returns a new Vector2 made from X and Z components of this vector
///
public static Vector2 ToVector2XZ(this Vector3 vector)
{
return new Vector2(vector.x, vector.z);
}
///
/// Returns a new Vector2 made from Y and Z components of this vector
///
public static Vector2 ToVector2YZ(this Vector3 vector)
{
return new Vector2(vector.y, vector.z);
}
///
/// Returns an angle in degrees [0, 360] between from and to
///
/// The angle extends round from this vector
/// The angle extends round to this vector
/// Up direction of the clockwise axis
public static float Angle360(Vector3 from, Vector3 to, Vector3 normal)
{
float angle = Vector3.SignedAngle(from, to, normal);
while (angle < 0)
{
angle += 360;
}
return angle;
}
///
/// Calculates the linear parameter t that produces the interpolant value within the range [a, b].
///
public static Vector3 InverseLerp(Vector3 a, Vector3 b, Vector3 value)
{
return new Vector3(
Mathf.InverseLerp(a.x, b.x, value.x),
Mathf.InverseLerp(a.y, b.y, value.y),
Mathf.InverseLerp(a.z, b.z, value.z));
}
#endregion Vector3
#region Vector4
///
/// Calculates the linear parameter t that produces the interpolant value within the range [a, b].
///
public static Vector4 InverseLerp(Vector4 a, Vector4 b, Vector4 value)
{
return new Vector4(
Mathf.InverseLerp(a.x, b.x, value.x),
Mathf.InverseLerp(a.y, b.y, value.y),
Mathf.InverseLerp(a.z, b.z, value.z),
Mathf.InverseLerp(a.w, b.w, value.w));
}
#endregion Vector4
}
}