// private void RadialSort(ICoordinateList p) // { // // A selection sort routine, assumes the pivot point is // // the first point (i.e., p[0]). // Coordinate t; // for (int i = 1; i < (p.Count - 1); i++) // { // int min = i; // for (int j = i + 1; j < p.Count; j++) // { // if (PolarCompare(p[0], p[j], p[min]) < 0) // { // min = j; // } // } // t = p[i]; // p[i] = p[min]; // p[min] = t; // } // } // // private int PolarCompare(Coordinate o, Coordinate p, Coordinate q) // { // // Given two points p and q Compare them with respect to their radial // // ordering about point o. -1, 0 or 1 depending on whether p is less than, // // equal to or greater than q. First checks radial ordering then if both // // points lie on the same line, check Distance to o. // double dxp = p.X - o.X; // double dyp = p.Y - o.Y; // double dxq = q.X - o.X; // double dyq = q.Y - o.Y; // double alph = Math.Atan2(dxp, dyp); // double beta = Math.Atan2(dxq, dyq); // if (alph < beta) // { // return - 1; // } // if (alph > beta) // { // return 1; // } // double op = dxp * dxp + dyp * dyp; // double oq = dxq * dxq + dyq * dyq; // if (op < oq) // { // return -1; // } // if (op > oq) // { // return 1; // } // return 0; // } /// <returns> whether the three coordinates are collinear and c2 lies between /// c1 and c3 inclusive /// </returns> private bool IsBetween(Coordinate c1, Coordinate c2, Coordinate c3) { if (CGAlgorithms.ComputeOrientation(c1, c2, c3) != 0) { return(false); } if (c1.X != c3.X) { if (c1.X <= c2.X && c2.X <= c3.X) { return(true); } if (c3.X <= c2.X && c2.X <= c1.X) { return(true); } } if (c1.Y != c3.Y) { if (c1.Y <= c2.Y && c2.Y <= c3.Y) { return(true); } if (c3.Y <= c2.Y && c2.Y <= c1.Y) { return(true); } } return(false); }
private Stack GrahamScan(ICoordinateList c) { Coordinate p; Stack ps = new Stack(); ps.Push(c[0]); ps.Push(c[1]); ps.Push(c[2]); for (int i = 3; i < c.Count; i++) { p = (Coordinate)ps.Pop(); while (CGAlgorithms.ComputeOrientation( (Coordinate)ps.Peek(), p, c[i]) > 0) { p = (Coordinate)ps.Pop(); } ps.Push(p); ps.Push(c[i]); p = c[i]; } ps.Push(c[0]); return(ps); }
/** * Given two points p and q compare them with respect to their radial * ordering about point o. First checks radial ordering. * If points are collinear, the comparison is based * on their distance to the origin. * <p> * p < q iff * <ul> * <li>ang(o-p) < ang(o-q) (e.g. o-p-q is CCW) * <li>or ang(o-p) == ang(o-q) && dist(o,p) < dist(o,q) * </ul> * * @param o the origin * @param p a point * @param q another point * @return -1, 0 or 1 depending on whether p is less than, * equal to or greater than q */ private static int PolarCompare(Coordinate o, Coordinate p, Coordinate q) { double dxp = p.X - o.X; double dyp = p.Y - o.Y; double dxq = q.X - o.X; double dyq = q.Y - o.Y; /* * // MD - non-robust * int result = 0; * double alph = Math.atan2(dxp, dyp); * double beta = Math.atan2(dxq, dyq); * if (alph < beta) { * result = -1; * } * if (alph > beta) { * result = 1; * } * if (result != 0) return result; * //*/ OrientationType orient = CGAlgorithms.ComputeOrientation(o, p, q); if (orient == OrientationType.CounterClockwise) { return(1); } if (orient == OrientationType.Clockwise) { return(-1); } // points are collinear - check distance double op = dxp * dxp + dyp * dyp; double oq = dxq * dxq + dyq * dyq; if (op < oq) { return(-1); } if (op > oq) { return(1); } return(0); }