Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Tetrahedrons/MVec3d.cs
#	Tetrahedrons/TetrahedronWindow.cs
This commit is contained in:
2018-04-04 20:18:57 -04:00
7 changed files with 1434 additions and 587 deletions

View File

@@ -1,271 +0,0 @@
using System;
using OpenTK;
namespace Tetrahedrons
{
// ReSharper disable once InconsistentNaming
public struct MVec3d
{
public static readonly MVec3d Zero = new MVec3d(0, 0, 0, 0, 0, 0, 0, 0);
public static readonly MVec3d One = new MVec3d(1, 1, 1, 1, 1, 1, 1, 1);
public static readonly MVec3d Unit = new MVec3d(1, 0, 0, 0, 0, 0, 0, 0);
public static readonly MVec3d Unit1 = new MVec3d(0, 1, 0, 0, 0, 0, 0, 0);
public static readonly MVec3d Unit2 = new MVec3d(0, 0, 1, 0, 0, 0, 0, 0);
public static readonly MVec3d Unit3 = new MVec3d(0, 0, 0, 1, 0, 0, 0, 0);
public static readonly MVec3d Unit23 = new MVec3d(0, 0, 0, 0, 1, 0, 0, 0);
public static readonly MVec3d Unit31 = new MVec3d(0, 0, 0, 0, 0, 1, 0, 0);
public static readonly MVec3d Unit12 = new MVec3d(0, 0, 0, 0, 0, 0, 1, 0);
public static readonly MVec3d Unit123 = new MVec3d(0, 0, 0, 0, 0, 0, 0, 1);
public double E;
public double E1;
public double E2;
public double E3;
public double E23;
public double E31;
public double E12;
public double E123;
public MVec3d(double e, double e1, double e2, double e3, double e23, double e31, double e12, double e123)
{
E = e;
E1 = e1;
E2 = e2;
E3 = e3;
E23 = e23;
E31 = e31;
E12 = e12;
E123 = e123;
}
public MVec3d(MVec3d s, MVec3d v, MVec3d b, MVec3d t)
: this(s.E, v.E1, v.E2, v.E3, b.E23, b.E31, b.E12, t.E123)
{
}
public static MVec3d Scalar(double e) => new MVec3d(e, 0, 0, 0, 0, 0, 0, 0);
public static MVec3d Vector(double e1, double e2, double e3) => new MVec3d(0, e1, e2, e3, 0, 0, 0, 0);
public static MVec3d Vector(Vector3d v) => new MVec3d(0, v.X, v.Y, v.Z, 0, 0, 0, 0);
public static MVec3d Bivector(double e23, double e31, double e12) => new MVec3d(0, 0, 0, 0, e23, e31, e12, 0);
public static MVec3d Trivector(double e123) => new MVec3d(0, 0, 0, 0, 0, 0, 0, e123);
public static MVec3d Complex(double real, double imag) => new MVec3d(real, 0, 0, 0, 0, 0, 0, imag);
public static MVec3d Complex(double w, double i, double j, double k) => new MVec3d(w, 0, 0, 0, i, j, k, 0);
public static MVec3d Complex(double angle, MVec3d plane) => Math.Cos(angle) + Math.Sin(angle) * plane;
public static MVec3d Add(MVec3d m, MVec3d n)
{
return new MVec3d(m.E + n.E,
m.E1 + n.E1, m.E2 + n.E2, m.E3 + n.E3,
m.E23 + n.E23, m.E31 + n.E31, m.E12 + n.E12,
m.E123 + n.E123);
}
public static MVec3d Sub(MVec3d m, MVec3d n)
{
return new MVec3d(m.E - n.E,
m.E1 - n.E1, m.E2 - n.E2, m.E3 - n.E3,
m.E23 - n.E23, m.E31 - n.E31, m.E12 - n.E12,
m.E123 - n.E123);
}
public static MVec3d Mult(MVec3d m, MVec3d n)
{
var r = new MVec3d();
if (Math.Abs(m.E) > 1e-8)
{
r.E += m.E * n.E;
r.E1 += m.E * n.E1;
r.E2 += m.E * n.E2;
r.E3 += m.E * n.E3;
r.E23 += m.E * n.E23;
r.E31 += m.E * n.E31;
r.E12 += m.E * n.E12;
r.E123 += m.E * n.E123;
}
if (Math.Abs(m.E1) > 1e-8)
{
r.E += +m.E1 * n.E1;
r.E1 += +m.E1 * n.E;
r.E2 += +m.E1 * n.E12;
r.E3 += -m.E1 * n.E31;
r.E23 += +m.E1 * n.E123;
r.E31 += -m.E1 * n.E3;
r.E12 += +m.E1 * n.E2;
r.E123 += +m.E1 * n.E23;
}
if (Math.Abs(m.E2) > 1e-8)
{
r.E += +m.E2 * n.E2;
r.E1 += -m.E2 * n.E12;
r.E2 += +m.E2 * n.E;
r.E3 += +m.E2 * n.E23;
r.E23 += +m.E2 * n.E3;
r.E31 += +m.E2 * n.E123;
r.E12 += -m.E2 * n.E1;
r.E123 += +m.E2 * n.E31;
}
if (Math.Abs(m.E3) > 1e-8)
{
r.E += +m.E3 * n.E3;
r.E1 += +m.E3 * n.E31;
r.E2 += -m.E3 * n.E23;
r.E3 += +m.E3 * n.E;
r.E23 += -m.E3 * n.E2;
r.E31 += +m.E3 * n.E1;
r.E12 += +m.E3 * n.E123;
r.E123 += +m.E3 * n.E12;
}
if (Math.Abs(m.E23) > 1e-8)
{
r.E += -m.E23 * n.E23;
r.E1 += -m.E23 * n.E123;
r.E2 += +m.E23 * n.E3;
r.E3 += -m.E23 * n.E2;
r.E23 += +m.E23 * n.E;
r.E31 += +m.E23 * n.E12;
r.E12 += -m.E23 * n.E31;
r.E123 += +m.E23 * n.E1;
}
if (Math.Abs(m.E31) > 1e-8)
{
r.E += -m.E31 * n.E31;
r.E1 += -m.E31 * n.E3;
r.E2 += -m.E31 * n.E123;
r.E3 += +m.E31 * n.E1;
r.E23 += -m.E31 * n.E12;
r.E31 += +m.E31 * n.E;
r.E12 += +m.E31 * n.E23;
r.E123 += +m.E31 * n.E2;
}
if (Math.Abs(m.E12) > 1e-8)
{
r.E += -m.E12 * n.E12;
r.E1 += +m.E12 * n.E2;
r.E2 += -m.E12 * n.E1;
r.E3 += -m.E12 * n.E123;
r.E23 += +m.E12 * n.E31;
r.E31 += -m.E12 * n.E23;
r.E12 += +m.E12 * n.E;
r.E123 += +m.E12 * n.E3;
}
if (Math.Abs(m.E123) > 1e-8)
{
r.E += -m.E123 * n.E123;
r.E1 += -m.E123 * n.E23;
r.E2 += -m.E123 * n.E31;
r.E3 += -m.E123 * n.E12;
r.E23 += +m.E123 * n.E1;
r.E31 += +m.E123 * n.E2;
r.E12 += +m.E123 * n.E3;
r.E123 += +m.E123 * n.E;
}
return r;
}
public double Norm2 => E * E + E1 * E1 + E2 * E2 + E3 * E3 + E23 * E23 + E31 * E31 + E12 * E12 + E123 * E123;
public double Norm => Math.Sqrt(Norm2);
public MVec3d Inv
{
get
{
var n2 = Norm2;
return new MVec3d(E / n2, -E1 / n2, -E2 / n2, -E3 / n2, -E23 / n2, -E31 / n2, -E12 / n2, E123 / n2);
// return new MVec3d(E / n2, E1 / n2, E2 / n2, E3 / n2, E23 / n2, E31 / n2, E12 / n2, E123 / n2);
}
}
public MVec3d Grade(int k)
{
switch (k)
{
case 0:
return Scalar(E);
case 1:
return Vector(E1, E2, E3);
case 2:
return Bivector(E23, E31, E12);
case 3:
return Trivector(E123);
default:
return new MVec3d();
}
}
public static MVec3d Inner(MVec3d m, MVec3d n)
{
var m0 = m.Grade(0);
var m1 = m.Grade(1);
var m2 = m.Grade(2);
var m3 = m.Grade(3);
var n0 = n.Grade(0);
var n1 = n.Grade(1);
var n2 = n.Grade(2);
var n3 = n.Grade(3);
return new MVec3d(
m0 * n0 + m1 * n1 + m2 * n2 + m3 * n3,
m0 * n1 + m1 * n2 + m2 * n3,
m0 * n2 + m1 * n3,
m0 * n3
);
}
public static MVec3d Outer(MVec3d m, MVec3d n)
{
var m0 = m.Grade(0);
var m1 = m.Grade(1);
var m2 = m.Grade(2);
var m3 = m.Grade(3);
var n0 = n.Grade(0);
var n1 = n.Grade(1);
var n2 = n.Grade(2);
var n3 = n.Grade(3);
return new MVec3d(
m0 * n0,
m1 * n0 + m0 * n1,
m2 * n0 + m1 * n1 + m0 * n2,
m3 * n0 + m2 * n1 + m1 * n2 + m0 * m3
);
}
public static MVec3d operator ~(MVec3d m) => m.Inv;
public static MVec3d operator *(MVec3d m, MVec3d n) => Mult(m, n);
public static MVec3d operator +(MVec3d m, MVec3d n) => Add(m, n);
public static MVec3d operator -(MVec3d m, MVec3d n) => Sub(m, n);
public static MVec3d operator &(MVec3d m, MVec3d n) => Inner(m, n);
public static MVec3d operator ^(MVec3d m, MVec3d n) => Outer(m, n);
public MVec3d ScalarPart => Scalar(E);
public MVec3d VectorPart => Vector(E1, E2, E3);
public MVec3d BivectorPart => Bivector(E23, E31, E12);
public MVec3d TrivectorPart => Trivector(E123);
public static implicit operator MVec3d(Vector3 v) => new MVec3d(0, v.X, v.Y, v.Z, 0, 0, 0, 0);
public static implicit operator MVec3d(Vector3d v) => new MVec3d(0, v.X, v.Y, v.Z, 0, 0, 0, 0);
public static implicit operator MVec3d(double s) => new MVec3d(s, 0, 0, 0, 0, 0, 0, 0);
public static explicit operator double(MVec3d m) => m.E;
public static explicit operator Vector3d(MVec3d m) => new Vector3d(m.E1, m.E2, m.E3);
public override string ToString()
{
return $"({E:0.00} {E1:0.00}e1 {E2:0.00}e2 {E3:0.00}e3 {E23:0.00}e23 {E31:0.00}e31 {E12:0.00}e12 {E123:0.00}e123)";
}
}
}

1121
Tetrahedrons/MVec4D.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,14 @@
using OpenTK;
using System;
using OpenTK;
namespace Tetrahedrons
{
internal class Program : GameWindow
{
public static void Main(string[] args)
{
using(var p = new TetrahedronWindow())
p.Run();
}
}
internal class Program : GameWindow
{
public static void Main(string[] args)
{
using (var p = new TetrahedronWindow())
p.Run();
}
}
}

148
Tetrahedrons/Simplex.cs Normal file
View File

@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
namespace Tetrahedrons
{
public class Simplex
{
public MVec4D[] Verts;
public int[] Faces;
public int[] Edjes;
public Simplex(IEnumerable<MVec4D> verts)
: this(verts.ToArray())
{
}
public Simplex(params MVec4D[] 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)
{
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>();
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>();
{
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);
face_verts[i].Add(k);
face_verts[j].Add(k);
k++;
}
}
var faces = new List<int>();
foreach (var vlst in face_verts)
{
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]);
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

@@ -1,332 +1,153 @@
using System;
using System.Collections.Generic;
using System;
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
{
public struct Polygon
{
public Vector3d[] Points;
public Color Color;
public class TetrahedronWindow : GameWindow
{
private Matrix4 _proj3d;
private Matrix4 _view;
public Polygon(Vector3d[] points) : this(points, Color.DodgerBlue)
{
}
private MVec4D _a = MVec4D.UnitX;
private MVec4D _b = MVec4D.UnitY;
public Polygon(Vector3d[] points, Color color)
{
Points = points;
Color = color;
}
private Simplex[] _simplexes;
private Simplex[] _intersections;
private double _t;
private bool _pause;
private bool _wire;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
X = (DisplayDevice.Default.Width - Width) / 2;
Y = (DisplayDevice.Default.Height - Height) / 2;
_view = Matrix4.LookAt(Vector3.Zero, -new Vector3(.86f, .5f, 1), Vector3.UnitZ);
const int n = 5;
_simplexes = new Simplex[n * n * n * n];
_intersections = new Simplex[_simplexes.Length];
var off = (new Vector4d(n - 1, n - 1, n - 1, n - 1)) / 2;
int i = 0;
for (var x = 0; x < n; x++)
for (var y = 0; y < n; y++)
for (var z = 0; z < n; z++)
for (var w = 0; w < n; w++)
{
var d = new Vector4d(x, y, z, w);
_simplexes[i] = new Simplex( // not-quite-regular pentatope
new Vector4d(+.5, -.5, -.5, -.5) + d - off,
new Vector4d(-.5, +.5, -.5, -.5) + d - off,
new Vector4d(-.5, -.5, +.5, -.5) + d - off,
new Vector4d(-.5, -.5, -.5, +.5) + d - off,
new Vector4d(+.5, +.5, +.5, +.5) + d - off);
_intersections[i] = new Simplex();
i++;
}
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Viewport(ClientRectangle);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.PointSize(10f);
GL.LineWidth(3f);
GL.PushMatrix();
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref _proj3d);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref _view);
GL.Enable(EnableCap.DepthTest);
GL.Begin(PrimitiveType.Lines);
GL.Color3(0f, 0, 0);
foreach (var intr in _intersections)
foreach (var f in intr.Edjes)
Util.Vertex3(intr.Verts[f]);
GL.End();
GL.Begin(PrimitiveType.Triangles);
foreach (var intr in _intersections)
foreach (var f in intr.Faces)
{
Util.Color3(intr.Verts[f]);
Util.Vertex3(intr.Verts[f]);
}
GL.End();
GL.Disable(EnableCap.DepthTest);
if (_wire)
{
GL.Begin(PrimitiveType.Lines);
foreach (var sim in _simplexes)
foreach (var f in sim.Edjes)
Util.Vertex4(sim.Verts[f]);
public void Draw()
{
GL.Begin(PrimitiveType.TriangleStrip);
GL.Color3(Color);
foreach (var v in Points)
GL.Vertex3(v);
GL.End();
}
}
public static Polygon operator +(Polygon p, MVec3d m)
{
var pts = new Vector3d[p.Points.Length];
for (var i = 0; i < p.Points.Length; i++)
pts[i] = (Vector3d) (p.Points[i] + m);
return new Polygon(pts, p.Color);
}
SwapBuffers();
}
public static Polygon operator -(Polygon p, MVec3d m)
{
var pts = new Vector3d[p.Points.Length];
for (var i = 0; i < p.Points.Length; i++)
pts[i] = (Vector3d) (p.Points[i] - m);
return new Polygon(pts, p.Color);
}
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
public static Polygon operator *(Polygon p, MVec3d m)
{
var pts = new Vector3d[p.Points.Length];
for (var i = 0; i < p.Points.Length; i++)
pts[i] = (Vector3d) (p.Points[i] * m);
return new Polygon(pts, p.Color);
}
var w = 10f;
var d = w;
_proj3d = Matrix4.CreateOrthographic(w, w * Height / Width, -d / 2, d / 2);
public static Polygon operator ^(Polygon p, MVec3d m)
{
var pts = new Vector3d[p.Points.Length];
for (var i = 0; i < p.Points.Length; i++)
pts[i] = (Vector3d) (p.Points[i] ^ m);
return new Polygon(pts, p.Color);
}
if (_pause) return;
public static Polygon operator &(Polygon p, MVec3d m)
{
var pts = new Vector3d[p.Points.Length];
for (var i = 0; i < p.Points.Length; i++)
pts[i] = (Vector3d) (p.Points[i] & m);
return new Polygon(pts, p.Color);
}
}
_t += e.Time;
public class Tetrahedron
{
public readonly Vector3d[] Points;
public Color FillColor = Color.DodgerBlue;
public Color SurfaceColor = Color.GhostWhite;
public Color WireColor = Color.Maroon;
var pln = MVec4D.UnitXy + MVec4D.UnitXz + MVec4D.UnitYw;
var r = MVec4D.Rotor(e.Time / 10, pln.Normalized);
foreach (var pent in _simplexes)
for (var i = 0; i < pent.Verts.Length; i++)
pent.Verts[i] |= r;
public Tetrahedron(Vector3d p1, Vector3d p2, Vector3d p3, Vector3d p4)
{
Points = new[] {p1, p2, p3, p4};
}
var blade = MVec4D.UnitXyz;
var pivot = MVec4D.Zero;
public void Draw(bool wire = true)
{
if (wire)
{
GL.Begin(PrimitiveType.Lines);
GL.Color3(WireColor);
for (var i = 0; i < _simplexes.Length; i++)
{
_intersections[i] = _simplexes[i].Intersect(blade, pivot);
}
}
for (var i = 0; i < 4; i++)
for (var j = i + 1; j < 4; j++)
{
GL.Vertex3(Points[i]);
GL.Vertex3(Points[j]);
}
protected override void OnKeyDown(KeyboardKeyEventArgs e)
{
base.OnKeyDown(e);
GL.End();
}
else
{
GL.Begin(PrimitiveType.Triangles);
GL.Color3(SurfaceColor);
if (e.Key == Key.Space)
_pause = !_pause;
for (var i = 0; i < 4; i++)
for (var j = i + 1; j < 4; j++)
for (var k = j + 1; k < 4; k++)
{
GL.Vertex3(Points[i]);
GL.Vertex3(Points[j]);
GL.Vertex3(Points[k]);
}
GL.End();
}
}
public Polygon Intersection(MVec3d blade, MVec3d pivot)
{
var pts = new Vector3d[4];
for (var i = 0; i < 4; i++)
{
pts[i] = (Vector3d) (Points[i] - pivot);
}
var a = blade * MVec3d.Unit123;
var sides = new double[4];
for (var i = 0; i < 4; i++)
{
sides[i] = (a & ((pts[i] ^ blade) * ~blade)).E; // normal dot rejection
}
var vecs = new List<Vector3d>(4);
for (var i = 0; i < 4; i++)
{
for (var j = i + 1; j < 4; j++)
{
if (sides[i] * sides[j] >= 0) continue; // both pts on same side
var t = ((blade ^ pts[i]) * ~(blade ^ (pts[j] - pts[i]))).E;
var point = pts[i] + t * (pts[j] - pts[i]);
vecs.Add((Vector3d) (point + pivot));
}
}
return new Polygon(vecs.ToArray()) {Color = FillColor};
}
}
public class TetrahedronWindow : GameWindow
{
private Matrix4 _proj3D;
private Matrix4 _proj2D;
private Matrix4 _view;
private double _t;
private bool _pause;
private bool _div;
private Tetrahedron _tetra;
private Polygon _polyg;
private MVec3d _b1 = MVec3d.Unit1;
private MVec3d _b2 = MVec3d.Unit3;
private MVec3d _pivot = MVec3d.Zero;
private Polygon _square = new Polygon(new[] {new Vector3d(-1, -1, 0), new Vector3d(-1, 1, 0), new Vector3d(1, -1, 0), new Vector3d(1, 1, 0),}, Color.Red);
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
X = (DisplayDevice.Default.Width - Width) / 2;
Y = (DisplayDevice.Default.Height - Height) / 2;
_tetra = new Tetrahedron(new Vector3d(1, 1, 1), new Vector3d(-1, -1, 1), new Vector3d(-1, 1, -1), new Vector3d(1, -1, -1));
_polyg = new Polygon(new[] {new Vector3d(-1, -1, 0), new Vector3d(-1, 1, 0), new Vector3d(1, -1, 0), new Vector3d(1, 1, 0)});
_view = Matrix4.LookAt(Vector3.Zero, -new Vector3(1, .6f, 1f), Vector3.UnitZ);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Viewport(ClientRectangle);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.PointSize(10f);
GL.PushMatrix();
if (_div)
{
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref _proj2D);
_polyg.Draw();
}
else
{
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref _proj3D);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref _view);
GL.Enable(EnableCap.DepthTest);
_tetra.Draw(wire: false);
GL.Disable(EnableCap.DepthTest);
_polyg.Draw();
GL.Begin(PrimitiveType.Points);
GL.Color3(Color.DarkBlue);
GL.Vertex3((Vector3d) _pivot);
GL.End();
GL.Begin(PrimitiveType.Lines);
GL.Vertex3((Vector3d) _pivot);
GL.Vertex3((Vector3d) (_pivot + (_b2 ^ _b1) * MVec3d.Unit123 * .5));
GL.End();
GL.Enable(EnableCap.DepthTest);
_tetra.Draw(wire: true);
}
GL.PopMatrix();
SwapBuffers();
}
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
_proj3D = Matrix4.CreateOrthographic(6, 6f * Height / Width, -2, 2);
_proj2D = Matrix4.CreateOrthographic(4, 4f * Height / Width, -1, 1);
_t += e.Time;
if (Keyboard[Key.Left])
{
var rot = MVec3d.Complex(-e.Time, MVec3d.Unit12);
_b1 = rot * _b1 * ~rot; // todo make blade classes
_b2 = rot * _b2 * ~rot;
}
if (Keyboard[Key.Right])
{
var rot = MVec3d.Complex(e.Time, MVec3d.Unit12);
_b1 = rot * _b1 * ~rot;
_b2 = rot * _b2 * ~rot;
}
if (Keyboard[Key.Up])
{
_pivot -= (_b1 ^ _b2) * MVec3d.Unit123 * e.Time;
}
if (Keyboard[Key.Down])
{
_pivot += (_b1 ^ _b2) * MVec3d.Unit123 * e.Time;
}
if (_pause)
return;
// var b1 = MVec3d.Unit2;
// var b2 = MVec3d.Unit3;
// var pivot = new Vector3d(Math.Cos(_t), 0, 0);
// var b1 = MVec3d.Vector(0, Math.Cos(_t * .2), Math.Sin(_t * .5));
// var b2 = MVec3d.Vector(Math.Cos(_t * .6), 0, Math.Sin(_t * .4));
// var pivot = Vector3d.Zero;
// var b1 = MVec3d.Vector(Math.Cos(_t/2), Math.Sin(_t/2), 0);
// var b2 = MVec3d.Unit3;
// var pivot = Vector3d.Zero;
// var blade = MVec3d.Outer(b1, b2);
// var rot = MVec3d.Complex(_t / 2, MVec3d.Unit12);
// var b1 = rot * MVec3d.Unit2 * ~rot;
// var b2 = rot * MVec3d.Unit3 * ~rot;
// var pln = MVec3d.Outer(b1, b2);
// var blade = pln;
// var pivot = Vector3d.Zero;
_polyg = _tetra.Intersection(_b1 ^ _b2, _pivot);
if (_div)
{
var px = ((_pivot & _b1) * ~_b1) & _b1;
var py = ((_pivot ^ _b1) * ~_b1) & ((_b2 ^ _b1) * ~_b1);
for (var i = 0; i < _polyg.Points.Length; i++)
{
MVec3d p = _polyg.Points[i];
var x = ((p & _b1) * ~_b1) & _b1;
var y = ((p ^ _b1) * ~_b1) & ((_b2 ^ _b1) * ~_b1);
_polyg.Points[i] = new Vector3d(x.E - px.E, y.E - py.E, 0);
}
}
}
protected override void OnKeyDown(KeyboardKeyEventArgs e)
{
base.OnKeyDown(e);
switch (e.Key)
{
case Key.Space:
_pause = !_pause;
break;
case Key.A:
_div = !_div;
break;
case Key.R:
_b1 = MVec3d.Unit1;
_b2 = MVec3d.Unit3;
_pivot = MVec3d.Zero;
break;
}
}
}
if (e.Key == Key.Comma)
_wire = !_wire;
}
}
}

View File

@@ -42,10 +42,12 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MVec3d.cs" />
<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
View 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);
}
}
}