public static List<Point2D> getSubdividedLine(ref Point2D vec1, ref Point2D vec2, float segmentSize)
 {
     List<Point2D> temp = new List<Point2D>();
     temp.Add(vec1);
     temp.AddRange(getSubdividePoints(ref vec1, ref vec2, segmentSize));
     temp.Add(vec2);
     return temp;
 }
Пример #2
0
        private void calcBisector()
        {
            rayStart = new Point2D(LineTools.LineIntersect(prevEdge.getFirstPoint(), prevEdge.getSecondPoint(), nextEdge.getFirstPoint(), nextEdge.getSecondPoint()));

            float angle1 = MathHelper.ToRadians(prevEdge.getOwnAngle());
            float angle2 = MathHelper.ToRadians(nextEdge.getOwnAngle());
            double angle = (angle1 + ((angle2 - angle1 + 2 * Math.PI) % (2 * Math.PI)) / 2) % (Math.PI * 2);

            rayDir = new Point2D((float)-Math.Sin(angle), (float)Math.Cos(angle));
        }
 public static List<Point2D> getSubdividePoints(ref Point2D vec1, ref Point2D vec2, float segmentSize)
 {
     List<Point2D> temp = new List<Point2D>();
     int totalSegments = (int)Math.Ceiling(OwnVector2.Distance(vec1, vec2) / segmentSize);
     for (int j = 1; j < totalSegments; j++)
     {
         float scaleFactor = (float)j / (float)totalSegments;
         Point2D interpolated = new Point2D(OwnVector2.Lerp(vec1, vec2, scaleFactor)); //LineTools.Interpolate(ref vec1, ref vec2, scaleFactor);
         temp.Add(interpolated);
     }
     return temp;
 }
        /// <summary>
        /// Get all intersections between a line segment and a list of vertices
        /// representing a polygon. The vertices reuse adjacent points, so for example
        /// edges one and two are between the first and second vertices and between the
        /// second and third vertices. The last edge is between vertex vertices.Count - 1
        /// and verts0. (ie, vertices from a Geometry or AABB)
        /// </summary>
        /// <param name="point1">The first point of the line segment to test</param>
        /// <param name="point2">The second point of the line segment to test.</param>
        /// <param name="vertices">The vertices, as described above</param>
        public static Vertices LineSegmentVerticesIntersect(ref Point2D point1, ref Point2D point2, Vertices vertices)
        {
            Vertices intersectionPoints = new Vertices();

            for (int i = 0; i < vertices.Count; i++)
            {
                Point2D point;
                if (LineIntersect(vertices[i], vertices[vertices.NextIndex(i)], point1, point2, true, true, out point))
                {
                    intersectionPoints.Add(point);
                }
            }

            return intersectionPoints;
        }
 /// <summary>
 /// This method detects if two line segments intersect,
 /// and, if so, the point of intersection. 
 /// Note: If two line segments are coincident, then 
 /// no intersection is detected (there are actually
 /// infinite intersection points).
 /// </summary>
 /// <param name="point1">The first point of the first line segment.</param>
 /// <param name="point2">The second point of the first line segment.</param>
 /// <param name="point3">The first point of the second line segment.</param>
 /// <param name="point4">The second point of the second line segment.</param>
 /// <param name="intersectionPoint">This is set to the intersection
 /// point if an intersection is detected.</param>
 /// <returns>True if an intersection is detected, false otherwise.</returns>
 public static bool LineIntersect(Point2D point1, Point2D point2, Point2D point3, Point2D point4, out Point2D intersectionPoint)
 {
     return LineIntersect(ref point1, ref point2, ref point3, ref point4, true, true, out intersectionPoint);
 }
        public static Vertices LineSegmentPolygonIntersect(ref Point2D point1, ref Point2D point2, Polygon polygon)
        {
            Vertices intersectionPoints = new Vertices();
            int count = polygon.Vertices.Count - (polygon.isClosed() ? 0 : 1);

            for (int i = 0; i < count; i++)
            {
                Point2D point;
                if (LineIntersect(polygon.Vertices[i], polygon.Vertices[polygon.Vertices.NextIndex(i)], point1, point2, true, true, out point))
                {
                    intersectionPoints.Add(point);
                }
            }
            return intersectionPoints;
        }
        /// <summary>
        /// This method detects if two line segments (or lines) intersect,
        /// and, if so, the point of intersection. Use the <paramref name="firstIsSegment"/> and
        /// <paramref name="secondIsSegment"/> parameters to set whether the intersection point
        /// must be on the first and second line segments. Setting these
        /// both to true means you are doing a line-segment to line-segment
        /// intersection. Setting one of them to true means you are doing a
        /// line to line-segment intersection test, and so on.
        /// Note: If two line segments are coincident, then 
        /// no intersection is detected (there are actually
        /// infinite intersection points).
        /// Author: Jeremy Bell
        /// </summary>
        /// <param name="point1">The first point of the first line segment.</param>
        /// <param name="point2">The second point of the first line segment.</param>
        /// <param name="point3">The first point of the second line segment.</param>
        /// <param name="point4">The second point of the second line segment.</param>
        /// <param name="point">This is set to the intersection
        /// point if an intersection is detected.</param>
        /// <param name="firstIsSegment">Set this to true to require that the 
        /// intersection point be on the first line segment.</param>
        /// <param name="secondIsSegment">Set this to true to require that the
        /// intersection point be on the second line segment.</param>
        /// <returns>True if an intersection is detected, false otherwise.</returns>
        public static bool LineIntersect(ref Point2D point1, ref Point2D point2, ref Point2D point3, ref Point2D point4, bool firstIsSegment, bool secondIsSegment, out Point2D point)
        {
            point = new Point2D(0, 0);

            // these are reused later.
            // each lettered sub-calculation is used twice, except
            // for b and d, which are used 3 times
            float a = point4.Y - point3.Y;
            float b = point2.X - point1.X;
            float c = point4.X - point3.X;
            float d = point2.Y - point1.Y;

            // denominator to solution of linear system
            float denom = (a * b) - (c * d);

            // if denominator is 0, then lines are parallel
            if (!(denom >= -Settings.Epsilon && denom <= Settings.Epsilon))
            {
                float e = point1.Y - point3.Y;
                float f = point1.X - point3.X;
                float oneOverDenom = 1.0f / denom;

                // numerator of first equation
                float ua = (c * e) - (a * f);
                ua *= oneOverDenom;

                // check if intersection point of the two lines is on line segment 1
                if (!firstIsSegment || ua >= 0.0f && ua <= 1.0f)
                {
                    // numerator of second equation
                    float ub = (b * e) - (d * f);
                    ub *= oneOverDenom;

                    // check if intersection point of the two lines is on line segment 2
                    // means the line segments intersect, since we know it is on
                    // segment 1 as well.
                    if (!secondIsSegment || ub >= 0.0f && ub <= 1.0f)
                    {
                        // check if they are coincident (no collision in this case)
                        if (ua != 0f || ub != 0f)
                        {
                            //There is an intersection
                            point.X = point1.X + ua * b;
                            point.Y = point1.Y + ua * d;

                            //TEST: ROUNDING SHOULD BE GONE?
                            //point.X = (float)Math.Round((double)(point.X),1);
                            //point.Y = (float)Math.Round((double)(point.Y),1);

                            return true;
                        }
                    }
                }
            }

            return false;
        }
        private void findClosestIntersectionAndStore(CircularLinkedList<Vertex> LAV, Vertex prev, Vertex current, Vertex next)
        {
            Vertices testPoly = new Vertices();
            foreach (Vertex v in LAV)
            {
                testPoly.Add(v.getPoint());
            }
            OwnVector2 prevIntersection = LineTools.LineIntersect(
                prev.getRayStart(), prev.getRayStepPoint(),
                current.getRayStart(), current.getRayStepPoint());
            OwnVector2 nextIntersection = LineTools.LineIntersect(
                current.getRayStart(), current.getRayStepPoint(),
                next.getRayStart(), next.getRayStepPoint());
            OwnVector2 nearestOppositeIntersection = OwnVector2.Zero;

            Point2D testPrev = new Point2D(prevIntersection);
            if (testPoly.PointInPolygon(ref testPrev) == -1)
            {
                prevIntersection = Point2D.Zero;
            }
            Point2D testNext = new Point2D(nextIntersection);
            if (testPoly.PointInPolygon(ref testNext) == -1)
            {
                nextIntersection = Point2D.Zero;
            }

            Vertex firstEdgePoint = null;
            Vertex secondEdgePoint = null;
            if(current.isConcave())
            {
                nearestOppositeIntersection = findNearestOppositeEdge(LAV, current, out firstEdgePoint, out secondEdgePoint);
            }

            float distPrev = prevIntersection.Equals(Point2D.Zero) ? float.MaxValue : OwnVector2.Distance(current.getPoint(), prevIntersection);
            float distNext = nextIntersection.Equals(Point2D.Zero) ? float.MaxValue : OwnVector2.Distance(current.getPoint(), nextIntersection);
            float distOpposite = float.MaxValue;

            if (distPrev == 0)
            {
                prevIntersection = Point2D.Zero;
            }
            if (distNext == 0)
            {
                nextIntersection = Point2D.Zero;
            }
            if (current.isConcave())
            {
                distOpposite = OwnVector2.Distance(current.getPoint(), nearestOppositeIntersection);
            }

            if (prevIntersection.Equals(OwnVector2.Zero) && nextIntersection.Equals(OwnVector2.Zero) && nearestOppositeIntersection.Equals(OwnVector2.Zero))
            {
                return;
            }
            if ((nextIntersection.Equals(OwnVector2.Zero) && nearestOppositeIntersection.Equals(OwnVector2.Zero)) || distPrev < distNext && distPrev < distOpposite)
            {
                Event e = new Event(new Point2D(prevIntersection), SLAV.IndexOf(LAV), EventType.Edge);
                e.storeFirstPoint(prev);
                e.storeSecondPoint(current);
                Q.Enqueue(e, distPrev);
            }
            else if ((nearestOppositeIntersection.Equals(OwnVector2.Zero) && prevIntersection.Equals(OwnVector2.Zero)) || distNext <= distPrev && distNext <= distOpposite)
            {
                Event e = new Event(new Point2D(nextIntersection), SLAV.IndexOf(LAV), EventType.Edge);
                e.storeFirstPoint(current);
                e.storeSecondPoint(next);
                Q.Enqueue(e, distNext);
            }
            else
            {
                Event e = new Event(new Point2D(nearestOppositeIntersection), SLAV.IndexOf(LAV), EventType.Split);
                e.storeFirstPoint(current);
                e.storeFirstEdgePoint(firstEdgePoint);
                e.storeSecondEdgePoint(secondEdgePoint);
                Q.Enqueue(e, distOpposite);
            }
        }
Пример #9
0
 /// <summary>
 /// Define edge from starting point to end point with Point2D
 /// </summary>
 /// <param name="firstPoint"></param>
 /// <param name="secondPoint"></param>
 public Edge(Point2D firstPoint, Point2D secondPoint)
 {
     this.firstPoint = firstPoint;
     this.secondPoint = secondPoint;
 }
        //From Mark Bayazit's convex decomposition algorithm
        public static OwnVector2 LineIntersect(Point2D p1, Point2D p2, Point2D q1, Point2D q2)
        {
            OwnVector2 i = OwnVector2.Zero;
            float a1 = p2.Y - p1.Y;
            float b1 = p1.X - p2.X;
            float c1 = a1 * p1.X + b1 * p1.Y;
            float a2 = q2.Y - q1.Y;
            float b2 = q1.X - q2.X;
            float c2 = a2 * q1.X + b2 * q1.Y;
            float det = a1 * b2 - a2 * b1;

            if (!MathUtils.FloatEquals(det, 0))
            {
                // lines are not parallel
                i.X = (b2 * c1 - b1 * c2) / det;
                i.Y = (a1 * c2 - a2 * c1) / det;
            }
            return i;
        }
Пример #11
0
        private void handleMouseInput()
        {
            if (mouseState.MiddleButton == ButtonState.Pressed && previousMouseState.MiddleButton == ButtonState.Released)
            {
                mirrorMode = !mirrorMode;
            }
            if (mouseState.RightButton == ButtonState.Pressed && previousMouseState.RightButton == ButtonState.Released)
            {
                //enable/disablef snapping mode
                snappingMode = !snappingMode;
            }

            int xCor = mouseState.X;
            int yCor = mouseState.Y;
            if (snappingMode)
            {
                xCor = ((int)(xCor / gridSize)) * gridSize + topLeftGridX;
                yCor = ((int)(yCor / gridSize)-1) * gridSize + topLeftGridY;
            }

            // Adding points when new click
            if (_gui.drawToggleButton.IsToggled
                && this.IsActive
                && !_gui.comboBox.IsPressed
                && mouseState.LeftButton == ButtonState.Pressed
                && previousMouseState.LeftButton == ButtonState.Released
                && mouseState.X >= 0 && mouseState.X < graphics.PreferredBackBufferWidth
                && mouseState.Y >= 40 && mouseState.Y < graphics.PreferredBackBufferHeight)
            {
                if (!_gui.polyToggleButton.IsToggled)
                {
                    Point2D point = new Point2D(xCor, yCor);
                    polygon.ControlVertices.Add(point);
                    controlPoints.Add(DrawTools.createDrawableRectangle(point));
                    Point2D mirrorPoint = new Point2D(graphics.PreferredBackBufferWidth - xCor, yCor);
                    polygon.MirrorVertices.Add(mirrorPoint);
                    mirrorPoints.Add(DrawTools.createDrawableRectangle(mirrorPoint));
                }
                else
                {
                    if (_gui.newHoleToggleButton.IsToggled || polygon.ControlVertices.Holes.Count == 0)
                    {
                        controlPointsHoles.Add(new List<Rectangle>());
                        mirrorPointsHoles.Add(new List<Rectangle>());
                        polygon.ControlVertices.Holes.Add(new Vertices());
                        polygon.MirrorVertices.Holes.Add(new Vertices());

                        currentSelectedHole = controlPointsHoles.Count - 1;

                        _gui.newHoleToggleButton.IsToggled = false;
                    }
                    Point2D point = new Point2D(xCor, yCor);
                    polygon.ControlVertices.Holes[currentSelectedHole].Add(point);
                    controlPointsHoles[currentSelectedHole].Add(DrawTools.createDrawableRectangle(point));

                    Point2D mirrorPoint = new Point2D(graphics.PreferredBackBufferWidth - xCor, yCor);
                    polygon.MirrorVertices.Holes[currentSelectedHole].Add(mirrorPoint);
                    mirrorPointsHoles[currentSelectedHole].Add(DrawTools.createDrawableRectangle(mirrorPoint));
                }
            }

            // Adding points when holding click
            if (_gui.drawToggleButton.IsToggled
                && this.IsActive
                && !_gui.comboBox.IsPressed
                && mouseState.LeftButton == ButtonState.Pressed
                && previousMouseState.LeftButton == ButtonState.Pressed
                && mouseState.X >= 0 && mouseState.X < graphics.PreferredBackBufferWidth
                && mouseState.Y >= 40 && mouseState.Y < graphics.PreferredBackBufferHeight)
            {
                if (!_gui.polyToggleButton.IsToggled)
                {
                    Point2D point = new Point2D(xCor, yCor);
                    polygon.ControlVertices[polygon.ControlVertices.Count - 1] = point;
                    controlPoints[polygon.ControlVertices.Count - 1] = DrawTools.createDrawableRectangle(point);
                    Point2D mirrorPoint = new Point2D(graphics.PreferredBackBufferWidth - xCor, yCor);
                    polygon.MirrorVertices[polygon.MirrorVertices.Count-1] = mirrorPoint;
                    mirrorPoints[polygon.MirrorVertices.Count - 1] = DrawTools.createDrawableRectangle(mirrorPoint);
                }
                else
                {
                    Point2D point = new Point2D(xCor, yCor);
                    polygon.ControlVertices.Holes[currentSelectedHole][polygon.ControlVertices.Holes[currentSelectedHole].Count - 1] = point;
                    controlPointsHoles[currentSelectedHole][polygon.ControlVertices.Holes[currentSelectedHole].Count - 1] = DrawTools.createDrawableRectangle(point);

                    Point2D mirrorPoint = new Point2D(graphics.PreferredBackBufferWidth - xCor, yCor);
                    polygon.MirrorVertices.Holes[currentSelectedHole][polygon.MirrorVertices.Holes[currentSelectedHole].Count - 1] = mirrorPoint;
                    mirrorPointsHoles[currentSelectedHole][polygon.MirrorVertices.Holes[currentSelectedHole].Count - 1] = DrawTools.createDrawableRectangle(mirrorPoint);
                }
            }

            // Check if start dragging point
            if (!_gui.drawToggleButton.IsToggled
                && this.IsActive
                && mouseState.LeftButton == ButtonState.Pressed
                && previousMouseState.LeftButton == ButtonState.Released
                && mouseState.X >= 0 && mouseState.X < graphics.PreferredBackBufferWidth
                && mouseState.Y >= 40 && mouseState.Y < graphics.PreferredBackBufferHeight)
            {
                for (int i = 0; i < controlPoints.Count; i++)
                {
                    if (controlPoints[i].Contains(new Point(mouseState.X, mouseState.Y)))
                    {
                        draggingPoints.Add(i);
                    }
                }
                for (int x = 0; x < controlPointsHoles.Count; x++)
                {
                    for (int i = 0; i < controlPointsHoles[x].Count; i++)
                    {
                        if (controlPointsHoles[x][i].Contains(new Point(mouseState.X, mouseState.Y)))
                        {
                            currentSelectedHole = x;
                            draggingHolePoints.Add(i);
                        }
                    }
                }
            }

            // Dragging Points
            if (!_gui.drawToggleButton.IsToggled
                && this.IsActive
                && mouseState.LeftButton == ButtonState.Pressed
                && previousMouseState.LeftButton == ButtonState.Pressed
                && mouseState.X >= 0 && mouseState.X < graphics.PreferredBackBufferWidth
                && mouseState.Y >= 40 && mouseState.Y < graphics.PreferredBackBufferHeight)
            {
                for (int i = 0; i < draggingPoints.Count; i++)
                {
                    Point2D point = polygon.ControlVertices[draggingPoints[i]];
                    point.X = xCor;
                    point.Y = yCor;
                    polygon.ControlVertices[draggingPoints[i]] = point;

                    Point2D mirrorPoint = polygon.MirrorVertices[draggingPoints[i]];
                    mirrorPoint.X = graphics.PreferredBackBufferWidth - xCor;
                    mirrorPoint.Y = yCor;
                    polygon.MirrorVertices[draggingPoints[i]] = mirrorPoint;

                    Rectangle rectangle = controlPoints[draggingPoints[i]];
                    rectangle.X = xCor - (rectangle.Width / 2);
                    rectangle.Y = yCor - (rectangle.Height / 2);
                    controlPoints[draggingPoints[i]] = rectangle;

                    Rectangle mirrorRectangle = mirrorPoints[draggingPoints[i]];
                    mirrorRectangle.X = graphics.PreferredBackBufferWidth - (xCor + (mirrorRectangle.Width / 2));
                    mirrorRectangle.Y = yCor - (mirrorRectangle.Height / 2);
                    mirrorPoints[draggingPoints[i]] = mirrorRectangle;

                }
                for (int i = 0; i < draggingHolePoints.Count; i++)
                {
                    Point2D point = polygon.ControlVertices.Holes[currentSelectedHole][draggingHolePoints[i]];
                    point.X = xCor;
                    point.Y = yCor;
                    polygon.ControlVertices.Holes[currentSelectedHole][draggingHolePoints[i]] = point;

                    Rectangle rectangle = controlPointsHoles[currentSelectedHole][draggingHolePoints[i]];
                    rectangle.X = xCor - (rectangle.Width / 2);
                    rectangle.Y = yCor - (rectangle.Height / 2);
                    controlPointsHoles[currentSelectedHole][draggingHolePoints[i]] = rectangle;

                    Point2D mirrorPoint = polygon.MirrorVertices.Holes[currentSelectedHole][draggingHolePoints[i]];
                    mirrorPoint.X = xCor;
                    mirrorPoint.Y = yCor;
                    polygon.MirrorVertices.Holes[currentSelectedHole][draggingHolePoints[i]] = mirrorPoint;

                    Rectangle mirrorRectangle = mirrorPointsHoles[currentSelectedHole][draggingHolePoints[i]];
                    mirrorRectangle.X = graphics.PreferredBackBufferWidth - (xCor - (mirrorRectangle.Width / 2));
                    mirrorRectangle.Y = yCor - (mirrorRectangle.Height / 2);
                    mirrorPointsHoles[currentSelectedHole][draggingHolePoints[i]] = mirrorRectangle;
                }
            }

            // Clear Dragging List if left Button is released
            if (!_gui.drawToggleButton.IsToggled
                && this.IsActive
                && mouseState.LeftButton == ButtonState.Released
                && previousMouseState.LeftButton == ButtonState.Pressed)
            {
                draggingPoints.Clear();
                draggingHolePoints.Clear();
            }
        }
        /// <summary>
        /// Performs algorithm and returns skeleton
        /// </summary>
        public List<Point2D> Skeleton()
        {
            List<Point2D> ret = new List<Point2D>();

            int i = 0;
            while (Q.Count != 0)
            {
                Event currentEvent = Q.Dequeue();
                CircularLinkedList<Vertex> currentLAV = SLAV[currentEvent.getLAVID()];

                Console.WriteLine("------ Iteration " + i + " LAV ID " + currentEvent.getLAVID() + " ------");
                if (currentLAV.Count > 0)
                {
                    foreach (Vertex vertex in currentLAV)
                    {
                        if (vertex != null)
                        {
                            Console.WriteLine("Vertex with ID= " + vertex.getID() + (vertex.isActive() ? " is active " : " is not active"));
                        }
                    }
                  Console.WriteLine("---------------------------------");
                }

                i++;
                if (currentEvent.getType() == EventType.Edge)
                {
                    Console.WriteLine("Edge event between " + currentEvent.getFirstPoint().getID() + " and " + currentEvent.getSecondPoint().getID());
                    Node<Vertex> prevNode = currentLAV.Find(currentEvent.getFirstPoint());
                    Node<Vertex> nextNode = currentLAV.Find(currentEvent.getSecondPoint());

                    //check if event is outdated
                    if (prevNode == null || nextNode == null || (!prevNode.Value.isActive() && !nextNode.Value.isActive()))
                    {
                        Console.WriteLine("Skipped edge event");
                        continue;
                    }

                    Vertex prevV = prevNode.Value;
                    Vertex nextV = nextNode.Value;

                    //check if we remain to the last 3 points
                    if (prevNode.PrevActive().PrevActive().Value.Equals(nextV))
                    {
                        Point2D intersect = new Point2D(LineTools.LineIntersect(prevV.getPoint(), prevV.getRayStepPoint(), nextV.getPoint(), nextV.getRayStepPoint()));

                        ret.Add(prevV.getPoint());
                        ret.Add(intersect);
                        ret.Add(nextV.getPoint());
                        ret.Add(intersect);
                        ret.Add(prevNode.PrevActive().Value.getPoint());
                        ret.Add(intersect);

                        currentLAV.Find(prevV).Value.setActive(false);
                        currentLAV.Find(nextV).Value.setActive(false);
                        currentLAV.Find(prevV).PrevActive().Value.setActive(false);
                        continue;
                    }

                    //output two arcs
                    ret.Add(currentEvent.getFirstPoint().getPoint());
                    ret.Add(currentEvent.getIntersection());
                    ret.Add(currentEvent.getSecondPoint().getPoint());
                    ret.Add(currentEvent.getIntersection());

                    //modify list
                    currentLAV.Find(currentEvent.getFirstPoint()).Value.setActive(false);
                    currentLAV.Find(currentEvent.getSecondPoint()).Value.setActive(false);

                    Point2D intersection = currentEvent.getIntersection();
                    if (!intersection.Equals(Point2D.Zero))
                    {
                        Vertex newV = new Vertex(intersection, id++);
                        newV.prevEdge = prevV.prevEdge;
                        newV.nextEdge = nextV.nextEdge;
                        newV.update();

                        Node<Vertex> newNode = new Node<Vertex>(newV);

                        currentLAV.AddAfter(prevV, newV);
                        //currentLAV.Remove(prevV);
                        //currentLAV.Remove(nextV);

                        findClosestIntersectionAndStore(currentLAV, currentLAV.Find(newV).PrevActive().Value, currentLAV.Find(newV).Value, currentLAV.Find(newV).NextActive().Value);
                    }
                }
                else
                {
                    Console.WriteLine("Split event " + currentEvent.getFirstPoint().getID());
                    Node<Vertex> prevNode = currentLAV.Find(currentEvent.getFirstPoint());

                    //check if event is outdated
                    if (prevNode == null || !prevNode.Value.isActive())
                    {

                        Console.WriteLine("Skipped split event");
                        continue;
                    }
                    Vertex prevV = prevNode.Value;
                    prevV.setActive(false);

                    //check if we remain to the last 3 points
                    if (prevNode.PrevActive().PrevActive().Value.Equals(prevNode.NextActive().Value))
                    {
                        Point2D intersect = new Point2D(LineTools.LineIntersect(prevV.getPoint(), prevV.getRayStepPoint(), prevNode.Next.Value.getPoint(), prevNode.Next.Value.getRayStepPoint()));

                        ret.Add(prevNode.Value.getPoint());
                        ret.Add(intersect);
                        ret.Add(prevNode.NextActive().Value.getPoint());
                        ret.Add(intersect);
                        ret.Add(prevNode.PrevActive().Value.getPoint());
                        ret.Add(intersect);

                        continue;
                    }
                    //output only VI
                    ret.Add(prevV.getPoint());
                    ret.Add(currentEvent.getIntersection());

                    //split LAV reset que etc
                    Vertex newNodeV1 = new Vertex(currentEvent.getIntersection(), id++);
                    newNodeV1.prevEdge = currentEvent.getFirstPoint().prevEdge;
                    newNodeV1.nextEdge = currentEvent.getFirstEdgePoint().nextEdge;
                    newNodeV1.update();

                    Vertex newNodeV2 = new Vertex(currentEvent.getIntersection(), id++);
                    newNodeV2.prevEdge = currentEvent.getFirstPoint().nextEdge;
                    newNodeV2.nextEdge = currentEvent.getFirstEdgePoint().nextEdge;
                    newNodeV2.update();

                    CircularLinkedList<Vertex> newLAV = new CircularLinkedList<Vertex>();
                    newLAV.AddFirst(newNodeV2);
                    Node<Vertex> current = SLAV[currentEvent.getLAVID()].Find(currentEvent.getFirstPoint());

                    while(!current.Next.Value.Equals(currentEvent.getSecondEdgePoint()))
                    {
                        if (current.Next.Equals(current))
                        {
                            break;
                        }
                        current = current.Next;
                        newLAV.AddLast(current.Value);
                        //current.Value.setActive(false);
                        SLAV[currentEvent.getLAVID()].Remove(current.Value);
                    }
                    SLAV.Add(newLAV);
                    SLAV[currentEvent.getLAVID()].AddAfter(currentEvent.getFirstPoint(),newNodeV1);
                    //SLAV[currentEvent.getLAVID()].Find(currentEvent.getFirstPoint()).Value.setActive(false);
                    //SLAV[currentEvent.getLAVID()].Remove(currentEvent.getFirstPoint());

                    //test
                    for (int x = 0; x < newLAV.Count; x++)
                    {
                        Vertex prev = newLAV[x].PrevActive().Value;
                        Vertex curr = newLAV[x].Value;
                        Vertex next = newLAV[x].NextActive().Value;

                        findClosestIntersectionAndStore(newLAV, prev, curr, next);
                    }

                    //findClosestIntersectionAndStore(newLAV, newLAV.Find(newNodeV2).PrevActive().Value, newLAV.Find(newNodeV2).Value, newLAV.Find(newNodeV2).NextActive().Value);
                    findClosestIntersectionAndStore(SLAV[currentEvent.getLAVID()], SLAV[currentEvent.getLAVID()].Find(newNodeV1).PrevActive().Value, SLAV[currentEvent.getLAVID()].Find(newNodeV1).Value, SLAV[currentEvent.getLAVID()].Find(newNodeV1).NextActive().Value);

                }
            }
            return ret;
        }
        private OwnVector2 findNearestOppositeEdge(CircularLinkedList<Vertex> LAV, Vertex current, out Vertex firstEdgePoint, out Vertex secondEdgePoint)
        {
            firstEdgePoint = null;
            secondEdgePoint = null;
            Node<Vertex> temp = LAV.Find(current).Next;
            Point2D intersectionPoint = new Point2D(0,0);
            Point2D currentClosest = new Point2D(0, 0);
            Vertices testPoly = new Vertices();
            foreach(Vertex v in LAV)
            {
                testPoly.Add(v.getPoint());
            }
            while (!temp.Next.Value.Equals(current))
            {
                //check if the edge is not behind the vertex
                if(LineTools.LineIntersect(
                    current.getRayStart(),
                    new Point2D(current.getRayStart().X + (-current.getRayDirection().X * int.MaxValue), -current.getRayStart().Y + (-current.getRayDirection().Y * int.MaxValue)),
                    temp.Value.getPoint(),
                    temp.Next.Value.getPoint(),
                    true,false, out intersectionPoint))
                {
                    //Calc Bi (intersection ray current + bisector of triangle)
                    Point2D intersect1 = new Point2D(LineTools.LineIntersect(
                        current.prevEdge.getFirstPoint(),
                        current.prevEdge.getSecondPoint(),
                        temp.Value.getPoint(),
                        temp.Next.Value.getPoint()));
                    Point2D intersect2 = new Point2D(LineTools.LineIntersect(
                        current.nextEdge.getFirstPoint(),
                        current.nextEdge.getSecondPoint(),
                        temp.Value.getPoint(),
                        temp.Next.Value.getPoint()));

                    Vertices tempVer = new Vertices();
                    tempVer.Add(current.getPoint());
                    tempVer.Add(intersect1);
                    tempVer.Add(intersect2);

                    Vertex edgeBisector1 = new Vertex(intersect1, -1);
                    edgeBisector1.prevEdge = new Edge(current.getPoint(), intersect1);
                    edgeBisector1.nextEdge = new Edge(intersect1, intersect2);
                    edgeBisector1.update();

                    Point2D Bi = new Point2D(LineTools.LineIntersect(
                        current.getRayStart(),
                        current.getRayStepPoint(),
                        edgeBisector1.getRayStart(),
                        edgeBisector1.getRayStepPoint()));

                    if (tempVer.PointInPolygon(ref Bi) == -1)
                    {

                        edgeBisector1 = new Vertex(intersect2, -1);
                        edgeBisector1.prevEdge = new Edge(current.getPoint(), intersect2);
                        edgeBisector1.nextEdge = new Edge(intersect2, intersect1);
                        edgeBisector1.update();

                        Bi = new Point2D(LineTools.LineIntersect(
                            current.getRayStart(),
                            current.getRayStepPoint(),
                            edgeBisector1.getRayStart(),
                            edgeBisector1.getRayStepPoint()));
                        if (tempVer.PointInPolygon(ref Bi) == -1)
                        {
                            temp = temp.Next;
                            continue;
                        }
                    }

                    //check if Bi inside polygon to begin with
                    if (testPoly.PointInPolygon(ref Bi) == -1)
                    {
                        temp = temp.Next;
                        continue;
                    }

                    //check if Bi is in area defined by opposing edge and it's bisectors
                    //first check if both bisectors of edge are convex so we can see if Bi is inside the defined triangle
                    if(temp.Value.isConvex() && temp.Next.Value.isConvex())
                    {
                        OwnVector2 trianglePoint = LineTools.LineIntersect(
                            temp.Value.getRayStart(),
                            temp.Value.getRayStepPoint(),
                            temp.Next.Value.getRayStart(),
                            temp.Next.Value.getRayStepPoint());

                        if (!MathHelper.PointInTriangle(trianglePoint, temp.Value.getPoint(), temp.Next.Value.getPoint(), Bi))
                        {
                            temp = temp.Next;
                            continue;
                        }
                    }
                    else{
                        Vertices test = new Vertices();
                        int sign1 = temp.Value.isConvex() ? 1 : -1;
                        int sign2 = temp.Next.Value.isConvex() ? 1 : -1;

                        test.Add(temp.Value.getPoint());
                        test.Add(temp.Next.Value.getPoint());
                        test.Add(new Point2D(
                            temp.Next.Value.getPoint().X + (sign2 * temp.Next.Value.getRayDirection().X * int.MaxValue),
                            temp.Next.Value.getPoint().Y + (sign2 * temp.Next.Value.getRayDirection().Y * int.MaxValue)));
                        test.Add(new Point2D(
                            temp.Value.getPoint().X + (sign1 * temp.Value.getRayDirection().X * int.MaxValue),
                            temp.Value.getPoint().Y + (sign1 * temp.Value.getRayDirection().Y * int.MaxValue)));

                        if (test.PointInPolygon(ref Bi) == -1)
                        {
                            temp = temp.Next;
                            continue;
                        }
                    }

                    if (currentClosest.Equals(Point2D.Zero) || Point2D.Distance(current.getPoint(), currentClosest) > Point2D.Distance(current.getPoint(), Bi))
                    {
                        currentClosest = Bi;
                        firstEdgePoint = temp.Value;
                        secondEdgePoint = temp.Next.Value;
                    }
                }
                temp = temp.Next;
            }

            testDots.Add(currentClosest);
            return currentClosest;
        }
Пример #14
0
 public Vertex(Point2D point, int id)
 {
     this.active = true;
     this.point = point;
     this.id = id;
 }
 /// <summary>
 /// This method detects if two line segments (or lines) intersect,
 /// and, if so, the point of intersection. Use the <paramref name="firstIsSegment"/> and
 /// <paramref name="secondIsSegment"/> parameters to set whether the intersection point
 /// must be on the first and second line segments. Setting these
 /// both to true means you are doing a line-segment to line-segment
 /// intersection. Setting one of them to true means you are doing a
 /// line to line-segment intersection test, and so on.
 /// Note: If two line segments are coincident, then 
 /// no intersection is detected (there are actually
 /// infinite intersection points).
 /// Author: Jeremy Bell
 /// </summary>
 /// <param name="point1">The first point of the first line segment.</param>
 /// <param name="point2">The second point of the first line segment.</param>
 /// <param name="point3">The first point of the second line segment.</param>
 /// <param name="point4">The second point of the second line segment.</param>
 /// <param name="intersectionPoint">This is set to the intersection
 /// point if an intersection is detected.</param>
 /// <param name="firstIsSegment">Set this to true to require that the 
 /// intersection point be on the first line segment.</param>
 /// <param name="secondIsSegment">Set this to true to require that the
 /// intersection point be on the second line segment.</param>
 /// <returns>True if an intersection is detected, false otherwise.</returns>
 public static bool LineIntersect(Point2D point1, Point2D point2, Point2D point3, Point2D point4, bool firstIsSegment, bool secondIsSegment, out Point2D intersectionPoint)
 {
     return LineIntersect(ref point1, ref point2, ref point3, ref point4, firstIsSegment, secondIsSegment, out intersectionPoint);
 }
        public List<OwnVector3> createCrossingSegment(OwnVector3 centerPoint, List<OwnVector3> connectingPoints)
        {
            OwnVector3 startPoint = OwnVector3.Lerp(centerPoint, connectingPoints[0], 0.5f);
            OwnVector3 endPoint = OwnVector3.Lerp(centerPoint, connectingPoints[1], 0.5f);
            OwnVector3 startPoint2 = OwnVector3.Lerp(centerPoint, connectingPoints[2], 0.5f);
            OwnVector3 endPoint2 = OwnVector3.Lerp(centerPoint, connectingPoints[3], 0.5f);

            List<OwnVector3> ret = new List<OwnVector3>();

            OwnVector3 p1 = OwnVector3.Lerp(centerPoint, connectingPoints[0], 0.7f);
            OwnVector3 p2 = OwnVector3.Lerp(centerPoint, connectingPoints[1], 0.7f);
            OwnVector3 p3 = OwnVector3.Lerp(centerPoint, connectingPoints[2], 0.7f);
            OwnVector3 p4 = OwnVector3.Lerp(centerPoint, connectingPoints[3], 0.7f);
            OwnVector3 p5 = connectingPoints[0] - (startPoint - connectingPoints[0]);
            OwnVector3 p6 = connectingPoints[1] - (endPoint - connectingPoints[1]);
            OwnVector3 p7 = connectingPoints[2] - (startPoint2 - connectingPoints[2]);
            OwnVector3 p8 = connectingPoints[3] - (endPoint2 - connectingPoints[3]);

            ret.Add(p1);
            ret.Add(p4);
            ret.Add(p2);
            ret.Add(p3);

            ret.Add(p1);
            ret.Add(p3);
            ret.Add(p2);
            ret.Add(p4);

            ret.Add(p5);
            ret.Add(p1);

            ret.Add(p6);
            ret.Add(p2);

            ret.Add(p7);
            ret.Add(p3);

            ret.Add(p8);
            ret.Add(p4);

            OwnVector3 direction = centerPoint - p5;
            OwnVector3 norDirection = direction / direction.Length();
            OwnVector3 direction2 = centerPoint - p6;
            OwnVector3 norDirection2 = direction2 / direction2.Length();
            OwnVector3 direction3 = centerPoint - p7;
            OwnVector3 norDirection3 = direction3 / direction3.Length();
            OwnVector3 direction4 = centerPoint - p8;
            OwnVector3 norDirection4 = direction4 / direction4.Length();

            OwnVector3 p9 = DrawTools.MoveForward(p5, DrawTools.TurnRight(90, norDirection), 2 * distance);
            OwnVector3 p10 = DrawTools.MoveForward(p8, DrawTools.TurnLeft(90, norDirection4), 2 * distance);
            OwnVector3 p11 = DrawTools.MoveForward(p6, DrawTools.TurnRight(90, norDirection2), 2 * distance);
            OwnVector3 p12 = DrawTools.MoveForward(p7, DrawTools.TurnLeft(90, norDirection3), 2 * distance);
            OwnVector3 p13 = DrawTools.MoveForward(p5, DrawTools.TurnLeft(90, norDirection), 2 * distance);
            OwnVector3 p14 = DrawTools.MoveForward(p7, DrawTools.TurnRight(90, norDirection3), 2 * distance);
            OwnVector3 p15 = DrawTools.MoveForward(p6, DrawTools.TurnLeft(90, norDirection2), 2 * distance);
            OwnVector3 p16 = DrawTools.MoveForward(p8, DrawTools.TurnRight(90, norDirection4), 2 * distance);

            Point2D intersectionPoint = new Point2D(0,0);

            LineTools.LineIntersect(new Point2D(p9.X, p9.Y), new Point2D(p10.X, p10.Y), new Point2D(p13.X, p13.Y), new Point2D(p14.X, p14.Y), true, true, out intersectionPoint);

            if (intersectionPoint == new Point2D(0, 0))
            {
                ret.Add(p9);
                ret.Add(p10);

                ret.Add(p11);
                ret.Add(p12);

                ret.Add(p13);
                ret.Add(p14);

                ret.Add(p15);
                ret.Add(p16);
            }
            else
            {
                ret.Add(p9);
                ret.Add(p12);

                ret.Add(p14);
                ret.Add(p15);

                ret.Add(p10);
                ret.Add(p11);

                ret.Add(p13);
                ret.Add(p16);
            }

            return ret;
        }
Пример #17
0
 public Event(Point2D intersectionPoint, int idLAV, EventType type)
 {
     this.intersectionPoint = intersectionPoint;
     this.type = type;
     this.idLAV = idLAV;
 }