110 lines
3.9 KiB
C#
110 lines
3.9 KiB
C#
using System;
|
|
#if UNITY_5_3_OR_NEWER
|
|
using Vector3Float = UnityEngine.Vector3;
|
|
#endif
|
|
|
|
namespace LinearAlgebra {
|
|
|
|
/// <summary>
|
|
/// A direction in 3D space
|
|
/// </summary>
|
|
/// A direction is represented using two angles:
|
|
/// * The horizontal angle ranging from -180 (inclusive) to 180 (exclusive)
|
|
/// degrees which is a rotation in the horizontal plane
|
|
/// * A vertical angle ranging from -90 (inclusive) to 90 (exclusive) degrees
|
|
/// which is the rotation in the up/down direction applied after the horizontal
|
|
/// rotation has been applied.
|
|
/// The angles are automatically normalized to stay within the abovenmentioned
|
|
/// ranges.
|
|
public class Direction {
|
|
public float horizontal;
|
|
public float vertical;
|
|
|
|
public Direction() {
|
|
horizontal = 0;
|
|
vertical = 0;
|
|
}
|
|
public Direction(Angle horizontal, Angle vertical) {
|
|
this.horizontal = horizontal.inDegrees;
|
|
this.vertical = vertical.inDegrees;
|
|
this.Normalize();
|
|
}
|
|
|
|
public static Direction Degrees(float horizontal, float vertical) {
|
|
Direction d = new() {
|
|
horizontal = horizontal,
|
|
vertical = vertical
|
|
};
|
|
d.Normalize();
|
|
return d;
|
|
}
|
|
public static Direction Radians(float horizontal, float vertical) {
|
|
Direction d = new() {
|
|
horizontal = horizontal * Angle.Rad2Deg,
|
|
vertical = vertical * Angle.Rad2Deg
|
|
};
|
|
d.Normalize();
|
|
return d;
|
|
}
|
|
|
|
public readonly static Direction forward = Degrees(0, 0);
|
|
public readonly static Direction backward = Degrees(-180, 0);
|
|
public readonly static Direction up = Degrees(0, 90);
|
|
public readonly static Direction down = Degrees(0, -90);
|
|
public readonly static Direction left = Degrees(-90, 0);
|
|
public readonly static Direction right = Degrees(90, 0);
|
|
|
|
public void Normalize() {
|
|
this.vertical = Angles.Normalize(this.vertical);
|
|
if (this.vertical > 90 || this.vertical < -90) {
|
|
this.horizontal += 180;
|
|
this.vertical = 180 - this.vertical;
|
|
}
|
|
this.horizontal = Angles.Normalize(this.horizontal);
|
|
}
|
|
|
|
public Vector3Float ToVector3() {
|
|
float verticalRad = ((float)Math.PI / 2) - this.vertical * Angle.Deg2Rad;
|
|
float horizontalRad = this.horizontal * Angle.Deg2Rad;
|
|
float cosVertical = (float)Math.Cos(verticalRad);
|
|
float sinVertical = (float)Math.Sin(verticalRad);
|
|
float cosHorizontal = (float)Math.Cos(horizontalRad);
|
|
float sinHorizontal = (float)Math.Sin(horizontalRad);
|
|
|
|
float x = sinVertical * sinHorizontal;
|
|
float y = cosVertical;
|
|
float z = sinVertical * cosHorizontal;
|
|
|
|
Vector3Float v = new(x, y, z);
|
|
return v;
|
|
}
|
|
|
|
public static bool operator ==(Direction d1, Direction d2) {
|
|
bool horizontalEq = d1.horizontal == d2.horizontal;
|
|
bool verticalEq = d1.vertical == d2.vertical;
|
|
return horizontalEq && verticalEq;
|
|
}
|
|
|
|
public static bool operator !=(Direction d1, Direction d2) {
|
|
bool horizontalNEq = d1.horizontal != d2.horizontal;
|
|
bool verticalNEq = d1.vertical != d2.vertical;
|
|
return horizontalNEq || verticalNEq;
|
|
}
|
|
|
|
public override bool Equals(object obj) {
|
|
if (obj is not Direction d)
|
|
return false;
|
|
|
|
bool horizontalEq = this.horizontal == d.horizontal;
|
|
bool verticalEq = this.vertical == d.vertical;
|
|
return horizontalEq && verticalEq;
|
|
}
|
|
|
|
|
|
public override int GetHashCode() {
|
|
return (this.horizontal, this.vertical).GetHashCode();
|
|
}
|
|
|
|
}
|
|
|
|
} |