buggy 4-simplex intersections
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Dynamic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Text;
|
||||
using OpenTK;
|
||||
@@ -42,6 +43,8 @@ namespace Tetrahedrons
|
||||
|
||||
public double Norm => Math.Sqrt(Norm2);
|
||||
|
||||
public MVec4D Normalized => this * (1 / Norm);
|
||||
|
||||
public MVec4D Grade(int k)
|
||||
{
|
||||
switch (k)
|
||||
@@ -929,12 +932,8 @@ namespace Tetrahedrons
|
||||
);
|
||||
}
|
||||
|
||||
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 n) => Mul(c, n.Inv);
|
||||
|
||||
public static MVec4D Inner(MVec4D m, MVec4D n)
|
||||
{
|
||||
var m0 = m.Grade(0);
|
||||
@@ -1030,10 +1029,6 @@ namespace Tetrahedrons
|
||||
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);
|
||||
@@ -1054,10 +1049,6 @@ namespace Tetrahedrons
|
||||
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);
|
||||
|
||||
90
Tetrahedrons/Simplex.cs
Normal file
90
Tetrahedrons/Simplex.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tetrahedrons
|
||||
{
|
||||
public class Simplex
|
||||
{
|
||||
public MVec4D[] Verts;
|
||||
|
||||
public Simplex(IEnumerable<MVec4D> verts)
|
||||
{
|
||||
Verts = verts.ToArray();
|
||||
}
|
||||
|
||||
public Simplex(params MVec4D[] verts)
|
||||
{
|
||||
Verts = verts;
|
||||
}
|
||||
|
||||
public bool[] Sides(MVec4D blade, MVec4D pivot)
|
||||
{
|
||||
var sides = new bool[Verts.Length];
|
||||
|
||||
var perp = blade.Dual;
|
||||
|
||||
for (var i = 0; i < Verts.Length; i++)
|
||||
{
|
||||
var m = Verts[i];
|
||||
var p = m - pivot;
|
||||
var rej = (p ^ blade) * ~blade;
|
||||
if (!rej.HasValue) continue;
|
||||
var dot = rej & perp;
|
||||
|
||||
sides[i] = dot.Value.S > 0;
|
||||
}
|
||||
|
||||
return sides;
|
||||
}
|
||||
|
||||
public Simplex Intersect(MVec4D blade, MVec4D pivot)
|
||||
{
|
||||
var sides = Sides(blade, pivot);
|
||||
var verts = new List<MVec4D>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return new Simplex(verts);
|
||||
}
|
||||
|
||||
public int[] Faces()
|
||||
{
|
||||
switch (Verts.Length)
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
default:
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.PerformanceData;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Printing;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Security;
|
||||
using System.Xml.XPath;
|
||||
using OpenTK;
|
||||
using OpenTK.Audio.OpenAL;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Input;
|
||||
using OpenTK.Platform.Windows;
|
||||
|
||||
namespace Tetrahedrons
|
||||
{
|
||||
@@ -16,10 +20,13 @@ namespace Tetrahedrons
|
||||
private Matrix4 _proj3d;
|
||||
private Matrix4 _view;
|
||||
|
||||
MVec4D a = MVec4D.UnitX;
|
||||
MVec4D b = MVec4D.UnitY;
|
||||
MVec4D v = MVec4D.Vec1(1, 1, 0, -1);
|
||||
MVec4D t = MVec4D.Vec1(0, 0, 0, 1);
|
||||
private MVec4D _a = MVec4D.UnitX;
|
||||
private MVec4D _b = MVec4D.UnitY;
|
||||
|
||||
private Simplex _pent;
|
||||
private Simplex _intr;
|
||||
|
||||
private double _t;
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
@@ -28,8 +35,14 @@ namespace Tetrahedrons
|
||||
X = (DisplayDevice.Default.Width - Width) / 2;
|
||||
Y = (DisplayDevice.Default.Height - Height) / 2;
|
||||
|
||||
_view = Matrix4.LookAt(Vector3.Zero, -new Vector3(1, 1, 1), Vector3.UnitZ);
|
||||
_view = Matrix4.LookAt(Vector3.Zero, -new Vector3(.86f, .5f, 1), Vector3.UnitZ);
|
||||
|
||||
_pent = new Simplex( // not-quite-regular pentatope
|
||||
new Vector4d(1, -1, -1, -1),
|
||||
new Vector4d(-1, 1, -1, -1),
|
||||
new Vector4d(-1, -1, 1, -1),
|
||||
new Vector4d(-1, -1, -1, 1),
|
||||
new Vector4d(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
@@ -39,7 +52,6 @@ namespace Tetrahedrons
|
||||
GL.Viewport(ClientRectangle);
|
||||
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
GL.PointSize(10f);
|
||||
GL.LineWidth(3f);
|
||||
|
||||
@@ -50,41 +62,42 @@ namespace Tetrahedrons
|
||||
GL.MatrixMode(MatrixMode.Modelview);
|
||||
GL.LoadMatrix(ref _view);
|
||||
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.Begin(PrimitiveType.TriangleStrip);
|
||||
GL.Color3(1d, 1, 1);
|
||||
GL.Vertex3((-a - b).V3);
|
||||
GL.Vertex3((-a + b).V3);
|
||||
GL.Vertex3((a - b).V3);
|
||||
GL.Vertex3((a + b).V3);
|
||||
Util.Vertex3(-_a - _b);
|
||||
Util.Vertex3(-_a + _b);
|
||||
Util.Vertex3(_a - _b);
|
||||
Util.Vertex3(_a + _b);
|
||||
GL.End();
|
||||
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
|
||||
GL.Begin(PrimitiveType.Lines);
|
||||
GL.Color3(1d,0,0); GL.Vertex3(0,0,0); GL.Vertex3(1,0,0);
|
||||
GL.Color3(0,1d,0); GL.Vertex3(0,0,0); GL.Vertex3(0,1,0);
|
||||
GL.Color3(0,0,1d); GL.Vertex3(0,0,0); GL.Vertex3(0,0,1);
|
||||
GL.Begin(PrimitiveType.Triangles);
|
||||
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();
|
||||
|
||||
var B = MVec4D.UnitXyz;
|
||||
var bt = B ^ t;
|
||||
var bv = B ^ v;
|
||||
var alph = bt / bv ?? MVec4D.Zero;
|
||||
var dt = alph * v;
|
||||
var p = t - dt;
|
||||
|
||||
Console.Out.WriteLine("p = {0}", p);
|
||||
|
||||
GL.Begin(PrimitiveType.Lines);
|
||||
GL.Color3(.5 + t.W/4, 0, .5 - t.W/4);
|
||||
GL.Vertex3(t.V3);
|
||||
GL.Color3(.5 + (t + v).W/4, 0, .5 - (t + v).W/4);
|
||||
GL.Vertex3((t + v).V3);
|
||||
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]);
|
||||
}
|
||||
|
||||
GL.End();
|
||||
|
||||
GL.Begin(PrimitiveType.Points);
|
||||
GL.Color3(0d, 0, 1);
|
||||
GL.Vertex3(p.V3);
|
||||
foreach (var m in _intr.Verts)
|
||||
Util.Vertex4(m);
|
||||
GL.End();
|
||||
|
||||
SwapBuffers();
|
||||
@@ -94,13 +107,24 @@ namespace Tetrahedrons
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
|
||||
_proj3d = Matrix4.CreateOrthographic(6, 6f * Height / Width, -2, 2);
|
||||
_proj3d = Matrix4.CreateOrthographic(6, 6f * Height / Width, -4, 4);
|
||||
|
||||
var rv = MVec4D.Rotor(e.Time, MVec4D.UnitXy);
|
||||
v = rv * v * !rv;
|
||||
_t += e.Time;
|
||||
|
||||
var rt = MVec4D.Rotor(e.Time / 4, MVec4D.UnitZw);
|
||||
t = rt * t * !rt;
|
||||
var pln = 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;
|
||||
}
|
||||
|
||||
var blade = MVec4D.UnitXyz;
|
||||
// var pivot = .5 * MVec4D.UnitW;
|
||||
var pivot = 1.1 * Math.Sin(_t) * MVec4D.UnitW;
|
||||
_intr = _pent.Intersect(blade, pivot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,9 @@
|
||||
<Compile Include="MVec4D.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Simplex.cs" />
|
||||
<Compile Include="TetrahedronWindow.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="OpenTK.dll.config" />
|
||||
|
||||
25
Tetrahedrons/Util.cs
Normal file
25
Tetrahedrons/Util.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace Tetrahedrons
|
||||
{
|
||||
public static class Util
|
||||
{
|
||||
public static void Color3(MVec4D m)
|
||||
{
|
||||
m *= .5;
|
||||
GL.Color3(.5 + m.X, .5 + m.Y, .5 * m.Z);
|
||||
}
|
||||
|
||||
public static void Vertex4(MVec4D m)
|
||||
{
|
||||
var i = m.W / 2;
|
||||
GL.Color3(.5 + i, 0, .5 - i);
|
||||
GL.Vertex3(m.X, m.Y, m.Z);
|
||||
}
|
||||
|
||||
public static void Vertex3(MVec4D m)
|
||||
{
|
||||
GL.Vertex3(m.X, m.Y, m.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user