// 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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
 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);
 }
Esempio n. 9
0
        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));
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 13
0
        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();
            }
        }
Esempio n. 14
0
 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();
 }
Esempio n. 15
0
 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);
 }
Esempio n. 16
0
        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;
        }
Esempio n. 17
0
        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);
Esempio n. 21
0
 public bool HasVert(d3 p) => p.Equals(a) || p.Equals(b) || p.Equals(c);
Esempio n. 22
0
 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);
 }
Esempio n. 24
0
        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);
        }