public static Blade InnerProduct(Basis e1, Basis e2) { int hashPair = Basis.GetHashPair(e1, e2); if (innerProductCache.ContainsKey(hashPair)) { return(innerProductCache[hashPair]); } Blade result; if (e1.IsNullMetric || e2.IsNullMetric) { MultiVector m1 = e1.ToMinkowskiMetric(); MultiVector m2 = e2.ToMinkowskiMetric(); result = (Blade)MultiVector.InnerProduct(m1, m2).ToNullMetric(); } else { if ((e1.bitMask & ~e2.bitMask) == 0) { result = (Blade)(e1 * e2); } else { result = Blade.Zero; } } innerProductCache.Add(hashPair, result); return(result); }
public static void GetCircleParams(MultiVector obj, out MultiVector n, out MultiVector c, out double r) { if (!obj.ContainsOnly(2)) throw new InvalidEntityException(); // c cross n MultiVector ccd = MultiVector.Vector( -obj[Basis.E23], obj[Basis.E13], -obj[Basis.E12]); // c dot n double d = obj[Basis.EPLANE]; n = MultiVector.Vector( obj[Basis.E1 ^ Basis.E0], obj[Basis.E2 ^ Basis.E0], obj[Basis.E3 ^ Basis.E0]); c = MultiVector.CrossProduct(n, ccd) + n * d; c /= (double)MultiVector.ScalarProduct(n, n); double x; if (n.E1 != 0) x = (obj[Basis.E1 ^ Basis.E8] + (double)d * c.E1) / n.E1; else if (n.E2 != 0) x = (obj[Basis.E2 ^ Basis.E8] + (double)d * c.E2) / n.E2; else if (n.E3 != 0) x = (obj[Basis.E3 ^ Basis.E8] + (double)d * c.E3) / n.E3; else throw new InvalidEntityException(); r = Math.Sqrt((double)MultiVector.ScalarProduct(c, c) - 2 * x); n /= n.Length; }
public static MultiVector CreatePoint(MultiVector v) { if (IPNS.GetGeometricEntity(v) != GeometricEntity.Vector) throw new InvalidEntityException(); return v + 0.5 * MultiVector.ScalarProduct(v, v) * Basis.E8 + Basis.E0; }
public static void GetLineParams(MultiVector obj, out MultiVector t, out MultiVector d) { if (!obj.ContainsOnly(2)) { throw new InvalidEntityException(); } d = MultiVector.Vector( -obj[Basis.E23], obj[Basis.E13], -obj[Basis.E12]); double norm = d.Length; if (norm == 0.0) { throw new InvalidEntityException(); } d /= norm; // d cross t MultiVector dct = MultiVector.Vector( obj[Basis.E1 ^ Basis.E8], obj[Basis.E2 ^ Basis.E8], obj[Basis.E3 ^ Basis.E8]) / norm; t = MultiVector.CrossProduct(dct, d); }
public static MultiVector operator -(Blade b1, Blade b2) { MultiVector ret = new MultiVector(); ret[b1.Basis] = b1.Value; ret[b2.Basis] -= b2.Value; return(ret); }
public static MultiVector operator -(Basis e1, Basis e2) { MultiVector ret = new MultiVector(); ret[e1] = 1.0; ret[e2] -= 1.0; return(ret); }
public static MultiVector CreatePoint(MultiVector v) { if (IPNS.GetGeometricEntity(v) != GeometricEntity.Vector) { throw new InvalidEntityException(); } return(v + 0.5 * MultiVector.ScalarProduct(v, v) * Basis.E8 + Basis.E0); }
public static MultiVector Vector(double e1, double e2, double e3) { MultiVector v = new MultiVector(); v.E1 = e1; v.E2 = e2; v.E3 = e3; return(v); }
public MultiVector ToNullMetric() { MultiVector result = new MultiVector(); foreach (Blade blade in this.Blades) { result += blade.ToNullMetric(); } return(result); }
public MultiVector Clone() { MultiVector result = new MultiVector(); foreach (Blade blade in this.Blades) { result[blade.Basis] = blade.Value; } return(result); }
public static MultiVector operator -(MultiVector v1, MultiVector v2) { MultiVector result = v1.Clone(); foreach (Blade blade in v2.Blades) { result[blade.Basis] -= blade.Value; } return(result); }
public static MultiVector operator -(MultiVector v) { MultiVector result = new MultiVector(); foreach (Blade blade in v.Blades) { result[blade.Basis] = -blade.Value; } return(result); }
public static MultiVector operator *(double f, MultiVector v) { MultiVector result = new MultiVector(); foreach (Blade b in v.Blades) { result[b.Basis] = f * b.Value; } return(result); }
public static double ScalarProduct(MultiVector v1, MultiVector v2) { double result = 0; foreach (Blade b in v1.Blades) { result += b.Value * v2[b.Basis]; } return(result); }
public static void GetPointParams(MultiVector obj, out MultiVector x) { MultiVector temp; double r; IPNS.GetSphereParams(obj, out temp, out r); if (r != 0.0) { throw new InvalidEntityException(); } x = temp; }
public static void GetPlaneParams(MultiVector obj, out MultiVector n, out double d) { if (!obj.ContainsOnly(1) || obj.E0 != 0.0) { throw new InvalidEntityException(); } n = MultiVector.Vector(obj.E1, obj.E2, obj.E3); double norm = n.Length; n /= norm; d = obj.E8 / norm; }
public static MultiVector InnerProduct(MultiVector v1, MultiVector v2) { MultiVector result = new MultiVector(); foreach (Blade b1 in v1.Blades) { foreach (Blade b2 in v2.Blades) { result += Blade.InnerProduct(b1, b2); } } return(result); }
public static void GetCircleParams(MultiVector obj, out MultiVector n, out MultiVector c, out double r) { if (!obj.ContainsOnly(2)) { throw new InvalidEntityException(); } // c cross n MultiVector ccd = MultiVector.Vector( -obj[Basis.E23], obj[Basis.E13], -obj[Basis.E12]); // c dot n double d = obj[Basis.EPLANE]; n = MultiVector.Vector( obj[Basis.E1 ^ Basis.E0], obj[Basis.E2 ^ Basis.E0], obj[Basis.E3 ^ Basis.E0]); c = MultiVector.CrossProduct(n, ccd) + n * d; c /= (double)MultiVector.ScalarProduct(n, n); double x; if (n.E1 != 0) { x = (obj[Basis.E1 ^ Basis.E8] + (double)d * c.E1) / n.E1; } else if (n.E2 != 0) { x = (obj[Basis.E2 ^ Basis.E8] + (double)d * c.E2) / n.E2; } else if (n.E3 != 0) { x = (obj[Basis.E3 ^ Basis.E8] + (double)d * c.E3) / n.E3; } else { throw new InvalidEntityException(); } r = Math.Sqrt((double)MultiVector.ScalarProduct(c, c) - 2 * x); n /= n.Length; }
public static void GetSphereParams(MultiVector obj, out MultiVector c, out double r) { if (!obj.ContainsOnly(1) || obj.E0 == 0.0) { throw new InvalidEntityException(); } obj /= obj.E0; c = MultiVector.Vector(obj.E1, obj.E2, obj.E3); r = Math.Sqrt(Math.Abs(2 * obj.E8 - (double)MultiVector.ScalarProduct(c, c))); // HACK if (Math.Abs(r) < 1E-3) { r = 0.0; } }
public static MultiVector GeometricProduct(Basis e1, Basis e2) { int hashPair = Basis.GetHashPair(e1, e2); if (geometricProductCache.ContainsKey(hashPair)) { return(geometricProductCache[hashPair]); } MultiVector result; if (e1.IsNullMetric || e2.IsNullMetric) { MultiVector m1 = e1.ToMinkowskiMetric(); MultiVector m2 = e2.ToMinkowskiMetric(); result = (m1 * m2).ToNullMetric(); } else { int rBitMask = e1.bitMask ^ e2.bitMask; double rValue = Basis.Order(e1, e2); int common = e1.bitMask & e2.bitMask; int i = 0; while (common != 0) { if ((common & 0x1) != 0) { rValue *= Basis.minkowskiSignature[i]; } common >>= 1; i++; } result = new Blade(new Basis(rBitMask, false), rValue); } geometricProductCache.Add(hashPair, result); return(result); }
public static void GetPointPairParams(MultiVector obj, out MultiVector p1, out MultiVector p2) { if (!obj.ContainsOnly(3)) { throw new InvalidEntityException(); } obj = obj.Dual; double delta = Math.Sqrt(Math.Abs((double)MultiVector.InnerProduct(obj, obj))); try { MultiVector temp = MultiVector.InnerProduct(Basis.E8, obj); p1 = (+delta + obj) / temp; p2 = (-delta + obj) / temp; } catch (InvalidOperationException) { throw new InvalidEntityException(); } }
public static MultiVector CreateSphere(MultiVector p1, MultiVector p2, MultiVector p3, MultiVector p4) { return((p1 ^ p2 ^ p3 ^ p4).Dual); }
public static MultiVector CreatePointPair(MultiVector p1, MultiVector p2) { return((p1 ^ p2).Dual); }
public static MultiVector CreateCircle(MultiVector n, MultiVector c, double r) { double d = (double)MultiVector.ScalarProduct(c, n); return IPNS.CreatePlane(n, d) ^ IPNS.CreateSphere(c, r); }
private void drawPoint(MultiVector point, Color color) { MultiVector x; IPNS.GetPointParams(point, out x); GL.Color3(color); GL.PushMatrix(); GL.Translate(x.E1, x.E2, x.E3); GL.Scale(PointRadius, PointRadius, PointRadius); drawModel(sphereVbo); GL.PopMatrix(); }
public static MultiVector CrossProduct(MultiVector v1, MultiVector v2) { return((v2 ^ v1) * Basis.E123); }
public static MultiVector operator ^(MultiVector v1, MultiVector v2) { return(MultiVector.OuterProduct(v1, v2)); }
public static MultiVector CreatePlane(MultiVector n, double d) { return n + d * Basis.E8; }
public static void GetSphereParams(MultiVector obj, out MultiVector c, out double r) { if (!obj.ContainsOnly(1) || obj.E0 == 0.0) throw new InvalidEntityException(); obj /= obj.E0; c = MultiVector.Vector(obj.E1, obj.E2, obj.E3); r = Math.Sqrt(Math.Abs(2 * obj.E8 - (double)MultiVector.ScalarProduct(c, c))); // HACK if (Math.Abs(r) < 1E-3) r = 0.0; }
public static MultiVector CreateLine(MultiVector t, MultiVector d) { return d * Basis.E123 + (MultiVector.CrossProduct(d, t) ^ Basis.E8); }
public static void GetPlaneParams(MultiVector obj, out MultiVector n, out double d) { if (!obj.ContainsOnly(1) || obj.E0 != 0.0) throw new InvalidEntityException(); n = MultiVector.Vector(obj.E1, obj.E2, obj.E3); double norm = n.Length; n /= norm; d = obj.E8 / norm; }
public static MultiVector CreateCircle(MultiVector p1, MultiVector p2, MultiVector p3) { return (p1 ^ p2 ^ p3).Dual; }
public static MultiVector CreateCircle(MultiVector n, MultiVector c, double r) { double d = (double)MultiVector.ScalarProduct(c, n); return(IPNS.CreatePlane(n, d) ^ IPNS.CreateSphere(c, r)); }
private void drawVector(MultiVector vector, Color color) { GL.Color3(color); MultiVector rotAxis = MultiVector.CrossProduct(Basis.E3, vector); double rotAngle = Math.Acos(vector.E3 / vector.Length); ; if (rotAxis == MultiVector.Zero) { rotAxis = Basis.E1; rotAngle = 0.0; } double length = vector.Length; GL.PushMatrix(); GL.Rotate(MathHelper.RadiansToDegrees(rotAngle), rotAxis.E1, rotAxis.E2, rotAxis.E3); GL.Scale(length, length, length); drawModel(vectorLineVbo); GL.PopMatrix(); GL.PushMatrix(); GL.Translate(vector.E1, vector.E2, vector.E3); GL.Rotate(MathHelper.RadiansToDegrees(rotAngle), rotAxis.E1, rotAxis.E2, rotAxis.E3); drawModel(vectorArrowVbo); GL.PopMatrix(); }
public static MultiVector operator *(MultiVector v1, MultiVector v2) { return(MultiVector.GeometricProduct(v1, v2)); }
public static MultiVector CreateLine2(MultiVector p1, MultiVector p2) { return((p1 ^ p2 ^ Basis.E8).Dual); }
private void drawSphere(MultiVector sphere, Color color) { MultiVector c; double r; IPNS.GetSphereParams(sphere, out c, out r); GL.Color3(color); GL.PushMatrix(); GL.Translate(c.E1, c.E2, c.E3); GL.Scale(r, r, r); drawModel(sphereVbo); GL.PopMatrix(); }
public static MultiVector CreateSphere(MultiVector c, double r) { return IPNS.CreatePoint(c) - 0.5 * r * r * Basis.E8; }
private void drawPointPair(MultiVector pointPair, Color color) { MultiVector p1, p2; IPNS.GetPointPairParams(pointPair, out p1, out p2); drawPoint(p1, color); drawPoint(p2, color); }
public static MultiVector CreateLine(MultiVector t, MultiVector d) { return(d * Basis.E123 + (MultiVector.CrossProduct(d, t) ^ Basis.E8)); }
public static MultiVector CreatePlane(MultiVector p1, MultiVector p2, MultiVector p3) { return((p1 ^ p2 ^ p3 ^ Basis.E8).Dual); }
public static MultiVector CreatePlane(MultiVector n, double d) { return(n + d * Basis.E8); }
public static GeometricEntity GetGeometricEntity(MultiVector obj) { if (obj.ContainsOnly(0)) { return GeometricEntity.Scalar; } if (obj.ContainsOnly(1)) { if (obj.E0 == 0 && obj.E8 == 0) return GeometricEntity.Vector; if (obj.E0 == 0) return GeometricEntity.Plane; MultiVector center; double radius; GetSphereParams(obj, out center, out radius); if (radius == 0) return GeometricEntity.Point; return GeometricEntity.Sphere; } if (obj.ContainsOnly(2)) { if (obj.ContainsOnly(Basis.E12, Basis.E13, Basis.E23)) return GeometricEntity.Bivector; if (MultiVector.InnerProduct(Basis.E8, obj) == 0.0) return GeometricEntity.Line; return GeometricEntity.Circle; } if (obj.ContainsOnly(3)) { if (obj.ContainsOnly(Basis.E123)) return GeometricEntity.Trivector; try { MultiVector p1, p2; GetPointPairParams(obj, out p1, out p2); return GeometricEntity.PointPair; } catch (InvalidEntityException) { return GeometricEntity.Unknown; } } return GeometricEntity.Unknown; }
public static MultiVector CreateCircle(MultiVector p1, MultiVector p2, MultiVector p3) { return((p1 ^ p2 ^ p3).Dual); }
public static void GetLineParams(MultiVector obj, out MultiVector t, out MultiVector d) { if (!obj.ContainsOnly(2)) throw new InvalidEntityException(); d = MultiVector.Vector( -obj[Basis.E23], obj[Basis.E13], -obj[Basis.E12]); double norm = d.Length; if (norm == 0.0) throw new InvalidEntityException(); d /= norm; // d cross t MultiVector dct = MultiVector.Vector( obj[Basis.E1 ^ Basis.E8], obj[Basis.E2 ^ Basis.E8], obj[Basis.E3 ^ Basis.E8]) / norm; t = MultiVector.CrossProduct(dct, d); }
public static MultiVector operator *(double f, MultiVector v) { MultiVector result = new MultiVector(); foreach (Blade b in v.Blades) result[b.Basis] = f * b.Value; return result; }
public static void GetPointPairParams(MultiVector obj, out MultiVector p1, out MultiVector p2) { if (!obj.ContainsOnly(3)) throw new InvalidEntityException(); obj = obj.Dual; double delta = Math.Sqrt(Math.Abs((double)MultiVector.InnerProduct(obj, obj))); try { MultiVector temp = MultiVector.InnerProduct(Basis.E8, obj); p1 = (+delta + obj) / temp; p2 = (-delta + obj) / temp; } catch (InvalidOperationException) { throw new InvalidEntityException(); } }
public static MultiVector operator -(MultiVector v) { MultiVector result = new MultiVector(); foreach (Blade blade in v.Blades) result[blade.Basis] = -blade.Value; return result; }
public static void GetPointParams(MultiVector obj, out MultiVector x) { MultiVector temp; double r; IPNS.GetSphereParams(obj, out temp, out r); if (r != 0.0) throw new InvalidEntityException(); x = temp; }
public static MultiVector CrossProduct(MultiVector v1, MultiVector v2) { return (v2 ^ v1) * Basis.E123; }
public static MultiVector CreateLine2(MultiVector p1, MultiVector p2) { return (p1 ^ p2 ^ Basis.E8).Dual; }
public static MultiVector OuterProduct(MultiVector v1, MultiVector v2) { MultiVector result = new MultiVector(); foreach (Blade b1 in v1.Blades) foreach (Blade b2 in v2.Blades) result += Blade.OuterProduct(b1, b2); return result; }
public static MultiVector CreatePlane(MultiVector p1, MultiVector p2, MultiVector p3) { return (p1 ^ p2 ^ p3 ^ Basis.E8).Dual; }
public static double ScalarProduct(MultiVector v1, MultiVector v2) { double result = 0; foreach (Blade b in v1.Blades) { result += b.Value * v2[b.Basis]; } return result; }
public static MultiVector CreatePointPair(MultiVector p1, MultiVector p2) { return (p1 ^ p2).Dual; }
public static MultiVector Vector(double e1, double e2, double e3) { MultiVector v = new MultiVector(); v.E1 = e1; v.E2 = e2; v.E3 = e3; return v; }
public static MultiVector CreateSphere(MultiVector p1, MultiVector p2, MultiVector p3, MultiVector p4) { return (p1 ^ p2 ^ p3 ^ p4).Dual; }
public MultiVector Clone() { MultiVector result = new MultiVector(); foreach (Blade blade in this.Blades) result[blade.Basis] = blade.Value; return result; }
public static MultiVector operator -(Basis e1, Basis e2) { MultiVector ret = new MultiVector(); ret[e1] = 1.0; ret[e2] -= 1.0; return ret; }
public MultiVector ToNullMetric() { MultiVector result = new MultiVector(); foreach (Blade blade in this.Blades) result += blade.ToNullMetric(); return result; }