def test_left_right(self):
     p = Point2D(0, 0)
     q = Point2D(1, 0)
     r = Point2D(0, 1)
     self.assertTrue(left(p, q, r))
     self.assertFalse(left(p, r, q))
     self.assertFalse(right(p, q, r))
     self.assertTrue(right(p, r, q))
def find(S: List[Point2D]) -> List[int]:
    S1 = [Point2D(*i)
          for i in S]  # lo mismo que S1=S=[Point2D(x, y) for x,y in S]

    # Eleccion punto inicial y ordenacion
    min_y = min(p.y for p in S1)
    p = argmax((pt for pt in S1 if min_y == pt.y), lambda pt: pt.x)
    S1 = [p] + sorted((q for q in S1 if q != p),
                      key=lambda q: (atan2(p.y - q.y, p.x - q.x), q.x))
    Q = Lifo()
    Q.push(0), Q.push(1), Q.push(2)
    for pi in range(3, len(S1)):
        pj, pk = Q[-1], Q[-2]
        while not left(S1[pk], S1[pj], S1[pi]):
            Q.pop()
            pj, pk = Q[-1], Q[-2]
        Q.push(pi)
    return [S.index(S1[Q.pop()]) for i in range(len(Q))]
Example #3
0
    def find(self, S: "IList<Point2D>") -> "IList<int>":
        S1 = S = [Point2D(*p) for p in S]
        min_y = min(pt.y for pt in S)
        p = argmax((pt for pt in S if pt.y == min_y), lambda pt: pt.x)
        S = [p] + sorted((q for q in S if q != p),
                         key=lambda q: (atan2(p.y - q.y, p.x - q.x), q.x))
        Q = Lifo()
        Q.push(0)
        Q.push(1)
        Q.push(2)
        for pi in range(3, len(S)):
            pj, pk = Q[-1], Q[-2]
            while not left(S[pk], S[pj], S[pi]):
                Q.pop()
                pj, pk = Q[-1], Q[-2]
            Q.push(pi)
        return [S1.index(S[Q.pop()]) for i in range(len(Q))]


#> graham
Example #4
0
 def quickhull(self, S: "IList<(T, T)>") -> "Iterable<int>":
     if len(S) <= 2: return list(S)
     p, q = min(S), max(S)
     qhull = self._quickhull(p, [z for z in S if z != p and z != q and left(p, q, z)], q)[1:] + \
             self._quickhull(q, [z for z in S if z != p and z != q and right(p, q, z)], p)[1:]
     return qhull
Example #5
0
 def _quickhull(self, p, A, q):
     if len(A) == 0: return [p, q]
     h = argmax(A, lambda z: triangle_area(p, q, z))
     return self._quickhull(p, [z for z in A if left(p, h, z)],h) + \
            self._quickhull(h, [z for z in A if left(h, q, z)],q)[1:]