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,7 +988,8 @@ namespace Tetrahedrons
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, 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;
@@ -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(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
#region Operators
@@ -1037,6 +1040,9 @@ namespace Tetrahedrons
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 t) => Transform(m, t);
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);
@@ -1057,7 +1063,9 @@ namespace Tetrahedrons
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? t) => Transform(m, t);
public static MVec4D operator -(MVec4D m) => m.Neg;
public static MVec4D? operator ~(MVec4D m) => m.Inv;
public static MVec4D operator !(MVec4D m) => m.Rev;

View File

@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
namespace Tetrahedrons
{
@@ -7,14 +9,42 @@ namespace Tetrahedrons
{
public MVec4D[] Verts;
public int[] Faces;
public int[] Edjes;
public Simplex(IEnumerable<MVec4D> verts)
: this(verts.ToArray())
{
Verts = verts.ToArray();
}
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)
@@ -41,50 +71,78 @@ namespace Tetrahedrons
{
var sides = Sides(blade, pivot);
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 m = Verts[i] - pivot;
var n = Verts[j] - pivot;
var k = 0;
for (var i = 0; i < Verts.Length; i++)
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 alph = (blade ^ m) * ~(blade ^ v);
if (!alph.HasValue) continue;
var p = m - v * alph.Value;
verts.Add(p);
var v = m - n;
var alph = (blade ^ m) * ~(blade ^ v);
if (!alph.HasValue) continue;
var p = m - v * alph.Value;
verts.Add(p);
face_verts[i].Add(k);
face_verts[j].Add(k);
k++;
}
}
return new Simplex(verts);
}
public int[] Faces()
{
switch (Verts.Length)
var faces = new List<int>();
foreach (var vlst in face_verts)
{
case 3:
return new[] {0, 1, 2};
case 4:
return new[]
{
0, 1, 2,
0, 1, 3,
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
};
for (var i = 0; i < vlst.Count - 2; i++)
for (var j = i + 1; j < vlst.Count - 1; j++)
for (var k = j + 1; k < vlst.Count; k++)
{
faces.Add(vlst[i]);
faces.Add(vlst[j]);
faces.Add(vlst[k]);
default:
return new int[0];
edges.Add(vlst[i]);
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 double _t;
private bool _pause;
protected override void OnLoad(EventArgs e)
{
@@ -62,44 +63,30 @@ namespace Tetrahedrons
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref _view);
GL.Begin(PrimitiveType.TriangleStrip);
GL.Color3(1d, 1, 1);
Util.Vertex3(-_a - _b);
Util.Vertex3(-_a + _b);
Util.Vertex3(_a - _b);
Util.Vertex3(_a + _b);
GL.Enable(EnableCap.DepthTest);
GL.Begin(PrimitiveType.Lines);
GL.Color3(0f, 0, 0);
foreach (var f in _intr.Edjes)
Util.Vertex3(_intr.Verts[f]);
GL.End();
GL.Enable(EnableCap.DepthTest);
GL.Begin(PrimitiveType.Triangles);
foreach (var f in _intr.Faces())
foreach (var f in _intr.Faces)
{
Util.Color3(_intr.Verts[f]);
Util.Vertex3(_intr.Verts[f]);
}
GL.End();
GL.Disable(EnableCap.DepthTest);
GL.Begin(PrimitiveType.Points);
foreach (var m in _pent.Verts)
Util.Vertex4(m);
GL.End();
GL.Begin(PrimitiveType.Lines);
for (var i = 0; i < _pent.Verts.Length; i++)
for (var j = i + 1; j < _pent.Verts.Length; j++)
{
Util.Vertex4(_pent.Verts[i]);
Util.Vertex4(_pent.Verts[j]);
}
foreach (var f in _pent.Edjes)
Util.Vertex4(_pent.Verts[f]);
GL.End();
GL.Begin(PrimitiveType.Points);
foreach (var m in _intr.Verts)
Util.Vertex4(m);
GL.End();
SwapBuffers();
}
@@ -109,22 +96,29 @@ namespace Tetrahedrons
_proj3d = Matrix4.CreateOrthographic(6, 6f * Height / Width, -4, 4);
if (_pause) return;
_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);
for (var i = 0; i < _pent.Verts.Length; i++)
{
var m = _pent.Verts[i];
m = r * m * !r;
_pent.Verts[i] = m;
}
_pent.Verts[i] |= r;
var blade = MVec4D.UnitXyz;
// var pivot = .5 * MVec4D.UnitW;
var pivot = 1.1 * Math.Sin(_t) * MVec4D.UnitW;
var pivot = MVec4D.Zero;
pivot = .9 * Math.Sin(_t / 5) * MVec4D.UnitW;
_intr = _pent.Intersect(blade, pivot);
}
protected override void OnKeyDown(KeyboardKeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Space)
_pause = !_pause;
}
}
}