implemented 4-simplex intersections
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user