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; }
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); } }
/// <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; }
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; }
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; }
public Event(Point2D intersectionPoint, int idLAV, EventType type) { this.intersectionPoint = intersectionPoint; this.type = type; this.idLAV = idLAV; }