凸包走査アルゴリズムをPython+PyOpenGLで
オライリーから出版されている『アルゴリズムクイックリファレンス』で凸包走査アルゴリズムを学習したので、PythonとPyOpenGLで適当に点を打った点集合から凸包を計算して表示するプログラムを作成しました。
点(-1,-1)と、点(+1,+1)からなる矩形に一様乱数でランダムな点を作成してプロットしています。
- 作者: George T. Heineman,Gary Pollice,Stanley Selkow,黒川利明,黒川洋
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/04/26
- メディア: 単行本(ソフトカバー)
- 購入: 11人 クリック: 656回
- この商品を含むブログ (72件) を見る
ソース
#! /usr/bin/python2.6 # coding: utf-8 # random points convex hull from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import sys import random def clockWiseLastThree(u, p): vec = lambda i,j: (p[u[j]][0] - p[u[i]][0], p[u[j]][1] - p[u[i]][1]) v = vec(-3, -2) w = vec(-2, -1) op = v[0]*w[1] - v[1]*w[0] return op > 1e-6 def convexHullScan(p): assert len(ps) >= 3 # sort p.sort() # upper convex hull upper = [0, 1] for i in xrange(2, len(p)): upper.append(i) while len(upper) >= 3 and not clockWiseLastThree(upper, p): upper.pop(-2) # lower convex hull lower = [len(p)-1, len(p)-2] for i in xrange(len(p)-3, -1, -1): lower.append(i) while len(lower) >= 3 and not clockWiseLastThree(lower, p): lower.pop(-2) seq = upper + lower return seq ps = None indices = None def display(): glClearColor(1, 1, 1, 1) glClear(GL_COLOR_BUFFER_BIT) # plot points glColor3f(0, 0, 1) glPointSize(3) glBegin(GL_POINTS) for p in ps: glVertex2dv(p) glEnd() # plot convex hull glColor3f(1, 0, 0) glBegin(GL_LINE_LOOP) for i in indices: glVertex2dv(ps[i]) glEnd() # glutSwapBuffers() def main(): global npoints, ps, indices glutInit(sys.argv) glutCreateWindow("Convex Hull Scan Algorithm"); # app init if len(sys.argv) < 2: print 'usage: %s npoints' % __file__ return npoints = int(sys.argv[1]) f = lambda: 2.*(random.random()-.5) rp = lambda: (f(), f()) ps = [rp() for _ in xrange(npoints)] indices = convexHullScan(ps) # mainloop glutDisplayFunc(display) glutMainLoop() if __name__ == '__main__': main()