示例#1
0
        /** Triangulate between two polylines as if they where convex hulls, very similar to D&C merge
         * (Gift wrapping idea) from 3D Convex hull theory. Used for a tunnel start **/
        public void triangulateTunnelStart(Polyline originPoly, Polyline destinyPoly)           //TODO:some times does not triangulate correctly!
        //Start from a line between the first one of each polyline, by construction one is generated from the projection of the other=>NO as it has changed(smooth)
        {
            Vertex a      = originPoly.getVertex(0);
            Vertex b      = destinyPoly.getVertex(0);
            int    aIndex = 1;
            int    bIndex = 1;

            /*//For getting the starting line, using minimum distance points
             * //int j = 0;
             * float minDistance = Vector3.Distance (a.getPosition(), b.getPosition());
             * for (int j = 0; j < originPoly.getSize (); ++j) {
             *      for (int i = 0; i < destinyPoly.getSize (); ++i) {
             *              float auxDistance = Vector3.Distance (originPoly.getVertex(j).getPosition (), destinyPoly.getVertex (i).getPosition ());
             *              if (auxDistance < minDistance) {
             *                      a = originPoly.getVertex (j);
             *                      b = destinyPoly.getVertex (i);
             *                      minDistance = auxDistance;
             *                      bIndex = i + 1;
             *                      aIndex = j + 1;
             *              }
             *      }
             * }*/
            //Find lowerest tangent
            //The lower point of origin will be either the first or last vertex(by construction)

            /*if (a.getPosition ().y > originPoly.getVertex (-1).getPosition ().y) {
             *      a = originPoly.getVertex (-1);
             *      aIndex = 0;
             * }
             * int j = 0;
             * float minPos = float.MaxValue;
             * for (int i = 0; i < destinyPoly.getSize (); ++i) {
             *      float auxPos = destinyPoly.getVertex (i).getPosition ().y;
             *      if (auxPos < minPos) {
             *              b = destinyPoly.getVertex (i);
             *              minPos = auxPos;
             *              bIndex = i + 1;
             *      }
             * }*/
            const int maxFoll = 5;
            int       bFoll = 0, aFoll = 0;       //To controll not the same sida is always the winner, as it produces artifacts some cases
            int       bIter = 0, aIter = 0;
            bool      aWins = false;

            while (aIter < originPoly.getSize() && bIter < destinyPoly.getSize())
            {
                //This line ab will be triangulated with a point c either from one polyliline or the other, depending the one that has
                //smallest angle with ab line(A-winner or B-winner).c It's always an adjacent vertex, we can use they are clockwise sorted(lucky!)
                Vector3 ab = b.getPosition() - a.getPosition();
                //Check the B polylilne candidate
                Vertex bWinner = destinyPoly.getVertex(bIndex);
                float  bAngle  = Vector3.Angle(-ab, bWinner.getPosition() - b.getPosition());
                //Check the A polylilne candidate
                Vertex aWinner = originPoly.getVertex(aIndex);
                float  aAngle  = Vector3.Angle(ab, aWinner.getPosition() - a.getPosition());
                //aAngle = Vector3.Distance (aWinner.getPosition (), b.getPosition ());
                //bAngle = Vector3.Distance (bWinner.getPosition (), a.getPosition ());

                //Check not same polyline accumulates too much wins
                if (aFoll > maxFoll)
                {
                    aWins = false;
                    aFoll = 0;
                }
                else if (bFoll > maxFoll)
                {
                    aWins = true;
                    bFoll = 0;
                }
                else
                {
                    aWins = aAngle < bAngle;
                }

                //If it's A-winner(from first poly) a=c, if it's from b-Winner b = c
                if (aWins)                   //A wins!
                {
                    addTriangle(a.getIndex(), aWinner.getIndex(), b.getIndex());
                    a = aWinner;
                    ++aIndex;
                    ++aIter;
                    ++aFoll;
                }
                else                   //B wins!
                {
                    addTriangle(a.getIndex(), bWinner.getIndex(), b.getIndex());
                    b = bWinner;
                    ++bIndex;
                    ++bIter;
                    ++bFoll;
                }
            }            //Repeat until ab we arrive to some of the polylines start, then triangulate with a or b constant(depends on polyline)

            if (aIter >= originPoly.getSize())
            {
                while (bIter < destinyPoly.getSize())
                {
                    Vertex bWinner = destinyPoly.getVertex(bIndex);
                    addTriangle(a.getIndex(), bWinner.getIndex(), b.getIndex());
                    b = bWinner;
                    ++bIndex;
                    ++bIter;
                }
            }
            else if (bIter >= destinyPoly.getSize())
            {
                while (aIter < originPoly.getSize())
                {
                    Vertex aWinner = originPoly.getVertex(aIndex);
                    addTriangle(a.getIndex(), aWinner.getIndex(), b.getIndex());
                    a = aWinner;
                    ++aIndex;
                    ++aIter;
                }
            }

            //TODO: check strange artifacts cases,
            //may be procuduced by winner decision, maybe smallest angle is not the best choice(or checking worng angle)
        }