|
|
|
@ -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<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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|