implemented 4-simplex intersections

This commit is contained in:
2018-04-04 15:24:16 -04:00
parent 06096bf1aa
commit cb90af4fb7
3 changed files with 133 additions and 73 deletions

View File

@@ -988,6 +988,7 @@ namespace Tetrahedrons
public static MVec4D Outer(double c, MVec4D n) => Mul(c, n); public static MVec4D Outer(double c, MVec4D n) => Mul(c, n);
public static MVec4D Transform(MVec4D m, MVec4D t) => Mul(Mul(t, m), t.Rev);
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, 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(MVec4D? m, double? n) => m.HasValue && n.HasValue ? (MVec4D?) Add(m.Value, n.Value) : null;
@@ -1013,6 +1014,8 @@ namespace Tetrahedrons
public static MVec4D? Outer(MVec4D? m, double? 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; public static MVec4D? Outer(double? m, MVec4D? n) => n.HasValue && m.HasValue ? (MVec4D?) Outer(m.Value, n.Value) : null;
public static MVec4D? Transform(MVec4D? m, MVec4D? t) => Mul(Mul(t, m), t?.Rev);
#endregion #endregion
#region Operators #region Operators
@@ -1037,6 +1040,9 @@ namespace Tetrahedrons
public static MVec4D operator ^(MVec4D m, double c) => Outer(m, c); 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 ^(double c, MVec4D n) => Outer(c, n);
public static MVec4D operator |(MVec4D m, MVec4D t) => Transform(m, t);
public static MVec4D? operator +(MVec4D? m, MVec4D? n) => Add(m, 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 +(double? c, MVec4D? n) => Add(c, n);
public static MVec4D? operator +(MVec4D? m, double? c) => Add(m, c); public static MVec4D? operator +(MVec4D? m, double? c) => Add(m, c);
@@ -1057,6 +1063,8 @@ namespace Tetrahedrons
public static MVec4D? operator ^(MVec4D? m, double? c) => Outer(m, c); 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 ^(double? c, MVec4D? n) => Outer(c, n);
public static MVec4D? operator |(MVec4D? m, MVec4D? t) => Transform(m, t);
public static MVec4D operator -(MVec4D m) => m.Neg; public static MVec4D operator -(MVec4D m) => m.Neg;
public static MVec4D? operator ~(MVec4D m) => m.Inv; public static MVec4D? operator ~(MVec4D m) => m.Inv;

View File

@@ -1,5 +1,7 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Mail;
namespace Tetrahedrons namespace Tetrahedrons
{ {
@@ -7,14 +9,42 @@ namespace Tetrahedrons
{ {
public MVec4D[] Verts; public MVec4D[] Verts;
public int[] Faces;
public int[] Edjes;
public Simplex(IEnumerable<MVec4D> verts) public Simplex(IEnumerable<MVec4D> verts)
: this(verts.ToArray())
{ {
Verts = verts.ToArray();
} }
public Simplex(params MVec4D[] verts) public Simplex(params MVec4D[] verts)
{ {
Verts = verts; Verts = verts.ToArray();
var e = new List<int>();
for (var i = 0; i < Verts.Length; i++)
for (var j = i + 1; j < Verts.Length; j++)
{
e.Add(i);
e.Add(j);
}
Edjes = e.ToArray();
Faces = new int[0];
}
public Simplex(IEnumerable<MVec4D> verts, IEnumerable<int> faces)
: this(verts)
{
Faces = faces.ToArray();
}
public Simplex(IEnumerable<MVec4D> verts, IEnumerable<int> faces, IEnumerable<int> edges)
{
Verts = verts.ToArray();
Faces = faces.ToArray();
Edjes = edges.ToArray();
} }
public bool[] Sides(MVec4D blade, MVec4D pivot) public bool[] Sides(MVec4D blade, MVec4D pivot)
@@ -41,50 +71,78 @@ namespace Tetrahedrons
{ {
var sides = Sides(blade, pivot); var sides = Sides(blade, pivot);
var verts = new List<MVec4D>(); var verts = new List<MVec4D>();
var edges = new List<int>();
var face_verts = new List<int>[Verts.Length];
for (var i = 0; i < face_verts.Length; i++)
face_verts[i] = new List<int>();
for (var i = 0; i < Verts.Length; i++)
for (var j = i + 1; j < Verts.Length; j++)
{ {
if (sides[i] == sides[j]) continue; var k = 0;
var m = Verts[i] - pivot; for (var i = 0; i < Verts.Length; i++)
var n = Verts[j] - pivot; for (var j = i + 1; j < Verts.Length; j++)
{
if (sides[i] == sides[j]) continue;
var m = Verts[i] - pivot;
var n = Verts[j] - pivot;
var v = m - n; var v = m - n;
var alph = (blade ^ m) * ~(blade ^ v); var alph = (blade ^ m) * ~(blade ^ v);
if (!alph.HasValue) continue; if (!alph.HasValue) continue;
var p = m - v * alph.Value; var p = m - v * alph.Value;
verts.Add(p);
verts.Add(p);
face_verts[i].Add(k);
face_verts[j].Add(k);
k++;
}
} }
return new Simplex(verts); var faces = new List<int>();
} foreach (var vlst in face_verts)
public int[] Faces()
{
switch (Verts.Length)
{ {
case 3: for (var i = 0; i < vlst.Count - 2; i++)
return new[] {0, 1, 2}; for (var j = i + 1; j < vlst.Count - 1; j++)
case 4: for (var k = j + 1; k < vlst.Count; k++)
return new[] {
{ faces.Add(vlst[i]);
0, 1, 2, faces.Add(vlst[j]);
0, 1, 3, faces.Add(vlst[k]);
0, 2, 3,
1, 2, 3
};
case 6:
return new[]
{
0, 2, 4
// todo: vertices of a face must be on lines which share a vertex in the simplex
// that's the pattern, and why it "just works" for the 3-simplex.
// think of it as truncating the embedded simplex
};
default: edges.Add(vlst[i]);
return new int[0]; edges.Add(vlst[j]);
edges.Add(vlst[j]);
edges.Add(vlst[k]);
edges.Add(vlst[k]);
edges.Add(vlst[i]);
}
} }
if (faces.Count == 6)
{
for (var i = 0; i < 3; i++)
{
var a = faces[i];
var b = faces[(1 + i) % 3];
var c = faces[3 + i];
var d = faces[3 + (1 + i) % 3];
faces.Add(c);
faces.Add(a);
faces.Add(b);
faces.Add(b);
faces.Add(d);
faces.Add(c);
edges.Add(a);
edges.Add(c);
edges.Add(b);
edges.Add(d);
}
}
return new Simplex(verts, faces, edges);
} }
} }
} }

View File

@@ -27,6 +27,7 @@ namespace Tetrahedrons
private Simplex _intr; private Simplex _intr;
private double _t; private double _t;
private bool _pause;
protected override void OnLoad(EventArgs e) protected override void OnLoad(EventArgs e)
{ {
@@ -62,44 +63,30 @@ namespace Tetrahedrons
GL.MatrixMode(MatrixMode.Modelview); GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref _view); GL.LoadMatrix(ref _view);
GL.Begin(PrimitiveType.TriangleStrip); GL.Enable(EnableCap.DepthTest);
GL.Color3(1d, 1, 1);
Util.Vertex3(-_a - _b); GL.Begin(PrimitiveType.Lines);
Util.Vertex3(-_a + _b); GL.Color3(0f, 0, 0);
Util.Vertex3(_a - _b); foreach (var f in _intr.Edjes)
Util.Vertex3(_a + _b); Util.Vertex3(_intr.Verts[f]);
GL.End(); GL.End();
GL.Enable(EnableCap.DepthTest);
GL.Begin(PrimitiveType.Triangles); GL.Begin(PrimitiveType.Triangles);
foreach (var f in _intr.Faces()) foreach (var f in _intr.Faces)
{ {
Util.Color3(_intr.Verts[f]); Util.Color3(_intr.Verts[f]);
Util.Vertex3(_intr.Verts[f]); Util.Vertex3(_intr.Verts[f]);
} }
GL.End(); GL.End();
GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.DepthTest);
GL.Begin(PrimitiveType.Points);
foreach (var m in _pent.Verts)
Util.Vertex4(m);
GL.End();
GL.Begin(PrimitiveType.Lines); GL.Begin(PrimitiveType.Lines);
for (var i = 0; i < _pent.Verts.Length; i++) foreach (var f in _pent.Edjes)
for (var j = i + 1; j < _pent.Verts.Length; j++) Util.Vertex4(_pent.Verts[f]);
{
Util.Vertex4(_pent.Verts[i]);
Util.Vertex4(_pent.Verts[j]);
}
GL.End(); GL.End();
GL.Begin(PrimitiveType.Points);
foreach (var m in _intr.Verts)
Util.Vertex4(m);
GL.End();
SwapBuffers(); SwapBuffers();
} }
@@ -109,22 +96,29 @@ namespace Tetrahedrons
_proj3d = Matrix4.CreateOrthographic(6, 6f * Height / Width, -4, 4); _proj3d = Matrix4.CreateOrthographic(6, 6f * Height / Width, -4, 4);
if (_pause) return;
_t += e.Time; _t += e.Time;
var pln = MVec4D.UnitXy + MVec4D.UnitZw; var pln = .5 * MVec4D.UnitXy + MVec4D.UnitZw;
var r = MVec4D.Rotor(e.Time / 10, pln.Normalized); var r = MVec4D.Rotor(e.Time / 10, pln.Normalized);
for (var i = 0; i < _pent.Verts.Length; i++) for (var i = 0; i < _pent.Verts.Length; i++)
{ _pent.Verts[i] |= r;
var m = _pent.Verts[i];
m = r * m * !r;
_pent.Verts[i] = m;
}
var blade = MVec4D.UnitXyz; var blade = MVec4D.UnitXyz;
// var pivot = .5 * MVec4D.UnitW; var pivot = MVec4D.Zero;
var pivot = 1.1 * Math.Sin(_t) * MVec4D.UnitW;
pivot = .9 * Math.Sin(_t / 5) * MVec4D.UnitW;
_intr = _pent.Intersect(blade, pivot); _intr = _pent.Intersect(blade, pivot);
} }
protected override void OnKeyDown(KeyboardKeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Space)
_pause = !_pause;
}
} }
} }