2019-02-25 21:00:59 +01:00
using System ;
using System.ComponentModel ;
using System.Xml.Serialization ;
namespace JuicyGraphics.Mathematics {
using Exceptions ;
[ImmutableObject(true), Serializable]
public struct vec3
: IComparable , IComparable < vec3 > , IEquatable < vec3 > , 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 ) ;
}
}
2019-02-25 22:49:19 +01:00
public vec3 ( vec2 v1 , double z ) {
_x = v1 . x ;
_y = v1 . y ;
_z = z ;
}
public vec3 ( double x , vec2 v1 ) {
_x = x ;
_y = v1 . x ;
_z = v1 . y ;
}
2019-02-25 21:00:59 +01:00
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" ;
2019-02-25 22:49:19 +01:00
private const string THREE_COMPONENTS = "Array must contain exactly three components , (x, y, z)" ;
2019-02-25 21:00:59 +01:00
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)" ;
2019-02-25 22:49:19 +01:00
private const string ORIGIN_VECTOR_magnitude = "Cannot change the magnitude of vec3(0, 0, 0)" ;
2019-02-25 21:00:59 +01:00
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 ) ;
}
}