Пример #1
0
        Triangle GetAdjacent(DelaunayPoint start, DelaunayPoint end)
        {
            double t = 0;
            double s = SegmentsIntersect(m_v[0], m_v[1], start, end, t);

            if (t >= 0 && t <= 1 && s >= 0 && s <= 1)
            {
                return(adjacentFace[0]);
            }

            s = SegmentsIntersect(m_v[1], m_v[2], start, end, t);

            if (t >= 0 && t <= 1 && s >= 0 && s <= 1)
            {
                return(adjacentFace[1]);
            }

            s = SegmentsIntersect(m_v[2], m_v[0], start, end, t);

            if (t >= 0 && t <= 1 && s >= 0 && s <= 1)
            {
                return(adjacentFace[2]);
            }

            return(null);
        }
Пример #2
0
        float SegmentsIntersect(DelaunayPoint a, DelaunayPoint b, DelaunayPoint c, DelaunayPoint d, double t)
        {
            //what if denominator is zero??
            double diff0 = (c.Y - a.Y) * MULTIPLIER;
            double diff1 = (d.X - c.X) * MULTIPLIER;
            double diff2 = (a.X - c.X) * MULTIPLIER;
            double diff3 = (d.Y - c.Y) * MULTIPLIER;
            double diff4 = (b.Y - a.Y) * MULTIPLIER;
            double diff5 = (b.X - a.X) * MULTIPLIER;

            t = (diff0 * diff1 + diff2 * diff3) / (diff4 * diff1 - diff5 * diff3);
            double s = (-diff2 * diff4 - diff0 * diff5) / (diff3 * diff5 - diff1 * diff4);

            if (Math.Abs(t) <= VERY_SMALL_DIST)
            {
                t = 0;
            }

            if (Math.Abs(s) <= VERY_SMALL_DIST)
            {
                s = 0;
            }

            return((float)s);
        }
Пример #3
0
        bool IsClose(DelaunayPoint p, double maxDistance)
        {
            if (m_norm == 0)
            {
                ComputePlaneParams();
            }

            double dist = Math.Abs((m_a * p.X + m_b * p.Y + m_c * p.Z + m_d) / m_norm);

            return(dist <= maxDistance);
        }
Пример #4
0
 private void ForceClockwise()
 {
     if (DelaunayGeometry.CrossProduct(m_v[0], m_v[1], m_v[2]) >= 0)
     {
         // a positive value indicates counter clockwise
         // Swapping the first 2 points should be enough
         DelaunayPoint tmp = m_v[0];
         m_v[0] = m_v[1];
         m_v[1] = tmp;
     }
 }
Пример #5
0
        bool LocateInternalUsingTriangleList(IEnumerable <Triangle> triangles, DelaunayPoint p)
        {
            foreach (Triangle triangle in triangles)
            {
                if (LocateInternal(triangle, p) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #6
0
        bool LocateInternal(DelaunayPoint p)
        {
            if (m_currentTriangle != null)
            {
                Triangle newTriangle = LocateInternal(m_currentTriangle, p);
                if (newTriangle != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #7
0
        public Triangle(DelaunayPoint v1, DelaunayPoint v2, DelaunayPoint v3)
        {
            m_v = new DelaunayPoint[] { v1, v2, v3 };

            ForceClockwise();

            adjacentFace = new Triangle[3];

            centroidX = (float)(v1.X + v2.X + v3.X) / 3.0f;
            centroidY = (float)(v1.Y + v2.Y + v3.Y) / 3.0f;

            m_extent = new Extent2D(m_v[0], m_v[1], m_v[2]);
        }
Пример #8
0
        public bool Contains(DelaunayPoint p)
        {
            // Only bother to check if the point is within the initial extents of the Triangle_t
            if (m_extent.Contains(p.X, p.Y, true))
            {
                return (
                    (DelaunayGeometry.CrossProduct(m_v[0], p, m_v[1]) >= 0.0) &&
                    (DelaunayGeometry.CrossProduct(m_v[1], p, m_v[2]) >= 0.0) &&
                    (DelaunayGeometry.CrossProduct(m_v[2], p, m_v[0]) >= 0.0));
            }

            return false;
        }
Пример #9
0
        public Triangle(DelaunayPoint v1, DelaunayPoint v2, DelaunayPoint v3)
        {
            m_v = new DelaunayPoint[] { v1, v2, v3 };

            ForceClockwise();

            adjacentFace = new Triangle[3];

            centroidX = (float)(v1.X + v2.X + v3.X) / 3.0f;
            centroidY = (float)(v1.Y + v2.Y + v3.Y) / 3.0f;

            m_extent = new Extent2D(m_v[0], m_v[1], m_v[2]);
        }
Пример #10
0
        public bool Contains(DelaunayPoint p)
        {
            // Only bother to check if the point is within the initial extents of the Triangle_t
            if (m_extent.Contains(p.X, p.Y, true))
            {
                return(
                    (DelaunayGeometry.CrossProduct(m_v[0], p, m_v[1]) >= 0.0) &&
                    (DelaunayGeometry.CrossProduct(m_v[1], p, m_v[2]) >= 0.0) &&
                    (DelaunayGeometry.CrossProduct(m_v[2], p, m_v[0]) >= 0.0));
            }

            return(false);
        }
Пример #11
0
        public bool IsCoincidentWithVertex(DelaunayPoint p)
        {
            double distA = (m_v[0].X - p.X) * (m_v[0].X - p.X) + (m_v[0].Y - p.Y) * (m_v[0].Y - p.Y);
            double distB = (m_v[1].X - p.X) * (m_v[1].X - p.X) + (m_v[1].Y - p.Y) * (m_v[1].Y - p.Y);
            double distC = (m_v[2].X - p.X) * (m_v[2].X - p.X) + (m_v[2].Y - p.Y) * (m_v[2].Y - p.Y);

            if ((distA <= VERY_SMALL_DIST) || (distB <= VERY_SMALL_DIST) || (distC <= VERY_SMALL_DIST))
            {
                return(true);
            }

            return(false);
        }
Пример #12
0
        bool LocateInternalBruteForce(DelaunayPoint p)
        {
            m_currentTriangle = null;

            foreach (Triangle triangle in m_newTriangles)
            {
                if (triangle.Contains(p))
                {
                    m_currentTriangle = triangle;
                    return(true);
                }
            }

            return(false);
        }
Пример #13
0
        ////use this only for direction and nothing else
        public static float CrossProduct(DelaunayPoint p, DelaunayPoint a, DelaunayPoint b)
        {
            // FUTURE: Migrate this into a more appropriate place.
            //use the multiplier for making sure we handle small numbers correctly
            double diffax = (double)a.X - p.X;
            double diffay = (double)a.Y - p.Y;
            double diffbx = (double)b.X - p.X;
            double diffby = (double)b.Y - p.Y;

            double cross = (diffax * diffby - diffbx * diffay);

            if (cross >= 1.0e-12 || cross <= -1.0e-12)
                return (float)cross;

            return 0.0f;
        }
Пример #14
0
        public bool UpdateTriangle(DelaunayPoint p)
        {
            if (m_currentTriangle == null)
            {
                return(false);
            }

            if (m_currentTriangle.IsCoincidentWithVertex(p))
            {
                return(false);
            }

            Update(p);

            return(true);
        }
Пример #15
0
        public static Extent2D Circumcircle(DelaunayPoint v1, DelaunayPoint v2, DelaunayPoint v3, double cx, double cy)
        {
            const double ERROR_BOUND = 0.005;

            //http://mathworld.wolfram.com/Circumcircle.html
            double x1 = v1.X;
            double x2 = v2.X;
            double x3 = v3.X;
            double y1 = v1.Y;
            double y2 = v2.Y;
            double y3 = v3.Y;

            double x1Sq = x1 * x1;
            double x2Sq = x2 * x2;
            double x3Sq = x3 * x3;
            double y1Sq = y1 * y1;
            double y2Sq = y2 * y2;
            double y3Sq = y3 * y3;

            double a  = (x1 - x2) * (y2 - y3) - (y1 - y2) * (x2 - x3);
            double bx = -((x1Sq + y1Sq - x2Sq - y2Sq) * (y2 - y3) - (x2Sq + y2Sq - x3Sq - y3Sq) * (y1 - y2));
            double by = ((x1Sq + y1Sq - x2Sq - y2Sq) * (x2 - x3) - (x2Sq + y2Sq - x3Sq - y3Sq) * (x1 - x2));
            double c  = -((x1Sq + y1Sq) * (x2 * y3 - x3 * y2) - (x2Sq + y2Sq) * (x1 * y3 - x3 * y1) + (x3Sq + y3Sq) * (x1 * y2 - x2 * y1));

            Extent2D extent = null;

            if (a == 0.0f)
            {
                extent = new Extent2D(cx - ERROR_BOUND, cx + ERROR_BOUND, cy - ERROR_BOUND, cy + ERROR_BOUND);
            }
            else
            {
                double x0        = -bx / (2.0f * a);
                double y0        = -by / (2.0f * a);
                double numerator = bx * bx + by * by - 4.0f * a * c;

                double rad = 0;
                if (numerator >= 0)
                {
                    rad = Math.Sqrt(numerator) / (2.0f * Math.Abs(a));
                }

                extent = new Extent2D(x0 - rad - ERROR_BOUND, x0 + rad + ERROR_BOUND, y0 - rad - ERROR_BOUND, y0 + rad + ERROR_BOUND);
            }
            return(extent);
        }
Пример #16
0
        // Returns true if the point is contained in the triangle otherwise returns false
        // if false then ref is the next triangle
        public bool Contains(DelaunayPoint p, ref Triangle next)
        {
            //unrolled the dot product logic for optimization
            // a refers to point m_v[0]
            // b refers to point m_v[1]
            // c refers to point m_v[1]
            // p is the point
            double diffax = (m_v[0].X - p.X);
            double diffay = (m_v[0].Y - p.Y);
            double diffcx = (m_v[2].X - p.X);
            double diffcy = (m_v[2].Y - p.Y);

            double aXc = (diffax * diffcy - diffcx * diffay);

            if (aXc < 0.0)            // if negative point is outside of edge a,c
            {
                next = adjacentFace[2];
                return(false);
            }
            else
            {
                double diffbx = (m_v[1].X - p.X);
                double diffby = (m_v[1].Y - p.Y);

                double cXb = (diffcx * diffby - diffbx * diffcy);


                if (cXb < 0.0)                // if
                {
                    next = adjacentFace[1];
                    return(false);
                }
                else
                {
                    double bXa = (diffbx * diffay - diffax * diffby);
                    if (bXa < 0.0)
                    {
                        next = adjacentFace[0];
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #17
0
        ////use this only for direction and nothing else
        public static float CrossProduct(DelaunayPoint p, DelaunayPoint a, DelaunayPoint b)
        {
            // FUTURE: Migrate this into a more appropriate place.
            //use the multiplier for making sure we handle small numbers correctly
            double diffax = (double)a.X - p.X;
            double diffay = (double)a.Y - p.Y;
            double diffbx = (double)b.X - p.X;
            double diffby = (double)b.Y - p.Y;

            double cross = (diffax * diffby - diffbx * diffay);

            if (cross >= 1.0e-12 || cross <= -1.0e-12)
            {
                return((float)cross);
            }

            return(0.0f);
        }
Пример #18
0
        public static Extent2D Circumcircle(DelaunayPoint v1, DelaunayPoint v2, DelaunayPoint v3, double cx, double cy)
        {
            const double ERROR_BOUND = 0.005;

            //http://mathworld.wolfram.com/Circumcircle.html
            double x1 = v1.X;
            double x2 = v2.X;
            double x3 = v3.X;
            double y1 = v1.Y;
            double y2 = v2.Y;
            double y3 = v3.Y;

            double x1Sq = x1 * x1;
            double x2Sq = x2 * x2;
            double x3Sq = x3 * x3;
            double y1Sq = y1 * y1;
            double y2Sq = y2 * y2;
            double y3Sq = y3 * y3;

            double a = (x1 - x2) * (y2 - y3) - (y1 - y2) * (x2 - x3);
            double bx = -((x1Sq + y1Sq - x2Sq - y2Sq) * (y2 - y3) - (x2Sq + y2Sq - x3Sq - y3Sq) * (y1 - y2));
            double by = ((x1Sq + y1Sq - x2Sq - y2Sq) * (x2 - x3) - (x2Sq + y2Sq - x3Sq - y3Sq) * (x1 - x2));
            double c = -((x1Sq + y1Sq) * (x2 * y3 - x3 * y2) - (x2Sq + y2Sq) * (x1 * y3 - x3 * y1) + (x3Sq + y3Sq) * (x1 * y2 - x2 * y1));

            Extent2D extent = null;

            if (a == 0.0f)
            {
                extent = new Extent2D(cx - ERROR_BOUND, cx + ERROR_BOUND, cy - ERROR_BOUND, cy + ERROR_BOUND);
            }
            else
            {
                double x0 = -bx / (2.0f * a);
                double y0 = -by / (2.0f * a);
                double numerator = bx * bx + by * by - 4.0f * a * c;

                double rad = 0;
                if (numerator >= 0)
                    rad = Math.Sqrt(numerator) / (2.0f * Math.Abs(a));

                extent = new Extent2D(x0 - rad - ERROR_BOUND, x0 + rad + ERROR_BOUND, y0 - rad - ERROR_BOUND, y0 + rad + ERROR_BOUND);
            }
            return extent;
        }
Пример #19
0
        public bool CircumCircleContains(DelaunayPoint p)
        {
            // http://www.cs.cmu.edu/~quake/robust.html
            double a1 = (double)m_v[0].X - p.X;
            double a2 = (double)m_v[0].Y - p.Y;
            double a3 = a1*a1 + a2*a2;

            double b1 = (double)m_v[1].X - p.X;
            double b2 = (double)m_v[1].Y - p.Y;
            double b3 = b1*b1 + b2*b2;

            double c1 = (double)m_v[2].X - p.X;
            double c2 = (double)m_v[2].Y - p.Y;
            double c3 = c1*c1 + c2*c2;

            double det = a1 * (b2 * c3 - b3 * c2) - a2 * (b1 * c3 - b3 * c1) + a3 * (b1 * c2 - b2 * c1);

            return !(det >= double.Epsilon);
        }
Пример #20
0
        public bool Locate(DelaunayPoint p)
        {
            // Attempt to walk to the triangle.
            if (LocateInternal(p))
            {
                return(true);
            }
            else
            {
                //// Attempt to walk to the triangle using the cell's boundary triangles.
                //if(LocateInternalUsingTriangleList(cell->BoundaryTriangles(), p))
                //{
                //    return true;
                //}

                // Last ditch effort to find the triangle looking through memory -- O(n)
                return(LocateInternalBruteForce(p));
            }
        }
Пример #21
0
        public bool Locate(DelaunayPoint p)
        {
            // Attempt to walk to the triangle.
            if(LocateInternal(p))
            {
                return true;
            }
            else
            {
                //// Attempt to walk to the triangle using the cell's boundary triangles.
                //if(LocateInternalUsingTriangleList(cell->BoundaryTriangles(), p))
                //{
                //    return true;
                //}

                // Last ditch effort to find the triangle looking through memory -- O(n)
                return LocateInternalBruteForce(p);
            }
        }
Пример #22
0
        public bool CircumCircleContains(DelaunayPoint p)
        {
            // http://www.cs.cmu.edu/~quake/robust.html
            double a1 = (double)m_v[0].X - p.X;
            double a2 = (double)m_v[0].Y - p.Y;
            double a3 = a1 * a1 + a2 * a2;

            double b1 = (double)m_v[1].X - p.X;
            double b2 = (double)m_v[1].Y - p.Y;
            double b3 = b1 * b1 + b2 * b2;

            double c1 = (double)m_v[2].X - p.X;
            double c2 = (double)m_v[2].Y - p.Y;
            double c3 = c1 * c1 + c2 * c2;

            double det = a1 * (b2 * c3 - b3 * c2) - a2 * (b1 * c3 - b3 * c1) + a3 * (b1 * c2 - b2 * c1);

            return(!(det >= double.Epsilon));
        }
Пример #23
0
        void FreeTriangle(Triangle t, bool flush)
        {
            if (t == null)
            {
                //should never come here, maybe the last ones
                return;
            }

            //make sure we arent deleting the m_currentTriangle
            if (m_currentTriangle == t)
            {
                m_currentTriangle = null;
            }

            // TODO: Encapsulate this later if triangles reference edges/vertices via shared_ptr.
            DelaunayPoint v1 = t.m_v[0];
            DelaunayPoint v2 = t.m_v[1];
            DelaunayPoint v3 = t.m_v[2];

            if (flush)
            {
                bool isSuperTriangleVertex = false;
                for (int i = 0; i < 3; i++)
                {
                    DelaunayPoint v = t.m_v[i];
                    if (v == m_superA || v == m_superB || v == m_superC)
                    {
                        isSuperTriangleVertex = true;
                        break;
                    }
                }

                if (!isSuperTriangleVertex)
                {
                    m_outputTriangles.Add(v1.Index);
                    m_outputTriangles.Add(v2.Index);
                    m_outputTriangles.Add(v3.Index);
                }
            }

            //m_trianglesMemoryManager.dealloc(*t);
        }
Пример #24
0
        Triangle LocateInternal(Triangle startTriangle, DelaunayPoint end)
        {
            int step = 0;

            //first check if the point is in the current Triangle_t
            while ((startTriangle != null) && !startTriangle.Contains(end, ref startTriangle) && (++step) <= NUM_STEPS_TO_LOCATE)
            {
            }

            if (step > NUM_STEPS_TO_LOCATE)
            {
                startTriangle = null;
            }

            if (startTriangle == null)
            {
                return(null);
            }

            m_currentTriangle = startTriangle;
            return(m_currentTriangle);
        }
Пример #25
0
        public void Initialize(Extent3D extent, int numPointsToProcess)
        {
            double SQRT3 = Math.Sqrt(3);

            //create one big Triangle_t aka. supertriangle
            //Make the bounding box slightly bigger,
            //actually no need for this if coming from streaming delaunay side

            m_extent = extent;

            // compute the supertriangle vertices, clockwise order, check the math
            m_superA = new DelaunayPoint(extent.MinX - extent.RangeY * SQRT3 / 3.0f, extent.MinY, extent.MinZ, numPointsToProcess);
            m_superB = new DelaunayPoint(extent.MidpointX, extent.MaxY + extent.RangeX * SQRT3 * 0.5f, extent.MinZ, numPointsToProcess + 1);
            m_superC = new DelaunayPoint(extent.MaxX + extent.RangeY * SQRT3 / 3.0f, extent.MinY, extent.MinZ, numPointsToProcess + 2);

            //create the super Triangle_t
            m_delaunayGraph = new Triangle(m_superA, m_superB, m_superC);

            //keep track of the current Triangle_t
            m_currentTriangle = m_delaunayGraph;

            m_newTriangles = new List<Triangle>();
            m_outputTriangles = new List<int>();
        }
Пример #26
0
        public void Initialize(Extent3D extent, int numPointsToProcess)
        {
            double SQRT3 = Math.Sqrt(3);

            //create one big Triangle_t aka. supertriangle
            //Make the bounding box slightly bigger,
            //actually no need for this if coming from streaming delaunay side

            m_extent = extent;

            // compute the supertriangle vertices, clockwise order, check the math
            m_superA = new DelaunayPoint(extent.MinX - extent.RangeY * SQRT3 / 3.0f, extent.MinY, extent.MinZ, numPointsToProcess);
            m_superB = new DelaunayPoint(extent.MidpointX, extent.MaxY + extent.RangeX * SQRT3 * 0.5f, extent.MinZ, numPointsToProcess + 1);
            m_superC = new DelaunayPoint(extent.MaxX + extent.RangeY * SQRT3 / 3.0f, extent.MinY, extent.MinZ, numPointsToProcess + 2);

            //create the super Triangle_t
            m_delaunayGraph = new Triangle(m_superA, m_superB, m_superC);

            //keep track of the current Triangle_t
            m_currentTriangle = m_delaunayGraph;

            m_newTriangles    = new List <Triangle>();
            m_outputTriangles = new List <int>();
        }
Пример #27
0
        bool LocateInternalBruteForce(DelaunayPoint p)
        {
            m_currentTriangle = null;

            foreach (Triangle triangle in m_newTriangles)
            {
                if (triangle.Contains(p))
                {
                    m_currentTriangle = triangle;
                    return true;
                }
            }

            return false;
        }
Пример #28
0
        Triangle LocateInternal(Triangle startTriangle, DelaunayPoint end)
        {
            int step = 0;

            //first check if the point is in the current Triangle_t
            while((startTriangle != null) && !startTriangle.Contains(end, ref startTriangle) && (++step) <= NUM_STEPS_TO_LOCATE)
            {
            }

            if(step > NUM_STEPS_TO_LOCATE)
                startTriangle = null;

            if(startTriangle == null)
                return null;

            m_currentTriangle = startTriangle;
            return m_currentTriangle;
        }
Пример #29
0
        bool LocateInternal(DelaunayPoint p)
        {
            if(m_currentTriangle != null)
            {
                Triangle newTriangle = LocateInternal(m_currentTriangle, p);
                if(newTriangle != null)
                    return true;
            }

            return false;
        }
Пример #30
0
        public bool UpdateTriangle(DelaunayPoint p)
        {
            if (m_currentTriangle == null)
                return false;

            if (m_currentTriangle.IsCoincidentWithVertex(p))
                return false;

            Update(p);

            return true;
        }
Пример #31
0
        bool IsClose(DelaunayPoint p, double maxDistance)
        {
            if (m_norm == 0)
                ComputePlaneParams();

            double dist = Math.Abs((m_a * p.X + m_b * p.Y + m_c * p.Z + m_d) / m_norm);
            return (dist <= maxDistance);
        }
Пример #32
0
        // Returns true if the point is contained in the triangle otherwise returns false
        // if false then ref is the next triangle
        public bool Contains(DelaunayPoint p, ref Triangle next)
        {
            //unrolled the dot product logic for optimization
            // a refers to point m_v[0]
            // b refers to point m_v[1]
            // c refers to point m_v[1]
            // p is the point
            double diffax = (m_v[0].X - p.X);
            double diffay = (m_v[0].Y - p.Y);
            double diffcx = (m_v[2].X - p.X);
            double diffcy = (m_v[2].Y - p.Y);

            double aXc = (diffax * diffcy - diffcx * diffay);

            if(aXc < 0.0) // if negative point is outside of edge a,c
            {
                next = adjacentFace[2];
                return false;
            }
            else
            {
                double diffbx = (m_v[1].X - p.X);
                double diffby = (m_v[1].Y - p.Y);

                double cXb = (diffcx * diffby - diffbx * diffcy);

                if(cXb < 0.0) // if
                {
                    next = adjacentFace[1];
                    return false;
                }
                else
                {
                    double bXa = (diffbx * diffay - diffax * diffby);
                    if(bXa < 0.0)
                    {
                        next = adjacentFace[0];
                        return false;
                    }
                }
            }

            return true;
        }
Пример #33
0
        bool Overlaps(Extent2D extent)
        {
            // Check simplist case - triangle inside extent.
            if (extent.Contains(m_extent))
            {
                return(true);
            }

            // Use right-hand rule for each triangle segment against all points of extent rectangle.
            DelaunayPoint p1 = new DelaunayPoint(extent.MinX, extent.MinY, 0.0f, 0);
            DelaunayPoint p2 = new DelaunayPoint(extent.MaxX, extent.MinY, 0.0f, 0);
            DelaunayPoint p3 = new DelaunayPoint(extent.MaxX, extent.MaxY, 0.0f, 0);
            DelaunayPoint p4 = new DelaunayPoint(extent.MinX, extent.MaxY, 0.0f, 0);

            int ar = 0;

            if (DelaunayGeometry.CrossProduct(m_v[0], p1, m_v[1]) >= 0.0f)
            {
                ++ar;
            }
            if (DelaunayGeometry.CrossProduct(m_v[0], p2, m_v[1]) >= 0.0f)
            {
                ++ar;
            }
            if (DelaunayGeometry.CrossProduct(m_v[0], p3, m_v[1]) >= 0.0f)
            {
                ++ar;
            }
            if (DelaunayGeometry.CrossProduct(m_v[0], p4, m_v[1]) >= 0.0f)
            {
                ++ar;
            }

            int br = 0;

            if (DelaunayGeometry.CrossProduct(m_v[1], p1, m_v[2]) >= 0.0f)
            {
                ++br;
            }
            if (DelaunayGeometry.CrossProduct(m_v[1], p2, m_v[2]) >= 0.0f)
            {
                ++br;
            }
            if (DelaunayGeometry.CrossProduct(m_v[1], p3, m_v[2]) >= 0.0f)
            {
                ++br;
            }
            if (DelaunayGeometry.CrossProduct(m_v[1], p4, m_v[2]) >= 0.0f)
            {
                ++br;
            }

            int cr = 0;

            if (DelaunayGeometry.CrossProduct(m_v[2], p1, m_v[0]) >= 0.0f)
            {
                ++cr;
            }
            if (DelaunayGeometry.CrossProduct(m_v[2], p2, m_v[0]) >= 0.0f)
            {
                ++cr;
            }
            if (DelaunayGeometry.CrossProduct(m_v[2], p3, m_v[0]) >= 0.0f)
            {
                ++cr;
            }
            if (DelaunayGeometry.CrossProduct(m_v[2], p4, m_v[0]) >= 0.0f)
            {
                ++cr;
            }

            // There will be some sort intersection of triangle with rectangle if at least one point of
            // the rectangle is on, or to the right (not zero) of every segment of the triangle.
            if (ar != 0 && br != 0 && cr != 0)
            {
                return(true);
            }

            return(false);
        }
Пример #34
0
        void Update(DelaunayPoint p)
        {
            List <Triangle> removeList  = new List <Triangle>();
            List <Triangle> visitedList = new List <Triangle>();

            // Go in dfs order and keep adding triangles to it until the vertices of Triangle dont fall in the circumcircle
            m_currentTriangle.remove  = true;
            m_currentTriangle.visited = true;
            removeList.Add(m_currentTriangle);

            for (int start = 0; start != removeList.Count; ++start)
            {
                // All triangles with circumcircle containing the point will need to be removed.
                Triangle remTriangle = removeList[start];
                for (int k = 0; k < 3; k++)
                {
                    Triangle adjacentTriangle = remTriangle.adjacentFace[k];
                    if (adjacentTriangle != null && !adjacentTriangle.visited)
                    {
                        adjacentTriangle.visited = true;

                        if (adjacentTriangle.CircumCircleContains(p))
                        {
                            adjacentTriangle.remove = true;
                            removeList.Add(adjacentTriangle);                             //holds a list of removeable Triangle_t
                        }
                        else
                        {
                            visitedList.Add(adjacentTriangle);
                        }
                    }
                }
            }

            if (visitedList.Count > 0)
            {
                for (int i = 0; i < visitedList.Count; i++)
                {
                    visitedList[i].visited = false;
                }
            }
            visitedList.Clear();

            // For every n triangles we are going to remove we should be able to add n+2 new ones
            int numNewTriangles = 0;

            for (int i = 0; i != removeList.Count; i++)
            {
                Triangle remTriangle = removeList[i];
                for (int j = 0; j != 3; j++)
                {
                    // Create a Triangle for each side that isnt to be removed.
                    if (remTriangle.adjacentFace[j] == null)
                    {
                        numNewTriangles++;
                    }
                    else if (!remTriangle.adjacentFace[j].remove)
                    {
                        numNewTriangles++;
                    }
                }
            }

            // Paranoia check.
            if (numNewTriangles - 2 != removeList.Count)
            {
                // Don't expect to hit this, but checking anyways just in case of rounding errors.
                for (int i = 0; i != removeList.Count; i++)
                {
                    removeList[i].visited = false;
                    removeList[i].remove  = false;
                }

                return;
            }

            // Create new triangles.
            List <Triangle> newList = new List <Triangle>();

            int[] vertIndex = new int[] { 1, 2, 0 };

            for (int i = 0; i != removeList.Count; i++)
            {
                Triangle remTriangle = removeList[i];
                for (int j = 0; j < 3; j++)
                {
                    //create a Triangle for each side that isnt to be removed
                    Triangle adjacent = remTriangle.adjacentFace[j];
                    if (adjacent == null)
                    {
                        Triangle t = new Triangle(remTriangle.m_v[j], remTriangle.m_v[vertIndex[j]], p);
                        newList.Add(t);
                    }
                    else if (!adjacent.remove)
                    {
                        Triangle t = new Triangle(remTriangle.m_v[j], remTriangle.m_v[vertIndex[j]], p);

                        // Stitch shared edge of new triangle into existing network.
                        t.adjacentFace[0] = adjacent;
                        for (int e = 0; e != 3; e++)
                        {
                            if (adjacent.adjacentFace[e] == remTriangle)
                            {
                                adjacent.adjacentFace[e] = t;
                            }
                        }

                        newList.Add(t);
                    }
                }
            }

            // Stitch up the new triangles with each-other.  Simplified case because vertex[2] for all shared triangles is the same, and is
            // in fact parameter point 'p'.
            m_currentTriangle = null;
            for (int i = 0; i != newList.Count; i++)
            {
                Triangle t = newList[i];
                m_currentTriangle = t;

                // Iterate over other un-stitched edges looking for a match.
                for (int j = i + 1; (j != newList.Count) && ((t.adjacentFace[1] == null) || (t.adjacentFace[2] == null)); j++)
                {
                    Triangle q = newList[j];
                    if (t.adjacentFace[1] == null)
                    {
                        if (t.m_v[1] == q.m_v[0])
                        {
                            t.adjacentFace[1] = q;
                            q.adjacentFace[2] = t;
                        }
                    }

                    if (t.adjacentFace[2] == null)
                    {
                        if (t.m_v[0] == q.m_v[1])
                        {
                            t.adjacentFace[2] = q;
                            q.adjacentFace[1] = t;
                        }
                    }
                }
            }

            // Free triangles that were to be removed.
            for (int i = 0; i != removeList.Count; i++)
            {
                Triangle cur = removeList[i];
                m_newTriangles.Remove(cur);
                FreeTriangle(cur, false);
            }

            // Add new triangles for later consideration & processing.
            for (int i = 0; i != newList.Count; ++i)
            {
                m_newTriangles.Add(newList[i]);
            }
        }
Пример #35
0
        bool LocateInternalUsingTriangleList(IEnumerable<Triangle> triangles, DelaunayPoint p)
        {
            foreach(Triangle triangle in triangles)
            {
                if (LocateInternal(triangle, p) != null)
                    return true;
            }

            return false;
        }
Пример #36
0
        float SegmentsIntersect(DelaunayPoint a, DelaunayPoint b, DelaunayPoint c, DelaunayPoint d, double t)
        {
            //what if denominator is zero??
            double diff0 = (c.Y - a.Y) * MULTIPLIER;
            double diff1 = (d.X - c.X) * MULTIPLIER;
            double diff2 = (a.X - c.X) * MULTIPLIER;
            double diff3 = (d.Y - c.Y) * MULTIPLIER;
            double diff4 = (b.Y - a.Y) * MULTIPLIER;
            double diff5 = (b.X - a.X) * MULTIPLIER;

            t = (diff0 * diff1 + diff2 * diff3) / (diff4 * diff1 - diff5 * diff3);
            double s = (-diff2 * diff4 - diff0 * diff5) /(diff3 * diff5 - diff1 * diff4);

            if(Math.Abs(t) <= VERY_SMALL_DIST)
                t = 0;

            if(Math.Abs(s) <= VERY_SMALL_DIST)
                s = 0;

            return (float)s;
        }
Пример #37
0
        void Update(DelaunayPoint p)
        {
            List<Triangle> removeList = new List<Triangle>();
            List<Triangle> visitedList = new List<Triangle>();

            // Go in dfs order and keep adding triangles to it until the vertices of Triangle dont fall in the circumcircle
            m_currentTriangle.remove = true;
            m_currentTriangle.visited = true;
            removeList.Add(m_currentTriangle);

            for (int start = 0; start != removeList.Count; ++start)
            {
                // All triangles with circumcircle containing the point will need to be removed.
                Triangle remTriangle = removeList[start];
                for(int k = 0; k < 3; k++)
                {
                    Triangle adjacentTriangle = remTriangle.adjacentFace[k];
                    if(adjacentTriangle != null && !adjacentTriangle.visited )
                    {
                        adjacentTriangle.visited = true;

                        if(adjacentTriangle.CircumCircleContains(p))
                        {
                            adjacentTriangle.remove = true;
                            removeList.Add(adjacentTriangle); //holds a list of removeable Triangle_t
                        }
                        else
                        {
                            visitedList.Add(adjacentTriangle);
                        }
                    }
                }
            }

            if (visitedList.Count > 0)
            {
                for(int i = 0; i < visitedList.Count; i++)
                    visitedList[i].visited = false;
            }
            visitedList.Clear();

            // For every n triangles we are going to remove we should be able to add n+2 new ones
            int numNewTriangles = 0;
            for(int i = 0; i != removeList.Count; i++)
            {
                Triangle remTriangle = removeList[i];
                for(int j = 0; j != 3; j++)
                {
                    // Create a Triangle for each side that isnt to be removed.
                    if(remTriangle.adjacentFace[j] == null)
                    {
                        numNewTriangles++;
                    }
                    else if(!remTriangle.adjacentFace[j].remove)
                    {
                        numNewTriangles++;
                    }
                }
            }

            // Paranoia check.
            if(numNewTriangles - 2 != removeList.Count)
            {
                // Don't expect to hit this, but checking anyways just in case of rounding errors.
                for(int i = 0; i != removeList.Count; i++)
                {
                    removeList[i].visited = false;
                    removeList[i].remove = false;
                }

                return;
            }

            // Create new triangles.
            List<Triangle> newList = new List<Triangle>();
            int[] vertIndex = new int[] { 1, 2, 0 };

            for(int i = 0; i != removeList.Count; i++)
            {
                Triangle remTriangle = removeList[i];
                for(int j = 0; j < 3; j++)
                {
                    //create a Triangle for each side that isnt to be removed
                    Triangle adjacent = remTriangle.adjacentFace[j];
                    if(adjacent == null)
                    {
                        Triangle t = new Triangle(remTriangle.m_v[j], remTriangle.m_v[vertIndex[j]], p);
                        newList.Add(t);
                    }
                    else if(!adjacent.remove)
                    {
                        Triangle t = new Triangle(remTriangle.m_v[j], remTriangle.m_v[vertIndex[j]], p);

                        // Stitch shared edge of new triangle into existing network.
                        t.adjacentFace[0] = adjacent;
                        for (int e = 0; e != 3; e++)
                        {
                            if (adjacent.adjacentFace[e] == remTriangle)
                                adjacent.adjacentFace[e] = t;
                        }

                        newList.Add(t);
                    }
                }
            }

            // Stitch up the new triangles with each-other.  Simplified case because vertex[2] for all shared triangles is the same, and is
            // in fact parameter point 'p'.
            m_currentTriangle = null;
            for(int i = 0; i != newList.Count; i++)
            {
                Triangle t = newList[i];
                m_currentTriangle = t;

                // Iterate over other un-stitched edges looking for a match.
                for(int j = i+1; (j != newList.Count) && ((t.adjacentFace[1] == null) || (t.adjacentFace[2] == null)); j++)
                {
                    Triangle q = newList[j];
                    if (t.adjacentFace[1] == null)
                    {
                        if(t.m_v[1] == q.m_v[0])
                        {
                            t.adjacentFace[1] = q;
                            q.adjacentFace[2] = t;
                        }
                    }

                    if (t.adjacentFace[2] == null)
                    {
                        if(t.m_v[0] == q.m_v[1])
                        {
                            t.adjacentFace[2] = q;
                            q.adjacentFace[1] = t;
                        }
                    }
                }
            }

            // Free triangles that were to be removed.
            for(int i = 0; i != removeList.Count; i++)
            {
                Triangle cur = removeList[i];
                m_newTriangles.Remove(cur);
                FreeTriangle(cur, false);
            }

            // Add new triangles for later consideration & processing.
            for (int i = 0; i != newList.Count; ++i)
                m_newTriangles.Add(newList[i]);
        }
Пример #38
0
        bool Overlaps(Extent2D extent)
        {
            // Check simplist case - triangle inside extent.
            if (extent.Contains(m_extent))
                return true;

            // Use right-hand rule for each triangle segment against all points of extent rectangle.
            DelaunayPoint p1 = new DelaunayPoint(extent.MinX, extent.MinY, 0.0f, 0);
            DelaunayPoint p2 = new DelaunayPoint(extent.MaxX, extent.MinY, 0.0f, 0);
            DelaunayPoint p3 = new DelaunayPoint(extent.MaxX, extent.MaxY, 0.0f, 0);
            DelaunayPoint p4 = new DelaunayPoint(extent.MinX, extent.MaxY, 0.0f, 0);

            int ar = 0;
            if (DelaunayGeometry.CrossProduct(m_v[0], p1, m_v[1]) >= 0.0f)
                ++ar;
            if (DelaunayGeometry.CrossProduct(m_v[0], p2, m_v[1]) >= 0.0f)
                ++ar;
            if (DelaunayGeometry.CrossProduct(m_v[0], p3, m_v[1]) >= 0.0f)
                ++ar;
            if (DelaunayGeometry.CrossProduct(m_v[0], p4, m_v[1]) >= 0.0f)
                ++ar;

            int br = 0;
            if (DelaunayGeometry.CrossProduct(m_v[1], p1, m_v[2]) >= 0.0f)
                ++br;
            if (DelaunayGeometry.CrossProduct(m_v[1], p2, m_v[2]) >= 0.0f)
                ++br;
            if (DelaunayGeometry.CrossProduct(m_v[1], p3, m_v[2]) >= 0.0f)
                ++br;
            if (DelaunayGeometry.CrossProduct(m_v[1], p4, m_v[2]) >= 0.0f)
                ++br;

            int cr = 0;
            if (DelaunayGeometry.CrossProduct(m_v[2], p1, m_v[0]) >= 0.0f)
                ++cr;
            if (DelaunayGeometry.CrossProduct(m_v[2], p2, m_v[0]) >= 0.0f)
                ++cr;
            if (DelaunayGeometry.CrossProduct(m_v[2], p3, m_v[0]) >= 0.0f)
                ++cr;
            if (DelaunayGeometry.CrossProduct(m_v[2], p4, m_v[0]) >= 0.0f)
                ++cr;

            // There will be some sort intersection of triangle with rectangle if at least one point of
            // the rectangle is on, or to the right (not zero) of every segment of the triangle.
            if (ar != 0 && br != 0 && cr != 0)
            {
                return true;
            }

            return false;
        }
Пример #39
0
        public bool IsCoincidentWithVertex(DelaunayPoint p)
        {
            double distA = (m_v[0].X - p.X) * (m_v[0].X - p.X) + (m_v[0].Y - p.Y) * (m_v[0].Y - p.Y);
            double distB = (m_v[1].X - p.X) * (m_v[1].X - p.X) + (m_v[1].Y - p.Y) * (m_v[1].Y - p.Y);
            double distC = (m_v[2].X - p.X) * (m_v[2].X - p.X) + (m_v[2].Y - p.Y) * (m_v[2].Y - p.Y);

            if((distA <= VERY_SMALL_DIST) || (distB <= VERY_SMALL_DIST) || (distC <= VERY_SMALL_DIST))
                return true;

            return false;
        }
Пример #40
0
        Triangle GetAdjacent(DelaunayPoint start, DelaunayPoint end)
        {
            double t = 0;
            double s = SegmentsIntersect(m_v[0], m_v[1], start, end, t);

            if(t >= 0 && t <= 1 && s >= 0 && s <= 1)
            {
                return adjacentFace[0];
            }

            s = SegmentsIntersect(m_v[1], m_v[2], start, end, t);

            if(t >= 0 && t <= 1 && s >= 0 && s <= 1)
            {
                return adjacentFace[1];
            }

            s = SegmentsIntersect(m_v[2], m_v[0], start, end, t);

            if(t >= 0 && t <= 1 && s >= 0 && s <= 1)
            {
                return adjacentFace[2];
            }

            return null;
        }