Advertisement
Guest User

python code for 2D circle-surface

a guest
Oct 24th, 2013
872
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import pygame
  2. import random
  3. import math
  4.  
  5. pygame.init()
  6.  
  7. screen = pygame.display.set_mode([300,300])
  8.  
  9. def random_point_coud_2D(n, radius=10, deviation=3):
  10.     pts = [(0, 0)]*n
  11.     for i in range(n):
  12.         angle = random.random() * 2 * math.pi
  13.         rad = random.gauss(radius, deviation)
  14.         pts[i] = (math.cos(angle)*rad, math.sin(angle)*rad)
  15.     return pts
  16.  
  17. def translate_pts(pts, shift):
  18.     return [(pt[0] + shift[0], pt[1] + shift[1])for pt in pts]
  19.  
  20. def translate_edges(edges, shift):
  21.     tx, ty = shift
  22.     return [((ptA[0] + tx, ptA[1] + ty), (ptB[0] + tx, ptB[1] + ty)) for (ptA, ptB) in edges]
  23.  
  24. def pt_center(pts):
  25.     if(len(pts) == 0):
  26.         return (0,0)
  27.     sum_x = 0
  28.     sum_y = 0
  29.     for (x, y) in pts:
  30.         sum_x += x
  31.         sum_y += y
  32.     return (sum_x / len(pts), sum_y / len(pts))
  33.  
  34. def dot(ptA, ptB):
  35.     return ptA[0]*ptB[0] + ptA[1]*ptB[1]
  36.  
  37. def crossz(ptA, ptB):
  38.     return ptA[0]*ptB[1] - ptA[1]*ptB[0]
  39.  
  40. def norm(vec):
  41.     l = math.sqrt(vec[0]*vec[0] + vec[1]*vec[1])
  42.     return (vec[0] / l, vec[1] / l)
  43.  
  44. def point_in_triangle(pt, edges):
  45.     for (ptA, ptB) in edges:
  46.         vecside = norm((ptB[0]-ptA[0], ptB[1]-ptA[1]))
  47.         vecpt = norm((pt[0]-ptA[0], pt[1]-ptA[1]))
  48.         side = (crossz(vecside, vecpt) > 0) # pt is on correct side of this edge
  49.         proj = 0 <= dot(vecside, vecpt) and dot(vecside, vecpt) <= 1 # pt lies between A and B in projection
  50.         if(not (side and proj)):
  51.             # test failed for any edge.. fails overall
  52.             return False
  53.     return True
  54.  
  55. # this is a hack. horrible n^3 time
  56. def get_center_triangle(pts):
  57.     # sort points in terms of angle from x-axis
  58.     pts.sort( cmp=lambda (ax, ay), (bx, by): cmp(math.atan2(ay, ax), math.atan2(by, bx)))
  59.     # test every combination of 3 points
  60.     for i in range(len(pts)):
  61.         ptA = pts[i]
  62.         for j in range(len(pts)):
  63.             if j == i:
  64.                 continue
  65.             ptB = pts[j]
  66.             for k in range(len(pts)):
  67.                 if k == j or k == i:
  68.                     continue
  69.                 ptC = pts[k]
  70.                 if point_in_triangle((0,0), [(ptA, ptB), (ptB, ptC), (ptC, ptA)]):
  71.                     return (ptA, ptB, ptC)
  72.     print "NO CENTER TRIANGLE FOUND"
  73.     return None
  74.  
  75. def surface(pts):
  76.     center = pt_center(pts)
  77.     tx = -center[0]
  78.     ty = -center[1]
  79.     pts = translate_pts(pts, (tx, ty))
  80.     # tricky part: initialization
  81.     # initialize edges such that you have a triangle with the origin inside of it
  82.     # in 3D, this will be a tetrahedron.
  83.     ptA, ptB, ptC = get_center_triangle(pts)
  84.     print ptA, ptB, ptC
  85.     # tracking edges we've already included (triangles in 3D)
  86.     edges = [(ptA, ptB), (ptB, ptC), (ptC, ptA)]
  87.     # loop over all other points
  88.     pts.remove(ptA)
  89.     pts.remove(ptB)
  90.     pts.remove(ptC)
  91.     draw_scene(translate_pts(pts, (-tx, -ty)), translate_edges(edges, (-tx, -ty)))
  92.     pygame.event.wait()
  93.     for pt in pts:
  94.         ptA = (0,0)
  95.         ptB = (0,0)
  96.         # find the edge that this point will be splitting
  97.         for (ptA, ptB) in edges:
  98.             if crossz(ptA, pt) > 0 and crossz(pt, ptB) > 0:
  99.                 break
  100.         edges.remove((ptA, ptB))
  101.         edges.append((ptA, pt))
  102.         edges.append((pt, ptB))
  103.         draw_scene(translate_pts(pts, (-tx, -ty)), translate_edges(edges, (-tx, -ty)))
  104.         pygame.event.wait()
  105.  
  106.     # translate everything back
  107.     edges = translate_edges(edges, (-tx, -ty))
  108.     return edges
  109.  
  110. # PYGAME/GRAPHICS
  111.  
  112. def clear_screen():
  113.     screen.fill([255,255,255])
  114.  
  115. def draw_pts(pts, clear=True, size=1):
  116.     if clear:
  117.         clear_screen()
  118.     for pt in pts:
  119.         pygame.draw.circle(screen, (0, 0, 0), (int(pt[0]), int(pt[1])), size)
  120.  
  121. def draw_lines(lines, clear=True, size=1):
  122.     if(clear):
  123.         clear_screen()
  124.     for line in lines:
  125.         pygame.draw.line(screen, (0,0,0), (int(line[0][0]), int(line[0][1])), (int(line[1][0]), int(line[1][1])), size)
  126.  
  127. def draw_scene(pts, lines):
  128.     draw_pts(pts, size=3)
  129.     draw_lines(lines, clear=False)
  130.     pygame.display.update()
  131.  
  132. if __name__ == '__main__':
  133.     pts = random_point_coud_2D(100, radius=100, deviation=10)
  134.     pts = translate_pts(pts, (150, 150))
  135.     # draw_scene(pts, [])
  136.     # pause = raw_input()
  137.     draw_scene(pts, surface(pts))
  138.     pygame.image.save(screen, '/home/richard/Documents/code/SillyCode/point_cloud_demo.jpg')
  139.     pygame.quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement