예제 #1
0
        public List<int> FlushTriangles()
        {
            //if(m_currentTriangle == null)
            //    return null;

            m_currentTriangle = null;
            foreach(Triangle triangle in m_newTriangles)
            {
                //if (m_extent.Contains(triangle.CircumCircleExtent())) // Check to see if triangle's CC extent is in cell.
                //{
                //    FreeTriangle(triangle, true);
                //}
                //else
                //{
                //    triangle.visited = true;
                //    m_currentTriangle = triangle;
                //}

                FreeTriangle(triangle, true);
            }
            m_newTriangles.Clear();

            return m_outputTriangles;
        }
예제 #2
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>();
        }
예제 #3
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]);
        }
예제 #4
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;
        }
예제 #5
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;
        }
예제 #6
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);
        }
예제 #7
0
파일: Triangle.cs 프로젝트: jdauie/cloudae
        // 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;
        }