Exemplo n.º 1
0
 public bool GetIntersection(Line2D ray)
 {
     return(Line2D.GetIntersection(v1, v2, ray.v1.x, ray.v1.y, ray.v2.x, ray.v2.y));
 }
Exemplo n.º 2
0
 public bool GetIntersection(Line2D ray, out double u_ray, out double u_line)
 {
     return(Line2D.GetIntersection(v1, v2, ray.v1.x, ray.v1.y, ray.v2.x, ray.v2.y, out u_ray, out u_line));
 }
Exemplo n.º 3
0
 public bool GetIntersection(double x3, double y3, double x4, double y4)
 {
     return(Line2D.GetIntersection(v1, v2, x3, y3, x4, y4));
 }
Exemplo n.º 4
0
 public bool GetIntersection(double x3, double y3, double x4, double y4, out double u_ray, out double u_line)
 {
     return(Line2D.GetIntersection(v1, v2, x3, y3, x4, y4, out u_ray, out u_line));
 }
Exemplo n.º 5
0
        // This finds the cut coordinates and splits the other poly with inner vertices
        private static void SplitOuterWithInner(LinkedListNode <EarClipVertex> start, EarClipPolygon p)
        {
            LinkedListNode <EarClipVertex> insertbefore = null;
            float    foundu   = float.MaxValue;
            Vector2D foundpos = new Vector2D();

            // Create a line from start that goes beyond the right most vertex of p
            LinkedListNode <EarClipVertex> pr = FindRightMostVertex(p);
            float  startx       = start.Value.Position.x;
            float  endx         = pr.Value.Position.x + 10.0f;
            Line2D starttoright = new Line2D(start.Value.Position, new Vector2D(endx, start.Value.Position.y));

            // Calculate a small bonus (0.1 mappixel)
            float bonus = starttoright.GetNearestOnLine(new Vector2D(start.Value.Position.x + 0.1f, start.Value.Position.y));

            // Go for all lines in the outer polygon
            LinkedListNode <EarClipVertex> v1 = p.Last;
            LinkedListNode <EarClipVertex> v2 = p.First;

            while (v2 != null)
            {
                // Check if the line goes between startx and endx
                if ((v1.Value.Position.x > startx || v2.Value.Position.x > startx) &&
                    (v1.Value.Position.x < endx || v2.Value.Position.x < endx))
                {
                    // Find intersection
                    Line2D pl = new Line2D(v1.Value.Position, v2.Value.Position);
                    float  u, ul;
                    pl.GetIntersection(starttoright, out u, out ul);
                    if (float.IsNaN(u))
                    {
                        // We have found a line that is perfectly horizontal
                        // (parallel to the cut scan line) Check if the line
                        // is overlapping the cut scan line.
                        if (v1.Value.Position.y == start.Value.Position.y)
                        {
                            // This is an exceptional situation which causes a bit of a problem, because
                            // this could be a previously made cut, which overlaps another line from the
                            // same cut and we have to determine which of the two we will join with. If we
                            // pick the wrong one, the polygon is no longer valid and triangulation will fail.

                            // Calculate distance of each vertex in units
                            u  = starttoright.GetNearestOnLine(v1.Value.Position);
                            ul = starttoright.GetNearestOnLine(v2.Value.Position);

                            // Rule out vertices before the scan line
                            if (u < 0.0f)
                            {
                                u = float.MaxValue;
                            }
                            if (ul < 0.0f)
                            {
                                ul = float.MaxValue;
                            }

                            float    insert_u = Math.Min(u, ul);
                            Vector2D inserpos = starttoright.GetCoordinatesAt(insert_u);

                            // Check in which direction the line goes.
                            if (v1.Value.Position.x > v2.Value.Position.x)
                            {
                                // The line goes from right to left (towards our start point)
                                // so we must always insert our cut after this line.

                                // If the next line goes up, we consider this a better candidate than
                                // a horizontal line that goes from left to right (the other cut line)
                                // so we give it a small bonus.
                                LinkedListNode <EarClipVertex> v3 = v2.Next ?? v2.List.First;
                                if (v3.Value.Position.y < v2.Value.Position.y)
                                {
                                    insert_u -= bonus;
                                }

                                // Remember this when it is a closer match
                                if (insert_u <= foundu)
                                {
                                    insertbefore = v2.Next ?? v2.List.First;
                                    foundu       = insert_u;
                                    foundpos     = inserpos;
                                }
                            }
                            else
                            {
                                // The line goes from left to right (away from our start point)
                                // so we must always insert our cut before this line.

                                // If the previous line goes down, we consider this a better candidate than
                                // a horizontal line that goes from right to left (the other cut line)
                                // so we give it a small bonus.
                                LinkedListNode <EarClipVertex> v3 = v1.Previous ?? v1.List.Last;
                                if (v3.Value.Position.y > v1.Value.Position.y)
                                {
                                    insert_u -= bonus;
                                }

                                // Remember this when it is a closer match
                                if (insert_u <= foundu)
                                {
                                    insertbefore = v2;
                                    foundu       = insert_u;
                                    foundpos     = inserpos;
                                }
                            }
                        }
                    }
                    // Found a closer match?
                    else if ((ul >= 0.0f) && (ul <= 1.0f) && (u > 0.0f) && (u <= foundu))
                    {
                        // Found a closer intersection
                        insertbefore = v2;
                        foundu       = u;
                        foundpos     = starttoright.GetCoordinatesAt(u);
                    }
                }

                // Next
                v1 = v2;
                v2 = v2.Next;
            }

            // Found anything?
            if (insertbefore != null)
            {
                Sidedef sd = (insertbefore.Previous == null) ? insertbefore.List.Last.Value.Sidedef : insertbefore.Previous.Value.Sidedef;

                // Find the position where we have to split the outer polygon
                EarClipVertex split = new EarClipVertex(foundpos, null);

                // Insert manual split vertices
                p.AddBefore(insertbefore, new EarClipVertex(split, sd));

                // Start inserting from the start (do I make sense this time?)
                v1 = start;
                do
                {
                    // Insert inner polygon vertex
                    p.AddBefore(insertbefore, new EarClipVertex(v1.Value));
                    v1 = (v1.Next ?? v1.List.First);
                } while(v1 != start);

                // Insert manual split vertices
                p.AddBefore(insertbefore, new EarClipVertex(start.Value, sd));
                if (split.Position != insertbefore.Value.Position)
                {
                    p.AddBefore(insertbefore, new EarClipVertex(split, sd));
                }
            }
        }
Exemplo n.º 6
0
        // This checks if a line is inside a triangle (touching the triangle is allowed)
        // NOTE: We already know p1 is on an edge segment of the triangle
        private static bool LineInsideTriangle(EarClipVertex[] t, Vector2D p1, Vector2D p2)
        {
            float s01             = Line2D.GetSideOfLine(t[0].Position, t[1].Position, p2);
            float s12             = Line2D.GetSideOfLine(t[1].Position, t[2].Position, p2);
            float s20             = Line2D.GetSideOfLine(t[2].Position, t[0].Position, p2);
            float p2_on_edge      = 2.0f;                       // somewhere outside the 0 .. 1 range
            float p1_on_same_edge = 2.0f;

            // Test if p2 is inside the triangle
            if ((s01 < 0.0f) && (s12 < 0.0f) && (s20 < 0.0f))
            {
                // Line is inside triangle, because p2 is
                return(true);
            }
            // Test if p2 is on an edge of the triangle and if it is we would
            // like to know where on the edge segment p2 is
            else if (s01 == 0.0f)
            {
                p2_on_edge      = Line2D.GetNearestOnLine(t[0].Position, t[1].Position, p2);
                p1_on_same_edge = Line2D.GetSideOfLine(t[0].Position, t[1].Position, p1);
            }
            else if (s12 == 0.0f)
            {
                p2_on_edge      = Line2D.GetNearestOnLine(t[1].Position, t[2].Position, p2);
                p1_on_same_edge = Line2D.GetSideOfLine(t[1].Position, t[2].Position, p1);
            }
            else if (s20 == 0.0f)
            {
                p2_on_edge      = Line2D.GetNearestOnLine(t[2].Position, t[0].Position, p2);
                p1_on_same_edge = Line2D.GetSideOfLine(t[2].Position, t[0].Position, p1);
            }

            // Is p2 actually on the edge segment?
            if ((p2_on_edge >= 0.0f) && (p2_on_edge <= 1.0f))
            {
                // If p1 is on the same edge (or the unlimited line of that edge)
                // then the line is not inside this triangle.
                if (p1_on_same_edge == 0.0f)
                {
                    return(false);
                }
            }

            // Do a complete line-triangle intersection test
            // We already know p1 is not inside the triangle (possibly on an edge)
            Line2D p = new Line2D(p1, p2);
            Line2D t01 = new Line2D(t[0].Position, t[1].Position);
            Line2D t12 = new Line2D(t[1].Position, t[2].Position);
            Line2D t20 = new Line2D(t[2].Position, t[0].Position);
            float  pu, pt;

            // Test intersections
            t01.GetIntersection(p, out pu, out pt);
            if (!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f))
            {
                return(true);
            }
            t12.GetIntersection(p, out pu, out pt);
            if (!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f))
            {
                return(true);
            }
            t20.GetIntersection(p, out pu, out pt);
            if (!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f))
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 7
0
 public bool GetIntersection(Line2D ray, out float u_ray, bool bounded)
 {
     return(Line2D.GetIntersection(v1, v2, ray.v1.x, ray.v1.y, ray.v2.x, ray.v2.y, out u_ray, bounded));
 }
Exemplo n.º 8
0
 public bool GetIntersection(float x3, float y3, float x4, float y4, out float u_ray, out float u_line)
 {
     return(Line2D.GetIntersection(v1, v2, x3, y3, x4, y4, out u_ray, out u_line));
 }
Exemplo n.º 9
0
 public bool GetIntersection(float x3, float y3, float x4, float y4)
 {
     return(Line2D.GetIntersection(v1, v2, x3, y3, x4, y4));
 }