/// <summary>
        /// Test the triad against its 3 neighbours and flip it with any neighbour whose opposite point
        /// is inside the circumcircle of the triad
        /// </summary>
        /// <param name="triads">The triads</param>
        /// <param name="triadIndexToTest">The index of the triad to test</param>
        /// <param name="triadIndexFlipped">Index of adjacent triangle it was flipped with (if any)</param>
        /// <returns>true iff the triad was flipped with any of its neighbours</returns>
        bool FlipTriangle(List <Triad> triads, int triadIndexToTest, out int triadIndexFlipped)
        {
            int oppositeVertex = 0, edge1, edge2, edge3 = 0, edge4 = 0;

            triadIndexFlipped = 0;

            Triad tri = triads[triadIndexToTest];

            // test all 3 neighbours of tri

            if (tri.bc >= 0)
            {
                triadIndexFlipped = tri.bc;
                Triad t2 = triads[triadIndexFlipped];
                // find relative orientation (shared limb).
                t2.FindAdjacency(tri.b, triadIndexToTest, out oppositeVertex, out edge3, out edge4);
                if (tri.InsideCircumcircle(points[oppositeVertex]))
                {  // not valid in the Delaunay sense.
                    edge1 = tri.ab;
                    edge2 = tri.ac;
                    if (edge1 != edge3 && edge2 != edge4)
                    {
                        int tria = tri.a, trib = tri.b, tric = tri.c;
                        tri.Initialize(tria, trib, oppositeVertex, edge1, edge3, triadIndexFlipped, points);
                        t2.Initialize(tria, tric, oppositeVertex, edge2, edge4, triadIndexToTest, points);

                        // change knock on triangle labels.
                        if (edge3 >= 0)
                        {
                            triads[edge3].ChangeAdjacentIndex(triadIndexFlipped, triadIndexToTest);
                        }
                        if (edge2 >= 0)
                        {
                            triads[edge2].ChangeAdjacentIndex(triadIndexToTest, triadIndexFlipped);
                        }
                        return(true);
                    }
                }
            }


            if (tri.ab >= 0)
            {
                triadIndexFlipped = tri.ab;
                Triad t2 = triads[triadIndexFlipped];
                // find relative orientation (shared limb).
                t2.FindAdjacency(tri.a, triadIndexToTest, out oppositeVertex, out edge3, out edge4);
                if (tri.InsideCircumcircle(points[oppositeVertex]))
                {  // not valid in the Delaunay sense.
                    edge1 = tri.ac;
                    edge2 = tri.bc;
                    if (edge1 != edge3 && edge2 != edge4)
                    {
                        int tria = tri.a, trib = tri.b, tric = tri.c;
                        tri.Initialize(tric, tria, oppositeVertex, edge1, edge3, triadIndexFlipped, points);
                        t2.Initialize(tric, trib, oppositeVertex, edge2, edge4, triadIndexToTest, points);

                        // change knock on triangle labels.
                        if (edge3 >= 0)
                        {
                            triads[edge3].ChangeAdjacentIndex(triadIndexFlipped, triadIndexToTest);
                        }
                        if (edge2 >= 0)
                        {
                            triads[edge2].ChangeAdjacentIndex(triadIndexToTest, triadIndexFlipped);
                        }
                        return(true);
                    }
                }
            }

            if (tri.ac >= 0)
            {
                triadIndexFlipped = tri.ac;
                Triad t2 = triads[triadIndexFlipped];
                // find relative orientation (shared limb).
                t2.FindAdjacency(tri.a, triadIndexToTest, out oppositeVertex, out edge3, out edge4);
                if (tri.InsideCircumcircle(points[oppositeVertex]))
                {                   // not valid in the Delaunay sense.
                    edge1 = tri.ab; // .ac shared limb
                    edge2 = tri.bc;
                    if (edge1 != edge3 && edge2 != edge4)
                    {
                        int tria = tri.a, trib = tri.b, tric = tri.c;
                        tri.Initialize(trib, tria, oppositeVertex, edge1, edge3, triadIndexFlipped, points);
                        t2.Initialize(trib, tric, oppositeVertex, edge2, edge4, triadIndexToTest, points);

                        // change knock on triangle labels.
                        if (edge3 >= 0)
                        {
                            triads[edge3].ChangeAdjacentIndex(triadIndexFlipped, triadIndexToTest);
                        }
                        if (edge2 >= 0)
                        {
                            triads[edge2].ChangeAdjacentIndex(triadIndexToTest, triadIndexFlipped);
                        }
                        return(true);
                    }
                }
            }

            return(false);
        }