diff --git a/src/JuicyGraphics.csproj b/src/JuicyGraphics.csproj
index 3b59ab8..4cbde03 100644
--- a/src/JuicyGraphics.csproj
+++ b/src/JuicyGraphics.csproj
@@ -51,7 +51,13 @@
+
+
+
+
+
+
@@ -66,7 +72,7 @@
mainForm.cs
-
+
@@ -124,8 +130,6 @@
-
-
-
+
\ No newline at end of file
diff --git a/src/JuicyGraphics/Program.cs b/src/JuicyGraphics/App.cs
similarity index 78%
rename from src/JuicyGraphics/Program.cs
rename to src/JuicyGraphics/App.cs
index 24c3c07..6ad3f1c 100644
--- a/src/JuicyGraphics/Program.cs
+++ b/src/JuicyGraphics/App.cs
@@ -1,11 +1,8 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using System.Windows.Forms;
namespace JuicyGraphics {
- static class Program {
+ static class app {
///
/// The main entry point for the application.
///
diff --git a/src/JuicyGraphics/math/doubleExtentions.cs b/src/JuicyGraphics/math/doubleExtentions.cs
new file mode 100644
index 0000000..3edd0fb
--- /dev/null
+++ b/src/JuicyGraphics/math/doubleExtentions.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace JuicyGraphics.Mathematics {
+
+ public static class doubleExtension {
+ public static bool almostEqualsWithAbsTolerance(this double a, double b, double maxAbsoluteError) {
+ double diff = Math.Abs(a - b);
+
+ if (a.Equals(b)) {
+ return true;
+ }
+
+ return diff <= maxAbsoluteError;
+ }
+
+ public static bool almostEqualsWithAbsOrRelativeTolerance(
+ this double a,
+ double b,
+ double maxAbsoluteError,
+ double maxRelativeError) {
+ if (almostEqualsWithAbsTolerance(a, b, maxAbsoluteError)) {
+ return true;
+ }
+
+ double absA = Math.Abs(a);
+ double absB = Math.Abs(b);
+
+ double relativeError;
+ if (absB > absA) {
+ relativeError = Math.Abs((a - b) / b);
+ }
+ else {
+ relativeError = Math.Abs((a - b) / a);
+ }
+
+ return relativeError <= maxRelativeError;
+ }
+
+ public static bool almostEqualsWithAbsOrUlpsTolerance(
+ this double a,
+ double b,
+ double maxAbsoluteError,
+ long maxUlps) {
+ if (almostEqualsWithAbsTolerance(a, b, maxAbsoluteError)) {
+ return true;
+ }
+
+ long longA = BitConverter.DoubleToInt64Bits(a);
+ longA = longA < 0 ? (long)(0x8000000000000000 - (ulong)longA) : longA;
+
+ long longB = BitConverter.DoubleToInt64Bits(b);
+ longB = longB < 0 ? (long)(0x8000000000000000 - (ulong)longB) : longB;
+
+ long diff = Math.Abs(longA - longB);
+ return diff <= maxUlps;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/JuicyGraphics/math/normalizeVectorException.cs b/src/JuicyGraphics/math/normalizeVectorException.cs
new file mode 100644
index 0000000..ee07027
--- /dev/null
+++ b/src/JuicyGraphics/math/normalizeVectorException.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace JuicyGraphics.Exceptions {
+
+ [Serializable]
+ public class normalizeVectorException : Exception {
+ public normalizeVectorException() {
+ }
+
+ public normalizeVectorException(string message)
+ : base(message) {
+ }
+
+ public normalizeVectorException(string message, Exception innerException)
+ : base(message, innerException) {
+ }
+
+ protected normalizeVectorException(SerializationInfo info, StreamingContext context)
+ : base(info, context) {
+ }
+ }
+}
diff --git a/src/JuicyGraphics/math/vec2.cs b/src/JuicyGraphics/math/vec2.cs
new file mode 100644
index 0000000..741ac76
--- /dev/null
+++ b/src/JuicyGraphics/math/vec2.cs
@@ -0,0 +1,637 @@
+using System;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+namespace JuicyGraphics.Mathematics {
+ using Exceptions;
+
+ [ImmutableObject(true), Serializable]
+ public struct vec2
+ : IComparable, IComparable, IEquatable, IFormattable {
+
+ private readonly double _x;
+ private readonly double _y;
+
+ public vec2(double x, double y) {
+ this._x = x;
+ this._y = y;
+ }
+
+ public vec2(double[] xy) {
+ if (xy.Length == 2) {
+ this._x = xy[0];
+ this._y = xy[1];
+ }
+ else {
+ throw new ArgumentException(TWO_COMPONENTS);
+ }
+ }
+
+ public vec2(vec2 v1) {
+ this._x = v1.x;
+ this._y = v1.y;
+ }
+
+ public double x {
+ get {
+ return _x;
+ }
+ }
+
+ public double y {
+ get {
+ return _y;
+ }
+ }
+
+ public vec2 xx {
+ get {
+ return new vec2(_x, _x);
+ }
+ }
+
+ public vec2 xy {
+ get {
+ return this;
+ }
+ }
+
+ public vec2 yx {
+ get {
+ return new vec2(_y, _x);
+ }
+ }
+
+ public vec2 yy {
+ get {
+ return new vec2(_y, _y);
+ }
+ }
+
+ public vec2 normal {
+ get {
+ return this.normalize();
+ }
+ }
+
+ public double magnitude {
+ get {
+ return Math.Sqrt(this.sumComponentSqrs());
+ }
+ }
+
+ [XmlIgnore]
+ public double[] array {
+ get {
+ return new[] { this.x, this.y };
+ }
+ }
+
+ public double this[int index] {
+ get {
+ switch (index) {
+ case 0:
+ return this._x;
+ case 1:
+ return this._y;
+ default:
+ throw new ArgumentException(TWO_COMPONENTS, "index");
+ }
+ }
+ }
+
+ public static vec2 operator +(vec2 v1, vec2 v2) {
+ return new vec2(
+ v1.x + v2.x,
+ v1.y + v2.y);
+ }
+
+ public static vec2 operator -(vec2 v1, vec2 v2) {
+ return new vec2(
+ v1.x - v2.x,
+ v1.y - v2.y);
+ }
+
+ public static vec2 operator *(vec2 v1, double s2) {
+ return
+ new vec2(
+ v1.x * s2,
+ v1.y * s2);
+ }
+
+ public static vec2 operator *(double s1, vec2 v2) {
+ return v2 * s1;
+ }
+
+ public static vec2 operator /(vec2 v1, double s2) {
+ return new vec2(
+ v1.x / s2,
+ v1.y / s2);
+ }
+
+ public static vec2 operator -(vec2 v1) {
+ return new vec2(
+ -v1.x,
+ -v1.y);
+ }
+
+ public static vec2 operator +(vec2 v1) {
+ return new vec2(
+ +v1.x,
+ +v1.y);
+ }
+
+ public static bool operator <(vec2 v1, vec2 v2) {
+ return v1.sumComponentSqrs() < v2.sumComponentSqrs();
+ }
+
+ public static bool operator >(vec2 v1, vec2 v2) {
+ return v1.sumComponentSqrs() > v2.sumComponentSqrs();
+ }
+
+ public static bool operator <=(vec2 v1, vec2 v2) {
+ return v1.sumComponentSqrs() <= v2.sumComponentSqrs();
+ }
+
+ public static bool operator >=(vec2 v1, vec2 v2) {
+ return v1.sumComponentSqrs() >= v2.sumComponentSqrs();
+ }
+
+ public static bool operator ==(vec2 v1, vec2 v2) {
+ return
+ v1.x == v2.x &&
+ v1.y == v2.y;
+ }
+
+ public static bool operator !=(vec2 v1, vec2 v2) {
+ return !(v1 == v2);
+ }
+
+ public static vec2 scale(vec2 vector, double magnitude) {
+ if (magnitude < 0) {
+ throw new ArgumentOutOfRangeException("magnitude", magnitude, NEGATIVE_magnitude);
+ }
+
+ if (vector == new vec2(0, 0)) {
+ throw new ArgumentException(ORIGIN_VECTOR_magnitude, "vector");
+ }
+
+ return vector * (magnitude / vector.magnitude);
+ }
+
+ public vec2 scale(double magnitude) {
+ return vec2.scale(this, magnitude);
+ }
+
+ public static double dotProduct(vec2 v1, vec2 v2) {
+ return
+ v1.x * v2.x +
+ v1.y * v2.y;
+ }
+
+ public double dotProduct(vec2 other) {
+ return dotProduct(this, other);
+ }
+
+ public static vec2 normalize(vec2 v1) {
+ if (double.IsInfinity(v1.magnitude)) {
+ v1 = normalizeSpecialCasesOrOrigional(v1);
+
+ if (v1.isNaN()) {
+ throw new normalizeVectorException(NORMALIZE_Inf);
+ }
+ }
+
+ if (v1.magnitude == 0) {
+ throw new normalizeVectorException(NORMALIZE_0);
+ }
+
+ if (v1.isNaN()) {
+ throw new normalizeVectorException(NORMALIZE_NaN);
+ }
+
+ return normalizeOrNaN(v1);
+ }
+
+ public static vec2 normalizeOrDefault(vec2 v1) {
+ v1 = normalizeSpecialCasesOrOrigional(v1);
+
+ if (v1.magnitude == 0) {
+ return origin;
+ }
+
+ if (v1.isNaN()) {
+ return NaN;
+ }
+
+ return normalizeOrNaN(v1);
+ }
+
+ public vec2 normalize() {
+ return normalize(this);
+ }
+
+ public vec2 normalizeOrDefault() {
+ return normalizeOrDefault(this);
+ }
+
+ private static vec2 normalizeOrNaN(vec2 v1) {
+ double inverse = 1 / v1.magnitude;
+
+ return new vec2(
+ v1.x * inverse,
+ v1.y * inverse);
+ }
+
+ private static vec2 normalizeSpecialCasesOrOrigional(vec2 v1) {
+ if (double.IsInfinity(v1.magnitude)) {
+ var x = v1.x == 0 ? 0 : v1.x == -0 ? -0 : double.IsPositiveInfinity(v1.x) ? 1 : double.IsNegativeInfinity(v1.x) ? -1 : double.NaN;
+ var y = v1.y == 0 ? 0 : v1.y == -0 ? -0 : double.IsPositiveInfinity(v1.y) ? 1 : double.IsNegativeInfinity(v1.y) ? -1 : double.NaN;
+
+ return new vec2(x, y);
+ }
+
+ return v1;
+ }
+
+ public static vec2 interpolate(vec2 v1, vec2 v2, double control, bool allowExtrapolation) {
+ if (!allowExtrapolation && (control > 1 || control < 0)) {
+ throw new ArgumentOutOfRangeException(
+ "control",
+ control,
+ INTERPOLATION_RANGE + "\n" + ARGUMENT_VALUE + control);
+ }
+
+ return new vec2(
+ v1.x * (1 - control) + v2.x * control,
+ v1.y * (1 - control) + v2.y * control);
+ }
+
+ public static vec2 interpolate(vec2 v1, vec2 v2, double control) {
+ return interpolate(v1, v2, control, false);
+ }
+
+ public vec2 interpolate(vec2 other, double control) {
+ return interpolate(this, other, control);
+ }
+
+ public vec2 interpolate(vec2 other, double control, bool allowExtrapolation) {
+ return interpolate(this, other, control);
+ }
+
+ public static double distance(vec2 v1, vec2 v2) {
+ return Math.Sqrt(
+ (v1.x - v2.x) * (v1.x - v2.x) +
+ (v1.y - v2.y) * (v1.y - v2.y));
+ }
+
+ public double distance(vec2 other) {
+ return distance(this, other);
+ }
+
+ public static double angle(vec2 v1, vec2 v2) {
+ if (v1 == v2) {
+ return 0;
+ }
+
+ return
+ Math.Acos(
+ Math.Min(1.0f, normalizeOrDefault(v1).dotProduct(normalizeOrDefault(v2))));
+ }
+
+ public double angle(vec2 other) {
+ return angle(this, other);
+ }
+
+ public static vec2 max(vec2 v1, vec2 v2) {
+ return v1 >= v2 ? v1 : v2;
+ }
+
+ public vec2 max(vec2 other) {
+ return max(this, other);
+ }
+
+ public static vec2 min(vec2 v1, vec2 v2) {
+ return v1 <= v2 ? v1 : v2;
+ }
+
+ public vec2 min(vec2 other) {
+ return min(this, other);
+ }
+
+ public static vec2 rotate(vec2 v1, double rad) {
+ double x = (v1.x * Math.Cos(rad)) - (v1.y * Math.Sin(rad));
+ double y = (v1.x * Math.Sin(rad)) + (v1.y * Math.Cos(rad));
+ return new vec2(x, y);
+ }
+
+ public vec2 rotate(double rad) {
+ return rotate(this, rad);
+ }
+
+ public static vec2 rotate(vec2 v1, double xOff, double yOff, double rad) {
+ double x = (v1.x * Math.Cos(rad)) - (v1.y * Math.Sin(rad)) + (xOff * (1 - Math.Cos(rad)) + yOff * Math.Sin(rad));
+ double y = (v1.x * Math.Sin(rad)) + (v1.y * Math.Cos(rad)) + (yOff * (1 - Math.Cos(rad)) - xOff * Math.Sin(rad));
+ return new vec2(x, y);
+ }
+
+ public vec2 rotate(double xOff, double yOff, double rad) {
+ return rotate(this, xOff, yOff, rad);
+ }
+
+ public static vec2 projection(vec2 v1, vec2 v2) {
+ return new vec2(v2 * (v1.dotProduct(v2) / Math.Pow(v2.magnitude, 2)));
+ }
+
+ public vec2 projection(vec2 direction) {
+ return projection(this, direction);
+ }
+
+ public static vec2 rejection(vec2 v1, vec2 v2) {
+ return v1 - v1.projection(v2);
+ }
+
+ public vec2 rejection(vec2 direction) {
+ return rejection(this, direction);
+ }
+
+ public vec2 reflection(vec2 reflector) {
+ this = vec2.reflection(this, reflector);
+ return this;
+ }
+
+ public static vec2 reflection(vec2 v1, vec2 v2) {
+ if (Math.Abs(Math.Abs(v1.angle(v2)) - Math.PI / 2) < Double.Epsilon) {
+ return -v1;
+ }
+
+ vec2 retval = new vec2(2 * v1.projection(v2) - v1);
+ return retval.scale(v1.magnitude);
+ }
+
+ public static Double abs(vec2 v1) {
+ return v1.magnitude;
+ }
+
+ public double abs() {
+ return this.magnitude;
+ }
+
+ public static double sumComponents(vec2 v1) {
+ return v1.x + v1.y;
+ }
+
+ public double sumComponents() {
+ return sumComponents(this);
+ }
+
+ public static double sumComponentSqrs(vec2 v1) {
+ vec2 v2 = sqrComponents(v1);
+ return v2.sumComponents();
+ }
+
+ public double sumComponentSqrs() {
+ return sumComponentSqrs(this);
+ }
+
+ public static vec2 powComponents(vec2 v1, double power) {
+ return new vec2(
+ Math.Pow(v1.x, power),
+ Math.Pow(v1.y, power));
+ }
+
+ public vec2 powComponents(double power) {
+ return powComponents(this, power);
+ }
+
+ public static vec2 sqrtComponents(vec2 v1) {
+ return new vec2(
+ Math.Sqrt(v1.x),
+ Math.Sqrt(v1.y));
+ }
+
+ public vec2 sqrtComponents() {
+ return sqrtComponents(this);
+ }
+
+ public static vec2 sqrComponents(vec2 v1) {
+ return new vec2(
+ v1.x * v1.x,
+ v1.y * v1.y);
+ }
+
+ public vec2 sqrComponents() {
+ return sqrComponents(this);
+ }
+
+ public static vec2 round(vec2 v1) {
+ return new vec2(Math.Round(v1.x), Math.Round(v1.y));
+ }
+
+ public static vec2 round(vec2 v1, int digits) {
+ return new vec2(Math.Round(v1.x, digits), Math.Round(v1.y, digits));
+ }
+
+ public static vec2 round(vec2 v1, MidpointRounding mode) {
+ return new vec2(Math.Round(v1.x, mode), Math.Round(v1.y, mode));
+ }
+
+ public static vec2 round(vec2 v1, int digits, MidpointRounding mode) {
+ return new vec2(Math.Round(v1.x, digits, mode), Math.Round(v1.y, digits, mode));
+ }
+
+ public vec2 round() {
+ return new vec2(Math.Round(this.x), Math.Round(this.y));
+ }
+
+ public vec2 round(int digits) {
+ return new vec2(Math.Round(this.x, digits), Math.Round(this.y, digits));
+ }
+
+ public vec2 round(MidpointRounding mode) {
+ return new vec2(Math.Round(this.x, mode), Math.Round(this.y, mode));
+ }
+
+ public vec2 round(int digits, MidpointRounding mode) {
+ return new vec2(Math.Round(this.x, digits, mode), Math.Round(this.y, digits, mode));
+ }
+
+ public override string ToString() {
+ return this.ToString(null, null);
+ }
+
+ public string ToVerbString() {
+ string output = null;
+
+ if (this.isUnitVector()) {
+ output += UNIT_VECTOR;
+ }
+ else {
+ output += POSITIONAL_VECTOR;
+ }
+
+ output += string.Format("( x={0}, y={1} )", this.x, this.y);
+ output += magnitude + this.magnitude;
+
+ return output;
+ }
+
+ public string ToString(string format, IFormatProvider formatProvider) {
+ if (format == null || format == "") {
+ return string.Format("({0}, {1})", this.x, this.y);
+ }
+
+ char firstChar = format[0];
+ string remainder = null;
+
+ if (format.Length > 1) {
+ remainder = format.Substring(1);
+ }
+
+ switch (firstChar) {
+ case 'x': return this.x.ToString(remainder, formatProvider);
+ case 'y': return this.y.ToString(remainder, formatProvider);
+ default:
+ return String.Format(
+ "({0}, {1})",
+ this.x.ToString(format, formatProvider),
+ this.y.ToString(format, formatProvider));
+ }
+ }
+
+ public override int GetHashCode() {
+ unchecked {
+ var hashCode = this.x.GetHashCode();
+ hashCode = (hashCode * 397) ^ this.y.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ public override bool Equals(object other) {
+ if (other is vec2) {
+ return other.Equals(this);
+ }
+ else {
+ return false;
+ }
+ }
+
+ public bool Equals(object other, double tolerance) {
+ if (other is vec2) {
+ return this.Equals((vec2)other, tolerance);
+ }
+ return false;
+ }
+
+ public bool Equals(vec2 other) {
+ return
+ this.x.Equals(other.x) &&
+ this.y.Equals(other.y);
+ }
+
+ public bool Equals(vec2 other, double tolerance) {
+ return
+ this.x.almostEqualsWithAbsTolerance(other.x, tolerance) &&
+ this.y.almostEqualsWithAbsTolerance(other.y, tolerance);
+ }
+
+ public int CompareTo(vec2 other) {
+ if (this < other) {
+ return -1;
+ }
+
+ if (this > other) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ public int CompareTo(object other) {
+ if (other is vec2) {
+ return this.CompareTo((vec2)other);
+ }
+
+ throw new ArgumentException(
+ NON_VECTOR_COMPARISON + "\n" + ARGUMENT_TYPE + other.GetType().ToString(),
+ "other");
+ }
+
+ public int CompareTo(vec2 other, double tolerance) {
+ var bothInfinite = double.IsInfinity(this.sumComponentSqrs()) && double.IsInfinity(other.sumComponentSqrs());
+
+ if (this.Equals(other, tolerance) || bothInfinite) {
+ return 0;
+ }
+
+ if (this < other) {
+ return -1;
+ }
+
+ return 1;
+ }
+
+ public int CompareTo(object other, double tolerance) {
+ if (other is vec2) {
+ return this.CompareTo((vec2)other, tolerance);
+ }
+
+ throw new ArgumentException(
+ NON_VECTOR_COMPARISON + "\n" + ARGUMENT_TYPE + other.GetType().ToString(),
+ "other");
+ }
+
+ public static bool isUnitVector(vec2 v1, double tolerance) {
+ return v1.magnitude.almostEqualsWithAbsTolerance(1, tolerance);
+ }
+
+ public static bool isUnitVector(vec2 v1) {
+ return v1.magnitude == 1;
+ }
+
+ public bool isUnitVector() {
+ return isUnitVector(this);
+ }
+
+ public bool isUnitVector(double tolerance) {
+ return isUnitVector(this, tolerance);
+ }
+
+ public static bool isNaN(vec2 v1) {
+ return double.IsNaN(v1.x) || double.IsNaN(v1.y);
+ }
+
+ public bool isNaN() {
+ return isNaN(this);
+ }
+
+ public static readonly vec2 origin = new vec2(0, 0);
+ public static readonly vec2 right = new vec2(1, 0);
+ public static readonly vec2 left = new vec2(-1, 0);
+ public static readonly vec2 down = new vec2(0, 1);
+ public static readonly vec2 up = new vec2(0, -1);
+
+
+ private const string NORMALIZE_NaN = "Cannot normalize a vector when it's magnitude is NaN";
+ private const string NORMALIZE_0 = "Cannot normalize a vector when it's magnitude is zero";
+ private const string NORMALIZE_Inf = "Cannot normalize a vector when it's magnitude is infinite except under special conditions";
+ private const string TWO_COMPONENTS = "Array must contain exactly two components (x, y)";
+ private const string INTERPOLATION_RANGE = "Control parameter must be a value between 0 & 1";
+ private const string NON_VECTOR_COMPARISON = "Cannot compare a vec2 to a non-vec2";
+ private const string ARGUMENT_TYPE = "The argument provided is a type of ";
+ private const string ARGUMENT_VALUE = "The argument provided has a value of ";
+ private const string ARGUMENT_LENGTH = "The argument provided has a length of ";
+ private const string NEGATIVE_magnitude = "The magnitude of a vec2 must be a positive value, (i.e. greater than 0)";
+ private const string ORIGIN_VECTOR_magnitude = "Cannot change the magnitude of vec2(0, 0)";
+
+ private const string UNIT_VECTOR = "Unit vector composing of ";
+ private const string POSITIONAL_VECTOR = "Positional vector composing of ";
+ private const string MAGNITUDE = " of magnitude ";
+
+ public static readonly vec2 minValue = new vec2(Double.MinValue, Double.MinValue);
+ public static readonly vec2 maxValue = new vec2(Double.MaxValue, Double.MaxValue);
+ public static readonly vec2 epsilon = new vec2(Double.Epsilon, Double.Epsilon);
+ public static readonly vec2 zero = origin;
+ public static readonly vec2 NaN = new vec2(double.NaN, double.NaN);
+ }
+}
\ No newline at end of file
diff --git a/src/JuicyGraphics/math/vec3.cs b/src/JuicyGraphics/math/vec3.cs
new file mode 100644
index 0000000..96b56c6
--- /dev/null
+++ b/src/JuicyGraphics/math/vec3.cs
@@ -0,0 +1,956 @@
+using System;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+namespace JuicyGraphics.Mathematics {
+ using Exceptions;
+
+ [ImmutableObject(true), Serializable]
+ public struct vec3
+ : IComparable, IComparable, IEquatable, IFormattable {
+
+ private readonly double _x;
+ private readonly double _y;
+ private readonly double _z;
+
+ public vec3(double x, double y, double z) {
+ _x = x;
+ _y = y;
+ _z = z;
+ }
+
+ public vec3(double[] xyz) {
+ if (xyz.Length == 3) {
+ _x = xyz[0];
+ _y = xyz[1];
+ _z = xyz[2];
+ }
+ else {
+ throw new ArgumentException(THREE_COMPONENTS);
+ }
+ }
+
+ public vec3(vec3 v1) {
+ _x = v1.x;
+ _y = v1.y;
+ _z = v1.z;
+ }
+
+ public double x {
+ get {
+ return _x;
+ }
+ }
+
+ public double y {
+ get {
+ return _y;
+ }
+ }
+
+ public double z {
+ get {
+ return _z;
+ }
+ }
+
+ public vec2 xx {
+ get {
+ return new vec2(_x, _x);
+ }
+ }
+
+ public vec2 xy {
+ get {
+ return new vec2(_x, _y);
+ }
+ }
+
+ public vec2 yx {
+ get {
+ return new vec2(_y, _x);
+ }
+ }
+
+ public vec2 yy {
+ get {
+ return new vec2(_y, _y);
+ }
+ }
+
+ public vec3 xxx {
+ get {
+ return new vec3(_x, _x, _x);
+ }
+ }
+
+ public vec3 xxy {
+ get {
+ return new vec3(_x, _x, _y);
+ }
+ }
+
+ public vec3 xxz {
+ get {
+ return new vec3(_x, _x, _z);
+ }
+ }
+
+ public vec3 xyx {
+ get {
+ return new vec3(_x, _y, _x);
+ }
+ }
+
+ public vec3 xyy {
+ get {
+ return new vec3(_x, _y, _y);
+ }
+ }
+
+ public vec3 xyz {
+ get {
+ return new vec3(_x, _y, _z);
+ }
+ }
+
+ public vec3 xzx {
+ get {
+ return new vec3(_x, _z, _x);
+ }
+ }
+
+ public vec3 xzy {
+ get {
+ return new vec3(_x, _z, _y);
+ }
+ }
+
+ public vec3 xzz {
+ get {
+ return new vec3(_x, _z, _z);
+ }
+ }
+
+ public vec3 yxx {
+ get {
+ return new vec3(_y, _x, _x);
+ }
+ }
+
+ public vec3 yxy {
+ get {
+ return new vec3(_y, _x, _y);
+ }
+ }
+
+ public vec3 yxz {
+ get {
+ return new vec3(_y, _x, _z);
+ }
+ }
+
+ public vec3 yyx {
+ get {
+ return new vec3(_y, _y, _x);
+ }
+ }
+
+ public vec3 yyy {
+ get {
+ return new vec3(_y, _y, _y);
+ }
+ }
+
+ public vec3 yyz {
+ get {
+ return new vec3(_y, _y, _z);
+ }
+ }
+
+ public vec3 yzx {
+ get {
+ return new vec3(_y, _z, _x);
+ }
+ }
+
+ public vec3 yzy {
+ get {
+ return new vec3(_y, _z, _y);
+ }
+ }
+
+ public vec3 yzz {
+ get {
+ return new vec3(_y, _z, _z);
+ }
+ }
+
+ public vec3 zxx {
+ get {
+ return new vec3(_z, _x, _x);
+ }
+ }
+
+ public vec3 zxy {
+ get {
+ return new vec3(_z, _x, _y);
+ }
+ }
+
+ public vec3 zxz {
+ get {
+ return new vec3(_z, _x, _z);
+ }
+ }
+
+ public vec3 zyx {
+ get {
+ return new vec3(_z, _y, _x);
+ }
+ }
+
+ public vec3 zyy {
+ get {
+ return new vec3(_z, _y, _y);
+ }
+ }
+
+ public vec3 zyz {
+ get {
+ return new vec3(_z, _y, _z);
+ }
+ }
+
+ public vec3 zzx {
+ get {
+ return new vec3(_z, _z, _x);
+ }
+ }
+
+ public vec3 zzy {
+ get {
+ return new vec3(_z, _z, _y);
+ }
+ }
+
+ public vec3 zzz {
+ get {
+ return new vec3(_z, _z, _z);
+ }
+ }
+
+ public vec3 normal {
+ get {
+ return normalize();
+ }
+ }
+
+ public double magnitude {
+ get {
+ return Math.Sqrt(sumComponentSqrs());
+ }
+ }
+
+ [XmlIgnore]
+ public double[] array {
+ get {
+ return new[] { _x, _y, _z };
+ }
+ }
+
+ public double this[int index] {
+ get {
+ switch (index) {
+ case 0:
+ return x;
+ case 1:
+ return y;
+ case 2:
+ return z;
+ default:
+ throw new ArgumentException(THREE_COMPONENTS, "index");
+ }
+ }
+ }
+
+ public static vec3 operator +(vec3 v1, vec3 v2) {
+ return new vec3(
+ v1.x + v2.x,
+ v1.y + v2.y,
+ v1.z + v2.z);
+ }
+
+ public static vec3 operator -(vec3 v1, vec3 v2) {
+ return new vec3(
+ v1.x - v2.x,
+ v1.y - v2.y,
+ v1.z - v2.z);
+ }
+
+ public static vec3 operator *(vec3 v1, double s2) {
+ return
+ new vec3(
+ v1.x * s2,
+ v1.y * s2,
+ v1.z * s2);
+ }
+
+ public static vec3 operator *(double s1, vec3 v2) {
+ return v2 * s1;
+ }
+
+ public static vec3 operator /(vec3 v1, double s2) {
+ return new vec3(
+ v1.x / s2,
+ v1.y / s2,
+ v1.z / s2);
+ }
+
+ public static vec3 operator -(vec3 v1) {
+ return new vec3(
+ -v1.x,
+ -v1.y,
+ -v1.z);
+ }
+
+ public static vec3 operator +(vec3 v1) {
+ return new vec3(
+ +v1.x,
+ +v1.y,
+ +v1.z);
+ }
+
+ public static bool operator <(vec3 v1, vec3 v2) {
+ return v1.sumComponentSqrs() < v2.sumComponentSqrs();
+ }
+
+ public static bool operator >(vec3 v1, vec3 v2) {
+ return v1.sumComponentSqrs() > v2.sumComponentSqrs();
+ }
+
+ public static bool operator <=(vec3 v1, vec3 v2) {
+ return v1.sumComponentSqrs() <= v2.sumComponentSqrs();
+ }
+
+ public static bool operator >=(vec3 v1, vec3 v2) {
+ return v1.sumComponentSqrs() >= v2.sumComponentSqrs();
+ }
+
+ public static bool operator ==(vec3 v1, vec3 v2) {
+ return
+ v1.x == v2.x &&
+ v1.y == v2.y &&
+ v1.z == v2.z;
+ }
+
+ public static bool operator !=(vec3 v1, vec3 v2) {
+ return !(v1 == v2);
+ }
+
+ public static vec3 scale(vec3 vector, double magnitude) {
+ if (magnitude < 0) {
+ throw new ArgumentOutOfRangeException("magnitude", magnitude, NEGATIVE_magnitude);
+ }
+
+ if (vector == new vec3(0, 0, 0)) {
+ throw new ArgumentException(ORIGIN_VECTOR_magnitude, "vector");
+ }
+
+ return vector * (magnitude / vector.magnitude);
+ }
+
+ public vec3 scale(double magnitude) {
+ return vec3.scale(this, magnitude);
+ }
+
+ public static vec3 crossProduct(vec3 v1, vec3 v2) {
+ return
+ new vec3(
+ v1.y * v2.z - v1.z * v2.y,
+ v1.z * v2.x - v1.x * v2.z,
+ v1.x * v2.y - v1.y * v2.x);
+ }
+
+ public vec3 crossProduct(vec3 other) {
+ return crossProduct(this, other);
+ }
+
+ public static double dotProduct(vec3 v1, vec3 v2) {
+ return
+ v1.x * v2.x +
+ v1.y * v2.y +
+ v1.z * v2.z;
+ }
+
+ public double dotProduct(vec3 other) {
+ return dotProduct(this, other);
+ }
+
+ public static double mixedProduct(vec3 v1, vec3 v2, vec3 v3) {
+ return dotProduct(crossProduct(v1, v2), v3);
+ }
+
+ public double mixedProduct(vec3 other_v1, vec3 other_v2) {
+ return dotProduct(crossProduct(this, other_v1), other_v2);
+ }
+
+ public static vec3 normalize(vec3 v1) {
+ if (double.IsInfinity(v1.magnitude)) {
+ v1 = normalizeSpecialCasesOrOrigional(v1);
+
+ if (v1.isNaN()) {
+ throw new normalizeVectorException(NORMALIZE_Inf);
+ }
+ }
+
+ if (v1.magnitude == 0) {
+ throw new normalizeVectorException(NORMALIZE_0);
+ }
+
+ if (v1.isNaN()) {
+ throw new normalizeVectorException(NORMALIZE_NaN);
+ }
+
+ return normalizeOrNaN(v1);
+ }
+
+ public static vec3 normalizeOrDefault(vec3 v1) {
+ v1 = normalizeSpecialCasesOrOrigional(v1);
+
+ if (v1.magnitude == 0) {
+ return origin;
+ }
+
+ if (v1.isNaN()) {
+ return NaN;
+ }
+
+ return normalizeOrNaN(v1);
+ }
+
+ public vec3 normalize() {
+ return normalize(this);
+ }
+
+ public vec3 normalizeOrDefault() {
+ return normalizeOrDefault(this);
+ }
+
+ private static vec3 normalizeOrNaN(vec3 v1) {
+ double inverse = 1 / v1.magnitude;
+
+ return new vec3(
+ v1.x * inverse,
+ v1.y * inverse,
+ v1.z * inverse);
+ }
+
+ private static vec3 normalizeSpecialCasesOrOrigional(vec3 v1) {
+ if (double.IsInfinity(v1.magnitude)) {
+ var x = v1.x == 0 ? 0 : v1.x == -0 ? -0 : double.IsPositiveInfinity(v1.x) ? 1 : double.IsNegativeInfinity(v1.x) ? -1 : double.NaN;
+ var y = v1.y == 0 ? 0 : v1.y == -0 ? -0 : double.IsPositiveInfinity(v1.y) ? 1 : double.IsNegativeInfinity(v1.y) ? -1 : double.NaN;
+ var z = v1.z == 0 ? 0 : v1.z == -0 ? -0 : double.IsPositiveInfinity(v1.z) ? 1 : double.IsNegativeInfinity(v1.z) ? -1 : double.NaN;
+
+ return new vec3(x, y, z);
+ }
+
+ return v1;
+ }
+
+ public static vec3 interpolate(vec3 v1, vec3 v2, double control, bool allowExtrapolation) {
+ if (!allowExtrapolation && (control > 1 || control < 0)) {
+ throw new ArgumentOutOfRangeException(
+ "control",
+ control,
+ INTERPOLATION_RANGE + "\n" + ARGUMENT_VALUE + control);
+ }
+
+ return new vec3(
+ v1.x * (1 - control) + v2.x * control,
+ v1.y * (1 - control) + v2.y * control,
+ v1.z * (1 - control) + v2.z * control);
+ }
+
+ public static vec3 interpolate(vec3 v1, vec3 v2, double control) {
+ return interpolate(v1, v2, control, false);
+ }
+
+ public vec3 interpolate(vec3 other, double control) {
+ return interpolate(this, other, control);
+ }
+
+ public vec3 interpolate(vec3 other, double control, bool allowExtrapolation) {
+ return interpolate(this, other, control);
+ }
+
+ public static double distance(vec3 v1, vec3 v2) {
+ return Math.Sqrt(
+ (v1.x - v2.x) * (v1.x - v2.x) +
+ (v1.y - v2.y) * (v1.y - v2.y) +
+ (v1.z - v2.z) * (v1.z - v2.z));
+ }
+
+ public double distance(vec3 other) {
+ return distance(this, other);
+ }
+
+ public static double angle(vec3 v1, vec3 v2) {
+ if (v1 == v2) {
+ return 0;
+ }
+
+ return
+ Math.Acos(
+ Math.Min(1.0f, normalizeOrDefault(v1).dotProduct(normalizeOrDefault(v2))));
+ }
+
+ public double angle(vec3 other) {
+ return angle(this, other);
+ }
+
+ public static vec3 max(vec3 v1, vec3 v2) {
+ return v1 >= v2 ? v1 : v2;
+ }
+
+ public vec3 max(vec3 other) {
+ return max(this, other);
+ }
+
+ public static vec3 min(vec3 v1, vec3 v2) {
+ return v1 <= v2 ? v1 : v2;
+ }
+
+ public vec3 min(vec3 other) {
+ return min(this, other);
+ }
+
+ public static vec3 yaw(vec3 v1, double rad) {
+ return rotateY(v1, rad);
+ }
+
+ public vec3 yaw(double rad) {
+ return yaw(this, rad);
+ }
+
+ public static vec3 pitch(vec3 v1, double rad) {
+ return rotateX(v1, rad);
+ }
+
+ public vec3 pitch(double rad) {
+ return pitch(this, rad);
+ }
+
+ public static vec3 roll(vec3 v1, double rad) {
+ return rotateZ(v1, rad);
+ }
+
+ public vec3 roll(double rad) {
+ return roll(this, rad);
+ }
+
+ public static vec3 rotateX(vec3 v1, double rad) {
+ double x = v1.x;
+ double y = (v1.y * Math.Cos(rad)) - (v1.z * Math.Sin(rad));
+ double z = (v1.y * Math.Sin(rad)) + (v1.z * Math.Cos(rad));
+ return new vec3(x, y, z);
+ }
+
+ public vec3 rotateX(double rad) {
+ return rotateX(this, rad);
+ }
+
+ public static vec3 rotateY(vec3 v1, double rad) {
+ double x = (v1.z * Math.Sin(rad)) + (v1.x * Math.Cos(rad));
+ double y = v1.y;
+ double z = (v1.z * Math.Cos(rad)) - (v1.x * Math.Sin(rad));
+ return new vec3(x, y, z);
+ }
+
+ public vec3 rotateY(double rad) {
+ return rotateY(this, rad);
+ }
+
+ public static vec3 rotateZ(vec3 v1, double rad) {
+ double x = (v1.x * Math.Cos(rad)) - (v1.y * Math.Sin(rad));
+ double y = (v1.x * Math.Sin(rad)) + (v1.y * Math.Cos(rad));
+ double z = v1.z;
+ return new vec3(x, y, z);
+ }
+
+ public vec3 rotateZ(double rad) {
+ return rotateZ(this, rad);
+ }
+
+ public static vec3 rotateX(vec3 v1, double yOff, double zOff, double rad) {
+ double x = v1.x;
+ double y = (v1.y * Math.Cos(rad)) - (v1.z * Math.Sin(rad)) + (yOff * (1 - Math.Cos(rad)) + zOff * Math.Sin(rad));
+ double z = (v1.y * Math.Sin(rad)) + (v1.z * Math.Cos(rad)) + (zOff * (1 - Math.Cos(rad)) - yOff * Math.Sin(rad));
+ return new vec3(x, y, z);
+ }
+
+ public vec3 rotateX(double yOff, double zOff, double rad) {
+ return rotateX(this, yOff, zOff, rad);
+ }
+
+ public static vec3 rotateY(vec3 v1, double xOff, double zOff, double rad) {
+ double x = (v1.z * Math.Sin(rad)) + (v1.x * Math.Cos(rad)) + (xOff * (1 - Math.Cos(rad)) - zOff * Math.Sin(rad));
+ double y = v1.y;
+ double z = (v1.z * Math.Cos(rad)) - (v1.x * Math.Sin(rad)) + (zOff * (1 - Math.Cos(rad)) + xOff * Math.Sin(rad));
+ return new vec3(x, y, z);
+ }
+
+ public vec3 rotateY(double xOff, double zOff, double rad) {
+ return rotateY(this, xOff, zOff, rad);
+ }
+
+ public static vec3 rotateZ(vec3 v1, double xOff, double yOff, double rad) {
+ double x = (v1.x * Math.Cos(rad)) - (v1.y * Math.Sin(rad)) + (xOff * (1 - Math.Cos(rad)) + yOff * Math.Sin(rad));
+ double y = (v1.x * Math.Sin(rad)) + (v1.y * Math.Cos(rad)) + (yOff * (1 - Math.Cos(rad)) - xOff * Math.Sin(rad));
+ double z = v1.z;
+ return new vec3(x, y, z);
+ }
+
+ public vec3 rotateZ(double xOff, double yOff, double rad) {
+ return rotateZ(this, xOff, yOff, rad);
+ }
+
+ public static vec3 projection(vec3 v1, vec3 v2) {
+ return new vec3(v2 * (v1.dotProduct(v2) / Math.Pow(v2.magnitude, 2)));
+ }
+
+ public vec3 projection(vec3 direction) {
+ return projection(this, direction);
+ }
+
+ public static vec3 rejection(vec3 v1, vec3 v2) {
+ return v1 - v1.projection(v2);
+ }
+
+ public vec3 rejection(vec3 direction) {
+ return rejection(this, direction);
+ }
+
+ public vec3 reflection(vec3 reflector) {
+ this = vec3.reflection(this, reflector);
+ return this;
+ }
+
+ public static vec3 reflection(vec3 v1, vec3 v2) {
+ if (Math.Abs(Math.Abs(v1.angle(v2)) - Math.PI / 2) < Double.Epsilon) {
+ return -v1;
+ }
+
+ vec3 retval = new vec3(2 * v1.projection(v2) - v1);
+ return retval.scale(v1.magnitude);
+ }
+
+ public static Double abs(vec3 v1) {
+ return v1.magnitude;
+ }
+
+ public double abs() {
+ return magnitude;
+ }
+
+ public static double sumComponents(vec3 v1) {
+ return v1.x + v1.y + v1.z;
+ }
+
+ public double sumComponents() {
+ return sumComponents(this);
+ }
+
+ public static double sumComponentSqrs(vec3 v1) {
+ vec3 v2 = sqrComponents(v1);
+ return v2.sumComponents();
+ }
+
+ public double sumComponentSqrs() {
+ return sumComponentSqrs(this);
+ }
+
+ public static vec3 powComponents(vec3 v1, double power) {
+ return new vec3(
+ Math.Pow(v1.x, power),
+ Math.Pow(v1.y, power),
+ Math.Pow(v1.z, power));
+ }
+
+ public vec3 powComponents(double power) {
+ return powComponents(this, power);
+ }
+
+ public static vec3 sqrtComponents(vec3 v1) {
+ return new vec3(
+ Math.Sqrt(v1.x),
+ Math.Sqrt(v1.y),
+ Math.Sqrt(v1.z));
+ }
+
+ public vec3 sqrtComponents() {
+ return sqrtComponents(this);
+ }
+
+ public static vec3 sqrComponents(vec3 v1) {
+ return new vec3(
+ v1.x * v1.x,
+ v1.y * v1.y,
+ v1.z * v1.z);
+ }
+
+ public vec3 sqrComponents() {
+ return sqrComponents(this);
+ }
+
+ public static vec3 round(vec3 v1) {
+ return new vec3(Math.Round(v1.x), Math.Round(v1.y), Math.Round(v1.z));
+ }
+
+ public static vec3 round(vec3 v1, int digits) {
+ return new vec3(Math.Round(v1.x, digits), Math.Round(v1.y, digits), Math.Round(v1.z, digits));
+ }
+
+ public static vec3 round(vec3 v1, MidpointRounding mode) {
+ return new vec3(Math.Round(v1.x, mode), Math.Round(v1.y, mode), Math.Round(v1.z, mode));
+ }
+
+ public static vec3 round(vec3 v1, int digits, MidpointRounding mode) {
+ return new vec3(Math.Round(v1.x, digits, mode), Math.Round(v1.y, digits, mode), Math.Round(v1.z, digits, mode));
+ }
+
+ public vec3 round() {
+ return new vec3(Math.Round(x), Math.Round(y), Math.Round(z));
+ }
+
+ public vec3 round(int digits) {
+ return new vec3(Math.Round(x, digits), Math.Round(y, digits), Math.Round(z, digits));
+ }
+
+ public vec3 round(MidpointRounding mode) {
+ return new vec3(Math.Round(x, mode), Math.Round(y, mode), Math.Round(z, mode));
+ }
+
+ public vec3 round(int digits, MidpointRounding mode) {
+ return new vec3(Math.Round(x, digits, mode), Math.Round(y, digits, mode), Math.Round(z, digits, mode));
+ }
+
+ public override string ToString() {
+ return ToString(null, null);
+ }
+
+ public string ToVerbString() {
+ string output = null;
+
+ if (isUnitVector()) {
+ output += UNIT_VECTOR;
+ }
+ else {
+ output += POSITIONAL_VECTOR;
+ }
+
+ output += string.Format("( x={0}, y={1}, z={2} )", x, y, z);
+ output += magnitude + magnitude;
+
+ return output;
+ }
+
+ public string ToString(string format, IFormatProvider formatProvider) {
+ if (format == null || format == "") {
+ return string.Format("({0}, {1}, {2})", x, y, z);
+ }
+
+ char firstChar = format[0];
+ string remainder = null;
+
+ if (format.Length > 1) {
+ remainder = format.Substring(1);
+ }
+
+ switch (firstChar) {
+ case 'x': return x.ToString(remainder, formatProvider);
+ case 'y': return y.ToString(remainder, formatProvider);
+ case 'z': return z.ToString(remainder, formatProvider);
+ default:
+ return String.Format(
+ "({0}, {1}, {2})",
+ x.ToString(format, formatProvider),
+ y.ToString(format, formatProvider),
+ z.ToString(format, formatProvider));
+ }
+ }
+
+ public override int GetHashCode() {
+ unchecked {
+ var hashCode = _x.GetHashCode();
+ hashCode = (hashCode * 397) ^ _y.GetHashCode();
+ hashCode = (hashCode * 397) ^ _z.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ public override bool Equals(object other) {
+ if (other is vec3) {
+ return other.Equals(this);
+ }
+ else {
+ return false;
+ }
+ }
+
+ public bool Equals(object other, double tolerance) {
+ if (other is vec3) {
+ return Equals((vec3)other, tolerance);
+ }
+ return false;
+ }
+
+ public bool Equals(vec3 other) {
+ return
+ x.Equals(other.x) &&
+ y.Equals(other.y) &&
+ z.Equals(other.z);
+ }
+
+ public bool Equals(vec3 other, double tolerance) {
+ return
+ x.almostEqualsWithAbsTolerance(other.x, tolerance) &&
+ y.almostEqualsWithAbsTolerance(other.y, tolerance) &&
+ z.almostEqualsWithAbsTolerance(other.z, tolerance);
+ }
+
+ public int CompareTo(vec3 other) {
+ if (this < other) {
+ return -1;
+ }
+
+ if (this > other) {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ public int CompareTo(object other) {
+ if (other is vec3) {
+ return CompareTo((vec3)other);
+ }
+
+ throw new ArgumentException(
+ NON_VECTOR_COMPARISON + "\n" + ARGUMENT_TYPE + other.GetType().ToString(),
+ "other");
+ }
+
+ public int CompareTo(vec3 other, double tolerance) {
+ var bothInfinite = double.IsInfinity(sumComponentSqrs()) && double.IsInfinity(other.sumComponentSqrs());
+
+ if (Equals(other, tolerance) || bothInfinite) {
+ return 0;
+ }
+
+ if (this < other) {
+ return -1;
+ }
+
+ return 1;
+ }
+
+ public int CompareTo(object other, double tolerance) {
+ if (other is vec3) {
+ return CompareTo((vec3)other, tolerance);
+ }
+
+ throw new ArgumentException(
+ NON_VECTOR_COMPARISON + "\n" + ARGUMENT_TYPE + other.GetType().ToString(),
+ "other");
+ }
+ public static bool isUnitVector(vec3 v1, double tolerance) {
+ return v1.magnitude.almostEqualsWithAbsTolerance(1, tolerance);
+ }
+
+ public static bool isUnitVector(vec3 v1) {
+ return v1.magnitude == 1;
+ }
+
+ public bool isUnitVector() {
+ return isUnitVector(this);
+ }
+
+ public bool isUnitVector(double tolerance) {
+ return isUnitVector(this, tolerance);
+ }
+
+ public static bool isBackFace(vec3 normal, vec3 lineOfSight) {
+ return normal.dotProduct(lineOfSight) < 0;
+ }
+
+ public bool isBackFace(vec3 lineOfSight) {
+ return isBackFace(this, lineOfSight);
+ }
+
+ public static bool isPerpendicular(vec3 v1, vec3 v2, double tolerance) {
+ v1 = normalizeSpecialCasesOrOrigional(v1);
+ v2 = normalizeSpecialCasesOrOrigional(v2);
+
+ if (v1 == zero || v2 == zero) {
+ return false;
+ }
+
+ return v1.dotProduct(v2).almostEqualsWithAbsTolerance(0, tolerance);
+ }
+
+ public static bool isPerpendicular(vec3 v1, vec3 v2) {
+ v1 = normalizeSpecialCasesOrOrigional(v1);
+ v2 = normalizeSpecialCasesOrOrigional(v2);
+
+ if (v1 == zero || v2 == zero) {
+ return false;
+ }
+
+ return v1.dotProduct(v2).Equals(0);
+ }
+
+ public bool isPerpendicular(vec3 other) {
+ return isPerpendicular(this, other);
+ }
+
+ public bool isPerpendicular(vec3 other, double tolerance) {
+ return isPerpendicular(this, other, tolerance);
+ }
+
+ public static bool isNaN(vec3 v1) {
+ return double.IsNaN(v1.x) || double.IsNaN(v1.y) || double.IsNaN(v1.z);
+ }
+
+ public bool isNaN() {
+ return isNaN(this);
+ }
+
+ public static readonly vec3 origin = new vec3(0, 0, 0);
+ public static readonly vec3 xAxis = new vec3(1, 0, 0);
+ public static readonly vec3 yAxis = new vec3(0, 1, 0);
+ public static readonly vec3 zAxis = new vec3(0, 0, 1);
+
+ private const string NORMALIZE_NaN = "Cannot normalize a vector when it's magnitude is NaN";
+ private const string NORMALIZE_0 = "Cannot normalize a vector when it's magnitude is zero";
+ private const string NORMALIZE_Inf = "Cannot normalize a vector when it's magnitude is infinite except under special conditions";
+ private const string THREE_COMPONENTS = "Array must contain exactly three components , (x,y,z)";
+ private const string INTERPOLATION_RANGE = "Control parameter must be a value between 0 & 1";
+ private const string NON_VECTOR_COMPARISON = "Cannot compare a vec3 to a non-vec3";
+ private const string ARGUMENT_TYPE = "The argument provided is a type of ";
+ private const string ARGUMENT_VALUE = "The argument provided has a value of ";
+ private const string ARGUMENT_LENGTH = "The argument provided has a length of ";
+ private const string NEGATIVE_magnitude = "The magnitude of a vec3 must be a positive value, (i.e. greater than 0)";
+ private const string ORIGIN_VECTOR_magnitude = "Cannot change the magnitude of vec3(0,0,0)";
+
+ private const string UNIT_VECTOR = "Unit vector composing of ";
+ private const string POSITIONAL_VECTOR = "Positional vector composing of ";
+ private const string MAGNITUDE = " of magnitude ";
+
+ public static readonly vec3 minValue = new vec3(Double.MinValue, Double.MinValue, Double.MinValue);
+ public static readonly vec3 maxValue = new vec3(Double.MaxValue, Double.MaxValue, Double.MaxValue);
+ public static readonly vec3 epsilon = new vec3(Double.Epsilon, Double.Epsilon, Double.Epsilon);
+ public static readonly vec3 zero = origin;
+ public static readonly vec3 NaN = new vec3(double.NaN, double.NaN, double.NaN);
+ }
+}
\ No newline at end of file
diff --git a/src/JuicyGraphics/renderer/graphicalObjects/gridBackground.cs b/src/JuicyGraphics/renderer/graphicalObjects/gridBackground.cs
index c4237e4..a7c7501 100644
--- a/src/JuicyGraphics/renderer/graphicalObjects/gridBackground.cs
+++ b/src/JuicyGraphics/renderer/graphicalObjects/gridBackground.cs
@@ -1,17 +1,11 @@
-using System.Numerics;
-using System.Windows.Forms;
-using SharpGL.Shaders;
+using SharpGL.Shaders;
using SharpGL;
-using SharpGL.Enumerations;
-using System.Reflection;
-using System.IO;
using System.Collections.Generic;
-using System;
using SharpGL.VertexBuffers;
namespace Graphics.Objects {
class gridBackground : iGraphicalObject {
-
+
VertexBuffer vbo = new VertexBuffer();
VertexBufferArray vao = new VertexBufferArray();
ShaderProgram gridRender = new ShaderProgram();
diff --git a/src/JuicyGraphics/renderer/stain.cs b/src/JuicyGraphics/renderer/stain.cs
new file mode 100644
index 0000000..d7e7e36
--- /dev/null
+++ b/src/JuicyGraphics/renderer/stain.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JuicyGraphics.mathematics;
+
+namespace Graphics {
+ class stain {
+ class edgeElement {
+ public edgeElement() {
+
+ }
+ }
+ }
+}
diff --git a/src/JuicyGraphics/renderer/stainGraphicTexture.cs b/src/JuicyGraphics/renderer/stainGraphicTexture.cs
new file mode 100644
index 0000000..2dd2c47
--- /dev/null
+++ b/src/JuicyGraphics/renderer/stainGraphicTexture.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JuicyGraphics.JuicyGraphics.renderer {
+ class stainGraphicTexture {
+ }
+}
diff --git a/src/SharpGL/OpenGL.cs b/src/SharpGL/OpenGL.cs
index 53503f4..d255245 100644
--- a/src/SharpGL/OpenGL.cs
+++ b/src/SharpGL/OpenGL.cs
@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
-using System.ComponentModel;
using System.Runtime.InteropServices;
using SharpGL.RenderContextProviders;
using SharpGL.Version;