Exemplo n.º 1
0
        /// <summary>
        /// Divide a triangle at the given vertex located on a side
        /// without performing any edge swaps.
        /// </summary>
        /// <param name="t">The triangle to divide</param>
        /// <param name="loc">The location of the vertex on the triangle</param>
        /// <param name="v">The vertex on the side</param>
        private Triangle[] DivideTriangleOnEdgeNoSwap(Triangle t, PointOnTriangle loc, Vertex v)
        {
            Triangle t1 = null;
            Triangle t2 = null;

            if (loc == PointOnTriangle.OnS12)
            {
                // divide edge 12
                t1 = new Triangle(t.V1, v, t.V3);
                t2 = new Triangle(v, t.V2, t.V3);
                t1.SetMeshParams(t.S12.Opposite, t2.S31, t.S31.Opposite);
                t2.SetMeshParams(t.S12.Opposite, t.S23.Opposite, t1.S23);
            }
            else if (loc == PointOnTriangle.OnS23)
            {
                // divide edge 23
                t1 = new Triangle(t.V2, v, t.V1);
                t2 = new Triangle(v, t.V3, t.V1);
                t1.SetMeshParams(t.S23.Opposite, t2.S31, t.S12.Opposite);
                t2.SetMeshParams(t.S23.Opposite, t.S31.Opposite, t1.S23);
            }
            else if (loc == PointOnTriangle.OnS31)
            {
                // divide edge 31
                t1 = new Triangle(t.V3, v, t.V2);
                t2 = new Triangle(v, t.V1, t.V2);
                t1.SetMeshParams(t.S31.Opposite, t2.S31, t.S23.Opposite);
                t2.SetMeshParams(t.S31.Opposite, t.S12.Opposite, t1.S23);
            }

            return(new Triangle[] { t1, t2 });
        }
Exemplo n.º 2
0
        /// <summary>
        /// Divide two triangles at the given vertex located on
        /// their shared edge into four new triangles performing local
        /// edge swaps as necessary to keep the mesh delaunay.
        /// </summary>
        /// <param name="tt1">First triangle to divide</param>
        /// <param name="loc1">The location of the vertex on the first triangle</param>
        /// <param name="tt2">Second triangle to divide</param>
        /// <param name="loc2">The location of the vertex on the second triangle</param>
        /// <param name="v">The vertex on the shared side</param>
        private void DivideTrianglesOnSharedEdge(Triangle tt1, PointOnTriangle loc1, Triangle tt2, PointOnTriangle loc2, Vertex v)
        {
            OnDividingTriangle(new DividingTriangleEventArgs(v, new Triangle[] { tt1, tt2 }));

            Halfedge e1 = (loc1 == PointOnTriangle.OnS12 ? tt1.S12 : (loc1 == PointOnTriangle.OnS23 ? tt1.S23 : tt1.S31));
            Halfedge e2 = (loc2 == PointOnTriangle.OnS12 ? tt2.S12 : (loc2 == PointOnTriangle.OnS23 ? tt2.S23 : tt2.S31));

            // Divide into four triangles
            Triangle[] tn1 = DivideTriangleOnEdgeNoSwap(tt1, loc1, v);
            Triangle[] tn2 = DivideTriangleOnEdgeNoSwap(tt2, loc2, v);

            Triangle t1 = tn1[0];
            Triangle t2 = tn1[1];
            Triangle t3 = tn2[0];
            Triangle t4 = tn2[1];

            t1.SetMeshParams(t4.S12, t2.S31, null);
            t2.SetMeshParams(t3.S12, null, t1.S23);
            t3.SetMeshParams(t2.S12, t4.S31, null);
            t4.SetMeshParams(t1.S12, null, t3.S23);

            tt1.IsRemoved = true;
            tt2.IsRemoved = true;
            Triangles.SetRootTriangle(t1);

            OnDividedTriangle(new DividedTriangleEventArgs(v, new Triangle[] { tt1, tt2 }, new Triangle[] { t1, t2, t3, t4 }));

            // edge flip
            SwapTest(t1.S31, v);
            SwapTest(t2.S23, v);
            SwapTest(t3.S31, v);
            SwapTest(t4.S23, v);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Divides a triangles at the given vertex located on
        /// its edge into two new triangles performing local
        /// edge swaps as necessary to keep the mesh delaunay.
        /// </summary>
        /// <param name="tt">First triangle to divide</param>
        /// <param name="loc">The location of the vertex on the first triangle</param>
        /// <param name="tt2">Second triangle to divide</param>
        /// <param name="loc2">The location of the vertex on the second triangle</param>
        /// <param name="v">The vertex on the shared side</param>
        private void DivideTriangleOnEdge(Triangle tt, PointOnTriangle loc, Vertex v)
        {
            OnDividingTriangle(new DividingTriangleEventArgs(v, new Triangle[] { tt }));

            // Divide into two triangles
            Triangle[] tn1 = DivideTriangleOnEdgeNoSwap(tt, loc, v);

            Triangle t1 = tn1[0];
            Triangle t2 = tn1[1];

            t1.SetMeshParams(null, t2.S31, null);
            t2.SetMeshParams(null, null, t1.S23);

            tt.IsRemoved = true;
            Triangles.SetRootTriangle(t1);

            OnDividedTriangle(new DividedTriangleEventArgs(v, new Triangle[] { tt }, new Triangle[] { t1, t2 }));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Find the triangle(s) containing the given point. The search starts from an arbitrary
        /// triangle and homes in on the vertex by visiting triangles closest to the vertex.
        /// If the vertex is on and edge seperating two triangles, both are returned.
        /// </summary>
        /// <param name="v">The vertex to search for</param>
        /// <returns>The triangles(s) containing the vertex</returns>
        internal FindTriangle[] FindContaining(Vertex v)
        {
            Triangle current = root;

            while (true)
            {
                PointOnTriangle    loc         = PointOnTriangle.None;
                Halfedge           closestEdge = null;
                PointShapeRelation rel         = current.Contains(v, out loc, out closestEdge);
                if (rel == PointShapeRelation.Inside)
                {
                    // Inside triangle, return.
                    return(new FindTriangle[] { new FindTriangle(current, rel, loc) });
                }
                else if (rel == PointShapeRelation.Outside)
                {
                    // Outside triangle, continue searching from the neighbour closest to the point
                    Halfedge opp = closestEdge.Opposite;
                    if (opp == null)
                    {
                        throw new InvalidOperationException("No triangle contains this vertex.");
                    }
                    current = opp.Parent;
                }
                else
                {
                    // On an edge, return the triangle and its neighbour (if there is one)
                    Halfedge opp = closestEdge.Opposite;
                    if (opp == null)
                    {
                        return(new FindTriangle[] { new FindTriangle(current, rel, loc) });
                    }
                    else
                    {
                        Triangle           other    = opp.Parent;
                        PointOnTriangle    otherLoc = PointOnTriangle.None;
                        PointShapeRelation otherRel = other.Contains(v, out otherLoc);
                        return(new FindTriangle[] { new FindTriangle(current, rel, loc), new FindTriangle(other, otherRel, otherLoc) });
                    }
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Determines whether the triangle contains the given vertex.
        /// </summary>
        /// <param name="v">The vertex to check</param>
        /// <param name="location">On return, contains where on the triangle the vertex lies</param>
        /// <param name="closestEdge">On return, contains the edge closest to the input vertex</param>
        /// <returns>The relative location of the vertex</returns>
        public PointShapeRelation Contains(Vertex v, out PointOnTriangle location, out Halfedge closestEdge)
        {
            double a12 = new Matrix3(
                V1.X, V1.Y, 1,
                V2.X, V2.Y, 1,
                v.X, v.Y, 1).Determinant;
            double a23 = new Matrix3(
                V2.X, V2.Y, 1,
                V3.X, V3.Y, 1,
                v.X, v.Y, 1).Determinant;
            double a31 = new Matrix3(
                V3.X, V3.Y, 1,
                V1.X, V1.Y, 1,
                v.X, v.Y, 1).Determinant;

            if (Utility.AlmostZero(a12))
            {
                if (Utility.AlmostZero(a23))
                {
                    location = PointOnTriangle.OnV2;
                }
                else if (Utility.AlmostZero(a31))
                {
                    location = PointOnTriangle.OnV1;
                }
                else
                {
                    location = PointOnTriangle.OnS12;
                }
                closestEdge = S12;
                return(PointShapeRelation.On);
            }
            else if (Utility.AlmostZero(a23))
            {
                if (Utility.AlmostZero(a31))
                {
                    location = PointOnTriangle.OnV3;
                }
                else if (Utility.AlmostZero(a12))
                {
                    location = PointOnTriangle.OnV2;
                }
                else
                {
                    location = PointOnTriangle.OnS23;
                }
                closestEdge = S23;
                return(PointShapeRelation.On);
            }
            else if (Utility.AlmostZero(a31))
            {
                if (Utility.AlmostZero(a12))
                {
                    location = PointOnTriangle.OnV1;
                }
                else if (Utility.AlmostZero(a23))
                {
                    location = PointOnTriangle.OnV3;
                }
                else
                {
                    location = PointOnTriangle.OnS31;
                }
                closestEdge = S31;
                return(PointShapeRelation.On);
            }
            else if (a12 < 0 || a23 < 0 || a31 < 0)
            {
                if (a12 < 0)
                {
                    closestEdge = S12;
                }
                else if (a23 < 0)
                {
                    closestEdge = S23;
                }
                else
                {
                    closestEdge = S31;
                }
                location = PointOnTriangle.None;
                return(PointShapeRelation.Outside);
            }
            else
            {
                double d12 = a12 / S12.Length;
                double d23 = a23 / S23.Length;
                double d31 = a31 / S31.Length;
                if (d12 < d23 && d12 < d31)
                {
                    closestEdge = S12;
                }
                else if (d23 < d12 && d23 < d31)
                {
                    closestEdge = S23;
                }
                else
                {
                    closestEdge = S31;
                }

                location = PointOnTriangle.None;
                return(PointShapeRelation.Inside);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Determines whether the triangle contains the given vertex.
        /// </summary>
        /// <param name="v">The vertex to check</param>
        /// <param name="location">On return, contains where on the triangle the vertex lies</param>
        /// <returns>The relative location of the vertex</returns>
        public PointShapeRelation Contains(Vertex v, out PointOnTriangle location)
        {
            double a12 = new Matrix3(
                V1.X, V1.Y, 1,
                V2.X, V2.Y, 1,
                v.X, v.Y, 1).Determinant;
            double a23 = new Matrix3(
                V2.X, V2.Y, 1,
                V3.X, V3.Y, 1,
                v.X, v.Y, 1).Determinant;
            double a31 = new Matrix3(
                V3.X, V3.Y, 1,
                V1.X, V1.Y, 1,
                v.X, v.Y, 1).Determinant;

            if (Utility.AlmostZero(a12))
            {
                if (Utility.AlmostZero(a23))
                {
                    location = PointOnTriangle.OnV2;
                }
                else if (Utility.AlmostZero(a31))
                {
                    location = PointOnTriangle.OnV1;
                }
                else
                {
                    location = PointOnTriangle.OnS12;
                }
                return(PointShapeRelation.On);
            }
            else if (Utility.AlmostZero(a23))
            {
                if (Utility.AlmostZero(a31))
                {
                    location = PointOnTriangle.OnV3;
                }
                else if (Utility.AlmostZero(a12))
                {
                    location = PointOnTriangle.OnV2;
                }
                else
                {
                    location = PointOnTriangle.OnS23;
                }
                return(PointShapeRelation.On);
            }
            else if (Utility.AlmostZero(a31))
            {
                if (Utility.AlmostZero(a12))
                {
                    location = PointOnTriangle.OnV1;
                }
                else if (Utility.AlmostZero(a23))
                {
                    location = PointOnTriangle.OnV3;
                }
                else
                {
                    location = PointOnTriangle.OnS31;
                }
                return(PointShapeRelation.On);
            }
            else if (a12 < 0 || a23 < 0 || a31 < 0)
            {
                location = PointOnTriangle.None;
                return(PointShapeRelation.Outside);
            }
            else
            {
                location = PointOnTriangle.None;
                return(PointShapeRelation.Inside);
            }
        }
Exemplo n.º 7
0
 public FindTriangle(Triangle tri, PointShapeRelation rel, PointOnTriangle loc)
 {
     Triangle = tri;
     Relation = rel;
     Location = loc;
 }