// from http://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/ // Given three colinear points p, q, r, the function checks if // point q lies on line segment 'pr' private bool onSegment(Vertice p, Vertice q, Vertice r) { if (p.X <= Math.Max(p.X, r.X) && q.X >= Math.Max(p.X, r.X) && q.Y <= Math.Min(p.Y, r.Y) && q.Y >= Math.Min(p.Y, r.Y)) return true; return false; }
// To find orientation of ordered triplet (p, q, r). // The function returns following values // 0 --> p, q and r are colinear // 1 --> Clockwise // 2 --> Counterclockwise int orientation(Vertice p, Vertice q, Vertice r) { // See http://www.geeksforgeeks.org/orientation-3-ordered-points/ // for details of below formula. double val = (q.Y - p.Y) * (r.X - q.X) - (q.X - p.X) * (r.Y - q.Y); if (val == 0) { return 0; // colinear } return (val > 0) ? 1 : 2; // clock or counterclock wise }
// The main function that returns true if line segment 'p1q1' // and 'p2q2' intersect. bool doIntersect(Vertice p1, Vertice q1, Vertice p2, Vertice q2) { // Find the four orientations needed for general and // special cases int o1 = orientation(p1, q1, p2); int o2 = orientation(p1, q1, q2); int o3 = orientation(p2, q2, p1); int o4 = orientation(p2, q2, q1); // General case if (o1 != o2 && o3 != o4) return true; // Special Cases // p1, q1 and p2 are colinear and p2 lies on segment p1q1 if (o1 == 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are colinear and q2 lies on segment p1q1 if (o2 == 0 && onSegment(p1, q2, q1)) return true; // p2, q2 and p1 are colinear and p1 lies on segment p2q2 if (o3 == 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and q1 are colinear and q1 lies on segment p2q2 if (o4 == 0 && onSegment(p2, q1, q2)) return true; return false; // Doesn't fall in any of the above cases }
private bool findNext(Vertice Start, Vertice End, List<Vertice> path) { Vertice found = null; double closestDistance = 0, distance; List<Vertice> nonIntersects = new List<Vertice>(); for (int i = 0; i < Vertices.Count; i++) { if (checkAgainstAll(Start, Vertices[i]) && !path.Contains(Vertices[i])) { nonIntersects.Add(Vertices[i]); } } for (int j = 0; j < nonIntersects.Count; j++) { distance = Math.Sqrt((Math.Pow(Math.Abs(End.X - nonIntersects[j].X), 2) + Math.Pow(Math.Abs(End.Y - nonIntersects[j].Y), 2))); if ((j == 0) || (distance < closestDistance)) { found = nonIntersects[j]; closestDistance = distance; } } if (nonIntersects.Count == 0) { return false; } else { path.Add(found); return true; } }
private bool checkAgainstAll(Vertice Looking, Vertice Goal) { bool retVal = true; Pen penTg = new Pen(Color.Green); penTg.Width = 2; Pen penTr = new Pen(Color.Red); penTr.Width = 2; foreach (Guard guard in Guards) { if (guard.Validated) { if (!guard.belongsTo(Looking) && !guard.belongsTo(Goal) && doIntersect(Looking, Goal, guard.VerticeS, guard.VerticeE)) { if (!isDebug) { return false; } graphicsObject.DrawLine(penTr, 5 + (int)(guard.VerticeS.X * graphicsScale), ((int)((yMax - guard.VerticeS.Y) * graphicsScale) + 10), 5 + (int)(guard.VerticeE.X * graphicsScale), ((int)((yMax - guard.VerticeE.Y) * graphicsScale) + 10)); retVal = false; } else { graphicsObject.DrawLine(penTg, 5 + (int)(guard.VerticeS.X * graphicsScale), ((int)((yMax - guard.VerticeS.Y) * graphicsScale) + 10), 5 + (int)(guard.VerticeE.X * graphicsScale), ((int)((yMax - guard.VerticeE.Y) * graphicsScale) + 10)); } } if (isDebug) { Application.DoEvents(); Thread.Sleep(50); } } return retVal; }
public bool checkVisibles(Vertice Start, Vertice End, out List<Vertice> path) { if (Vertices == null || Guards == null) { path = null; return false; } Vertices.Add(End); path = new List<Vertice>(); path.Add(Start); int i = 0; do { findNext(path[i], End, path); i++; } while ((i < path.Count) && (path[i] != End)); Pen penPr = new Pen(Color.Purple); penPr.Width = 1; for (i = 0; i < path.Count - 1; i++) { graphicsObject.DrawLine(penPr, 5 + (int)(path[i].X * graphicsScale), ((int)((yMax - path[i].Y) * graphicsScale) + 10), 5 + (int)(path[i + 1].X * graphicsScale), ((int)((yMax - path[i + 1].Y) * graphicsScale) + 10)); } Vertices.Remove(End); // Vertices.Remove(Start); return true; }
public Vertice addVertice(Vertice vertice) { if (Vertices == null) { Vertices = new SortableBindingList<Vertice>(); } foreach (Vertice vertice_ in Vertices) { if ((vertice_.X == vertice.X) && (vertice_.Y == vertice.Y)) { return vertice_; } } Vertices.Add(vertice); return vertice; }
public bool setRange(double x1, double y1, double x2, double y2) { if ((x1 > parent.xMax) || (x1 < parent.xMin) || (x2 > parent.xMax) || (x2 < parent.xMin) || (y1 > parent.yMax) || (y1 < parent.yMin) || (y2 > parent.yMax) || (y2 < parent.yMin)) { return false; } if (VerticeS == null) { verticeS = new Vertice(); } if (VerticeE == null) { verticeE = new Vertice(); } VerticeS.X = x1; VerticeS.Y = y1; VerticeE.X = x2; VerticeE.Y = y2; VerticeS = parent.addVertice(VerticeS); VerticeE = parent.addVertice(VerticeE); validated = true; Notify("Set range"); return true; }
public bool belongsTo(Vertice vertice) { if ((vertice == VerticeS) || (vertice == VerticeE)) { return true; } return false; }