LoginSignup
2
1

More than 5 years have passed since last update.

Getting convex hull in python

Last updated at Posted at 2018-04-06
COUNTER_CLOCKWISE = 1
CLOCKWISE = -1
ONLINE_BACK = 2
ONLINE_FRONT = -2
ON_SEGMENT = 0
#occw = {"COUNTER_CLOCKWISE":1, "CLOCKWISE":-1, "ONLINE_BACK":2, "ONLINE_FRONT":-2, "ON_SEGMENT":0}
def ccw(p0, p1, p2):
    a = np.array(p1)-np.array(p0)
    b = np.array(p2)-np.array(p0)
    #print("==p0,p1,p2,a,b==")
    #print(p0,p1,p2,a,b)
    #print("==corss,dot==")
    #print(np.cross(a,b),np.dot(a,b))
    if (np.cross(a,b) > np.finfo(np.float).eps):
        return COUNTER_CLOCKWISE
    if (np.cross(a,b) < - np.finfo(np.float).eps):
        return CLOCKWISE
    if (np.dot(a,b) < - np.finfo(np.float).eps):
        return ONLINE_BACK
    if (np.linalg.norm(a)**2 < np.linalg.norm(b)**2):
        return ONLINE_FRONT
    return ON_SEGMENT

def andrewScan(s):
  u = []
  l = []
  if (len(s) < 3):
      return s
  #print(s)
  #s = np.sort([s])
  s = sorted(s)
  #print(s,len(s))
  u.append(s[0])
  u.append(s[1])
  l.append(s[len(s)-1])
  l.append(s[len(s)-2])
  for i in range(2,len(s)):
      for n in range(len(u),2-1,-1):
          if (ccw(u[n-2], u[n-1], s[i]) in [ONLINE_FRONT,CLOCKWISE]):
            break
          u.pop()
      u.append(s[i])
  #print(u)
  for i in range(len(s)-3,-1,-1):
      for n in range(len(l),2-1,-1):
          ret = ccw(l[n-2],l[n-1],s[i])
          if (ret in [CLOCKWISE,ONLINE_FRONT]):
              break
          l.pop()
      l.append(s[i])
  l = l[::-1]
  for i in range(len(u)-2,0,-1):
      l.append(u[i])
  return l

s = []
n = input()
for i in range(n):
    a = []
    a.append(map(int, raw_input().split()))
    for aa in a:
        x = aa[0]
        y = aa[1]
        s.append([x,y])

ret = andrewScan(s)
print(str(len(ret)))
out = ""
for x in ret:
    if (out):
        out = out + "\n"
    _out = ""
    for xx in x:
        if (_out):
            _out = _out + " "
        _out = _out + str(xx)
    out = out + _out
print(out)
7
2 1
0 0
1 2
2 2
4 2
1 3
3 3
5
0 0
2 1
4 2
3 3
1 3
  • In getting convex hull, you must compare the return of ccw with ONLINE_FRONT also, I think.

Refs.

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1