// TODO: Test // ref : https://cvtech.cc/pointdist/ public d3 Distance(d3 p) { var v = length(cross(p - a, dot(p - b, p - c))) / 6d; var s = length(cross(b - a, c - a)) / 2d; return(3 * v / s); }
public (TR t1, TR t2, TR t3, TR t4, DN n1, DN n2, DN n3, DN n4) Split(d3 p) { var th = tetrahedra; (DN n, TR t)abc = (new DN(p, th.a, th.b, th.c), new TR(th.a, th.b, th.c)); (DN n, TR t)bcd = (new DN(p, th.b, th.c, th.d), new TR(th.b, th.c, th.d)); (DN n, TR t)cda = (new DN(p, th.c, th.d, th.a), new TR(th.c, th.d, th.a)); (DN n, TR t)dab = (new DN(p, th.d, th.a, th.b), new TR(th.d, th.a, th.b)); abc.n.neighbor = new List <DN> { bcd.n, cda.n, dab.n }; bcd.n.neighbor = new List <DN> { cda.n, dab.n, abc.n }; cda.n.neighbor = new List <DN> { dab.n, abc.n, bcd.n }; dab.n.neighbor = new List <DN> { abc.n, bcd.n, cda.n }; this.SetNeighbor(abc.n, abc.t); this.SetNeighbor(bcd.n, bcd.t); this.SetNeighbor(cda.n, cda.t); this.SetNeighbor(dab.n, dab.t); return(abc.t, bcd.t, cda.t, dab.t, abc.n, bcd.n, cda.n, dab.n); }
public Sphere GetCircumscribedSphere() { /// <summary> // http://mathworld.wolfram.com/Circumsphere.html /// </summary> var a2 = a * a; var a2ex = a2.x + a2.y + a2.z; var b2 = b * b; var b2ex = b2.x + b2.y + b2.z; var c2 = c * c; var c2ex = c2.x + c2.y + c2.z; var d2 = d * d; var d2ex = d2.x + d2.y + d2.z; var detA = determinant(new d44( a.x, a.y, a.z, 1, b.x, b.y, b.z, 1, c.x, c.y, c.z, 1, d.x, d.y, d.z, 1)); var detX = determinant(new d44( a2ex, a.y, a.z, 1, b2ex, b.y, b.z, 1, c2ex, c.y, c.z, 1, d2ex, d.y, d.z, 1)); var detY = -determinant(new d44( a2ex, a.x, a.z, 1, b2ex, b.x, b.z, 1, c2ex, c.x, c.z, 1, d2ex, d.x, d.z, 1)); var detZ = determinant(new d44( a2ex, a.x, a.y, 1, b2ex, b.x, b.y, 1, c2ex, c.x, c.y, 1, d2ex, d.x, d.y, 1)); var ctr = new d3(detX, detY, detZ) / (2 * detA); return(new Sphere(ctr, distance(ctr, a))); }
Flip32(DN n1, DN n2, DN n3, d3 p31, d3 p12, d3 p23, d3 apex_x, d3 apex_y) { d3 a = p31; d3 b = p12; d3 c = p23; DN nx = new DN(a, b, c, apex_x); DN ny = new DN(a, b, c, apex_y); nx.neighbor.Add(ny); ny.neighbor.Add(nx); TR xab = new TR(apex_x, a, b); TR yab = new TR(apex_y, a, b); TR xbc = new TR(apex_x, b, c); TR ybc = new TR(apex_y, b, c); TR xca = new TR(apex_x, c, a); TR yca = new TR(apex_y, c, a); n1.SetNeighbor(nx, xab); n2.SetNeighbor(nx, xbc); n3.SetNeighbor(nx, xca); n1.SetNeighbor(ny, yab); n2.SetNeighbor(ny, ybc); n3.SetNeighbor(ny, yca); return(xab, xbc, xca, yab, ybc, yca, nx, ny); }
public bool Contains(d3 p, bool includeOnFacet) { var f1 = tris[0].IsSameSide(d, p, includeOnFacet); var f2 = tris[1].IsSameSide(a, p, includeOnFacet); var f3 = tris[2].IsSameSide(b, p, includeOnFacet); var f4 = tris[3].IsSameSide(c, p, includeOnFacet); return(f1 && f2 && f3 && f4); }
public GpuData(int index, int order, T val, d3 block, d3 thread, object ext = null) { Index = index; Order = order; Value = val; Block = block; Thread = thread; Ext = ext; }
public Triangle(d3 p1, d3 p2, d3 p3) { if (Equals(p1, p2) || Equals(p2, p3) || Equals(p3, p1)) { throw new Exception(); } this.a = p1; this.b = p2; this.c = p3; }
public bool Intersects(Line l, out d3 p, out bool isOnEdge) { if (!CramersLow(l.pos, l.vec, out d3 d, out p)) { isOnEdge = default; return(false); } isOnEdge = d.x == 0 || d.x == 1 || d.y == 0 || d.y == 1 || d.x + d.y == 1; return(d.x >= 0 && d.x <= 1 && d.y >= 0 && d.y <= 1 && d.x + d.y <= 1); }
public void TestKernelNoTile() { var blockCount = new d3(4); var threadCount = new d3(2); var arrayOut = new GpuArrayWrite <int>(blockCount.Volume() * threadCount.Volume()); GpuDevice.RunGpuKernel( blockCount, threadCount, TestKernels.IntKernelWrap(arrayOut, blockCount, threadCount)); }
public bool Intersects(SG e, out d3 p, out bool isOnEdge) { if (!CramersLow(e.a, normalize(e.b - e.a), out d3 d, out p)) { isOnEdge = default; return(false); } bool f1 = d.x >= 0 && d.x <= 1 && d.y >= 0 && d.y <= 1 && d.x + d.y <= 1; bool f2 = d.z >= 0 && d.z <= length(e.b - e.a); isOnEdge = d.x == 0 || d.x == 1 || d.y == 0 || d.y == 1 || d.x + d.y == 1; return(f1 && f2); }
void Split(d3 p) { var n = nodes.Find(_t => _t.tetrahedra.Contains(p, true)); var o = n.Split(p); nodes.Remove(n); nodes.Add(o.n1); nodes.Add(o.n2); nodes.Add(o.n3); nodes.Add(o.n4); stack.Push(o.t1); stack.Push(o.t2); stack.Push(o.t3); stack.Push(o.t4); }
int GetType(d3 p) { var v = dot(n, p) - w; var isNearPlane = abs(v) < EPSILON; var isFacingSide = v > 0; if (isNearPlane) { return(ONPLANE); } else { return(isFacingSide ? FACE : BACK); } }
public Tetrahedra(d3 a, d3 b, d3 c, d3 d) { this.vrts = new d34(a, b, c, d); this.tris = new TR[] { new TR(a, b, c), new TR(b, c, d), new TR(c, d, a), new TR(d, a, b) }; if (Equals(a, b) || Equals(a, c) || Equals(a, d) || Equals(b, c) || Equals(b, d) || Equals(c, d)) { throw new Exception(); } }
public SG Remaining(d3 p) { if (p.Equals(a)) { return(new SG(b, c)); } if (p.Equals(b)) { return(new SG(c, a)); } if (p.Equals(c)) { return(new SG(a, b)); } throw new Exception(); }
public bool HasPoint(d3 p) { if (p.Equals(a)) { return(true); } if (p.Equals(b)) { return(true); } if (p.Equals(c)) { return(true); } if (p.Equals(d)) { return(true); } return(false); }
static void IsIntersecting(SG e1, SG e2, out bool flag, out d3 pos, double threshold) { var v1 = e1.b - e1.a; var v2 = e2.b - e2.a; var n1 = normalize(v1); var n2 = normalize(v2); var alpha = dot(n1, n2); var r = e1.a - e2.a; var rho = dot(r, n1 - alpha * n2) / (alpha * alpha - 1d); var tau = dot(r, alpha * n1 - n2) / (alpha * alpha - 1d); var pos1 = e1.a + rho * n1; var pos2 = e2.a + tau * n2; var f1 = lengthsq(pos1 - pos2) < threshold; var _rho = rho / length(v1); var _tau = tau / length(v2); var f2 = _rho >= 0d && _rho <= 1d && _tau >= 0d && _tau <= 1d; flag = f1 && f2; pos = pos2; }
bool CramersLow(d3 ogn, d3 ray, out d3 det, out d3 pos) { // using cramer's rule var e1 = b - a; var e2 = c - a; var denominator = determinant(double3x3(e1, e2, -ray)); if (denominator == 0) { Debug.LogWarning("parallele"); det = default; pos = default; return(false); } var d = ogn - a; var u = determinant(double3x3(d, e2, -ray)) / denominator; var v = determinant(double3x3(e1, d, -ray)) / denominator; var t = determinant(double3x3(e1, e2, d)) / denominator; pos = ogn + ray * t; det = new d3(u, v, t); return(true); }
Flip23(DN n1, DN n2, d3 p1, d3 p2, TR t) { DN nab = new DN(p1, p2, t.a, t.b); DN nbc = new DN(p1, p2, t.b, t.c); DN nca = new DN(p1, p2, t.c, t.a); nab.neighbor = new List <DN> { nbc, nca }; nbc.neighbor = new List <DN> { nca, nab }; nca.neighbor = new List <DN> { nab, nbc }; TR t_ab_p1 = new TR(t.a, t.b, p1); n1.SetNeighbor(nab, t_ab_p1); TR t_ab_p2 = new TR(t.a, t.b, p2); n2.SetNeighbor(nab, t_ab_p2); TR t_bc_p1 = new TR(t.b, t.c, p1); n1.SetNeighbor(nbc, t_bc_p1); TR t_bc_p2 = new TR(t.b, t.c, p2); n2.SetNeighbor(nbc, t_bc_p2); TR t_ca_p1 = new TR(t.c, t.a, p1); n1.SetNeighbor(nca, t_ca_p1); TR t_ca_p2 = new TR(t.c, t.a, p2); n2.SetNeighbor(nca, t_ca_p2); return(t_ab_p1, t_ab_p2, t_bc_p1, t_bc_p2, t_ca_p1, t_ca_p2, nab, nbc, nca); }
public DelaunayGraphNode3D(d3 a, d3 b, d3 c, d3 d) { tetrahedra = new Tetrahedra(a, b, c, d); neighbor = new List <DN>(4); }
public bool Contains(d3 p, bool inclusive) => tetrahedra.Contains(p, inclusive);
public bool HasVert(d3 p) => p.Equals(a) || p.Equals(b) || p.Equals(c);
public Triangle(SG s, d3 p) : this(s.a, s.b, p) { }
public Plane(d3 a, d3 b, d3 c) { n = normalize(cross(b - a, c - a)); w = dot(n, a); }
public bool IsSameSide(d3 p1, d3 p2, bool includeOnPlane) { double d = dot(n, p1 - a) * dot(n, p2 - a); return(includeOnPlane ? d >= 0 : d > 0); }