From 8bec0d6b805669510f03133a87230d269882f0a4 Mon Sep 17 00:00:00 2001 From: allem Date: Tue, 3 Apr 2018 23:40:06 -0400 Subject: [PATCH] inner and outer products --- Tetrahedrons/MVec3d.cs | 12 +- Tetrahedrons/MVec4D.cs | 177 +++++++++++++++++++++++++++--- Tetrahedrons/TetrahedronWindow.cs | 4 +- 3 files changed, 166 insertions(+), 27 deletions(-) diff --git a/Tetrahedrons/MVec3d.cs b/Tetrahedrons/MVec3d.cs index 4ce9eb8..e4c2cf9 100644 --- a/Tetrahedrons/MVec3d.cs +++ b/Tetrahedrons/MVec3d.cs @@ -68,17 +68,7 @@ namespace Tetrahedrons return new MVec3D(0, 0, 0, 0, 0, 0, 0, e123); } - public static MVec3D Complex(double real, double imag) - { - return new MVec3D(real, 0, 0, 0, 0, 0, 0, imag); - } - - public static MVec3D Complex(double w, double i, double j, double k) - { - return new MVec3D(w, 0, 0, 0, i, j, k, 0); - } - - public static MVec3D Complex(double angle, MVec3D plane) + public static MVec3D Rotor(double angle, MVec3D plane) { return Math.Cos(angle) + Math.Sin(angle) * plane; } diff --git a/Tetrahedrons/MVec4D.cs b/Tetrahedrons/MVec4D.cs index 62216a0..ddc59be 100644 --- a/Tetrahedrons/MVec4D.cs +++ b/Tetrahedrons/MVec4D.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.Data.SqlClient; +using System.Dynamic; using System.Runtime.Remoting.Messaging; using System.Text; using OpenTK; +using OpenTK.Graphics.ES30; namespace Tetrahedrons { @@ -38,7 +41,26 @@ namespace Tetrahedrons Xyw * Xyw + Xzw * Xzw + Yzw * Yzw + Xyzw * Xyzw; public double Norm => Math.Sqrt(Norm2); - + + public MVec4D Grade(int k) + { + switch (k) + { + case 0: + return Vec0(S); + case 1: + return Vec1(X, Y, Z, W); + case 2: + return Vec2(Xy, Xz, Xw, Yz, Yw, Zw); + case 3: + return Vec3(Xyz, Xyw, Xzw, Yzw); + case 4: + return Vec4(Xyzw); + default: + return Zero; + } + } + #region Swizzle public double Yx @@ -904,25 +926,152 @@ namespace Tetrahedrons ); } - public static MVec4D? Div(MVec4D m, MVec4D n) - { - var inv = n.Inv; - if (!inv.HasValue) - return null; - - return Mul(m, inv.Value); - } + public static MVec4D? Div(MVec4D m, MVec4D n) => Mul(m, n.Inv); public static MVec4D Div(MVec4D m, double c) => Mul(m, 1 / c); - public static MVec4D? Div(double c, MVec4D m) + public static MVec4D? Div(double c, MVec4D n) => Mul(c, n.Inv); + + public static MVec4D Inner(MVec4D m, MVec4D n) { - var inv = m.Inv; - if (!inv.HasValue) - return null; - return Mul(c, inv.Value); + var m0 = m.Grade(0); + var m1 = m.Grade(1); + var m2 = m.Grade(2); + var m3 = m.Grade(3); + var m4 = m.Grade(4); + + var n0 = n.Grade(0); + var n1 = n.Grade(1); + var n2 = n.Grade(2); + var n3 = n.Grade(3); + var n4 = n.Grade(4); + + return new MVec4D( + m0 * n0 + m1 * n1 + m2 * n2 + m3 * n3 + n4 * n4, + m0 * n1 + m1 * n2 + m2 * n3 + m3 * n4, + m0 * n2 + m1 * n3 + m2 * n4, + m0 * n3 + m1 * n4, + m0 * n4 + ); } + public static MVec4D Inner(MVec4D m, double c) => Mul(m, c); + + public static MVec4D Inner(double c, MVec4D n) => Mul(c, n); + + public static MVec4D Outer(MVec4D m, MVec4D n) + { + var m0 = m.Grade(0); + var m1 = m.Grade(1); + var m2 = m.Grade(2); + var m3 = m.Grade(3); + var m4 = m.Grade(4); + + var n0 = n.Grade(0); + var n1 = n.Grade(1); + var n2 = n.Grade(2); + var n3 = n.Grade(3); + var n4 = n.Grade(4); + + return new MVec4D( + m0 * n0, + m1 * n0 + m0 * n1, + m2 * n0 + m1 * n1 + m0 * n2, + m3 * n0 + m2 * n1 + m1 * n2 + m0 * n3, + m4 * n0 + m3 * n1 + m2 * n2 + m1 * n3 + m0 * n4 + ); + } + + public static MVec4D Outer(MVec4D m, double c) => Mul(m, c); + + public static MVec4D Outer(double c, MVec4D n) => Mul(c, n); + + + public static MVec4D? Add(MVec4D? m, MVec4D? n) => m.HasValue && n.HasValue ? (MVec4D?) Add(m.Value, n.Value) : null; + public static MVec4D? Add(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Add(m.Value, n.Value) : null; + public static MVec4D? Add(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Add(m.Value, n.Value) : null; + + public static MVec4D? Sub(MVec4D? m, MVec4D? n) => m.HasValue && n.HasValue ? (MVec4D?) Sub(m.Value, n.Value) : null; + public static MVec4D? Sub(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Sub(m.Value, n.Value) : null; + public static MVec4D? Sub(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Sub(m.Value, n.Value) : null; + + public static MVec4D? Mul(MVec4D? m, MVec4D? n) => m.HasValue && n.HasValue ? (MVec4D?) Mul(m.Value, n.Value) : null; + public static MVec4D? Mul(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Mul(m.Value, n.Value) : null; + public static MVec4D? Mul(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Mul(m.Value, n.Value) : null; + + public static MVec4D? Div(MVec4D? m, MVec4D? n) => m.HasValue && n.HasValue ? (MVec4D?) Div(m.Value, n.Value) : null; + public static MVec4D? Div(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Div(m.Value, n.Value) : null; + public static MVec4D? Div(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Div(m.Value, n.Value) : null; + + public static MVec4D? Inner(MVec4D? m, MVec4D? n) => m.HasValue && n.HasValue ? (MVec4D?) Inner(m.Value, n.Value) : null; + public static MVec4D? Inner(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Inner(m.Value, n.Value) : null; + public static MVec4D? Inner(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Inner(m.Value, n.Value) : null; + + public static MVec4D? Outer(MVec4D? m, MVec4D? n) => m.HasValue && n.HasValue ? (MVec4D?) Outer(m.Value, n.Value) : null; + public static MVec4D? Outer(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Outer(m.Value, n.Value) : null; + public static MVec4D? Outer(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Outer(m.Value, n.Value) : null; + + #endregion + + #region Operators + + public static MVec4D operator +(MVec4D m, MVec4D n) => Add(m, n); + public static MVec4D operator +(double c, MVec4D n) => Add(c, n); + public static MVec4D operator +(MVec4D m, double c) => Add(m, c); + + public static MVec4D operator -(MVec4D m, MVec4D n) => Sub(m, n); + public static MVec4D operator -(double c, MVec4D n) => Sub(c, n); + public static MVec4D operator -(MVec4D m, double c) => Sub(m, c); + + public static MVec4D operator *(MVec4D m, MVec4D n) => Mul(m, n); + public static MVec4D operator *(double c, MVec4D n) => Mul(c, n); + public static MVec4D operator *(MVec4D m, double c) => Mul(m, c); + + public static MVec4D? operator /(MVec4D m, MVec4D n) => Div(m, n); + public static MVec4D? operator /(double c, MVec4D n) => Div(c, n); + public static MVec4D operator /(MVec4D m, double c) => Div(m, c); + + public static MVec4D operator &(MVec4D m, MVec4D n) => Inner(m, n); + public static MVec4D operator &(MVec4D m, double c) => Inner(m, c); + public static MVec4D operator &(double c, MVec4D n) => Inner(c, n); + + public static MVec4D operator ^(MVec4D m, MVec4D n) => Outer(m, n); + public static MVec4D operator ^(MVec4D m, double c) => Outer(m, c); + public static MVec4D operator ^(double c, MVec4D n) => Outer(c, n); + + public static MVec4D? operator +(MVec4D? m, MVec4D? n) => Add(m, n); + public static MVec4D? operator +(double? c, MVec4D? n) => Add(c, n); + public static MVec4D? operator +(MVec4D? m, double? c) => Add(m, c); + + public static MVec4D? operator -(MVec4D? m, MVec4D? n) => Sub(m, n); + public static MVec4D? operator -(double? c, MVec4D? n) => Sub(c, n); + public static MVec4D? operator -(MVec4D? m, double? c) => Sub(m, c); + + public static MVec4D? operator *(MVec4D? m, MVec4D? n) => Mul(m, n); + public static MVec4D? operator *(double? c, MVec4D? n) => Mul(c, n); + public static MVec4D? operator *(MVec4D? m, double? c) => Mul(m, c); + + public static MVec4D? operator /(MVec4D? m, MVec4D? n) => Div(m, n); + public static MVec4D? operator /(double? c, MVec4D? n) => Div(c, n); + public static MVec4D? operator /(MVec4D? m, double? c) => Div(m, c); + + public static MVec4D? operator &(MVec4D? m, MVec4D? n) => Inner(m, n); + public static MVec4D? operator &(MVec4D? m, double? c) => Inner(m, c); + public static MVec4D? operator &(double? c, MVec4D? n) => Inner(c, n); + + public static MVec4D? operator ^(MVec4D? m, MVec4D? n) => Outer(m, n); + public static MVec4D? operator ^(MVec4D? m, double? c) => Outer(m, c); + public static MVec4D? operator ^(double? c, MVec4D? n) => Outer(c, n); + + + public static MVec4D operator -(MVec4D m) => m.Neg; + public static MVec4D? operator ~(MVec4D m) => m.Inv; + public static MVec4D operator !(MVec4D m) => m.Rev; + + public static implicit operator MVec4D(double v) => Vec0(v); + public static implicit operator MVec4D(Vector3d v) => Vec1(v.X, v.Y, v.Z, 0); + public static implicit operator MVec4D(Vector4d v) => Vec1(v.X, v.Y, v.Z, v.W); + #endregion #region Equality diff --git a/Tetrahedrons/TetrahedronWindow.cs b/Tetrahedrons/TetrahedronWindow.cs index d7061ed..07bec16 100644 --- a/Tetrahedrons/TetrahedronWindow.cs +++ b/Tetrahedrons/TetrahedronWindow.cs @@ -255,14 +255,14 @@ namespace Tetrahedrons if (Keyboard[Key.Left]) { - var rot = MVec3D.Complex(-e.Time, MVec3D.Unit12); + var rot = MVec3D.Rotor(-e.Time, MVec3D.Unit12); _b1 = rot * _b1 * ~rot; // todo make blade classes _b2 = rot * _b2 * ~rot; } if (Keyboard[Key.Right]) { - var rot = MVec3D.Complex(e.Time, MVec3D.Unit12); + var rot = MVec3D.Rotor(e.Time, MVec3D.Unit12); _b1 = rot * _b1 * ~rot; _b2 = rot * _b2 * ~rot; }