Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

is_square?

By: ploffie on Jan 2nd, 2013  |  syntax: Python  |  size: 2.46 KB  |  views: 53  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. from  itertools import combinations
  2.  
  3. def distsq(p1, p2):
  4.     x1, y1 = p1
  5.     x2, y2 = p2
  6.     return (x2 - x1) ** 2 + (y2 - y1) ** 2
  7.    
  8. def is_square(p1, p2, p3, p4):
  9.     # check for double points first
  10.     if any(a == b for a, b in combinations((p1, p2, p3, p4), 2)):
  11.         return False
  12.     dis = [distsq(p1, p) for p in (p2, p3, p4)]
  13.     pmin = min(dis)
  14.     pmax = max(dis)
  15.     if not (pmax == 2 * pmin and dis.count(pmin) == 2):
  16.         return False
  17.     # find point furthest away and assert that distances of that point to the 2
  18.     #  remaining points are the same as pmin
  19.     far_pt = (p2, p3, p4)[dis.index(pmax)]
  20.     return all(distsq(far_pt, p) == pmin for p in (p2, p3, p4) if p != far_pt)
  21.        
  22. if __name__ == "__main__":
  23.     """random test against brute force function (is_square0)"""
  24.     import random
  25.     ran = random.randint
  26.     X = 5
  27.  
  28.     def sub(a, b):
  29.         return (a[0] -  b[0], a[1] - b[1])
  30.  
  31.     def add(a, b):
  32.         return (a[0] +  b[0], a[1] + b[1])
  33.  
  34.     def is_square0(p1, p2, p3, p4):
  35.         """for testing - check everything to death"""
  36.         if any(a == b for a, b in combinations((p1,p2,p3,p4), 2)):
  37.             return False
  38.         dis = [distsq(p1, p) for p in (p2,p3,p4)]
  39.         pmin = min(dis)
  40.         pmax = max(dis)
  41.         if not (pmax == (2 * pmin) and dis.count(pmin) == 2):
  42.             return False
  43.         dis = [distsq(p2, p) for p in (p1, p3,p4)]
  44.         if not (pmin == min(dis) and pmax == max(dis)):
  45.             return False
  46.         dis = [distsq(p3, p) for p in (p1, p2,p4)]
  47.         if not (pmin == min(dis) and pmax == max(dis)):
  48.             return False
  49.         dis = [distsq(p4, p) for p in (p1, p3,p2)]
  50.         if not (pmin == min(dis) and pmax == max(dis)):
  51.             return False
  52.         return True
  53.          
  54.     def rect():
  55.         b = a = (ran(-X, X), ran(-X, X))
  56.         while a == b:
  57.             b = (ran(-X, X), ran(-X, X))
  58.         dx,dy = sub(b, a)
  59.         c = add(a, (dy, -dx))
  60.         d = add(b, (dy, -dx))
  61.         return a, b, c, d
  62.        
  63.     def norect():
  64.         """random - still could be rect"""
  65.         return [(ran(-X, X), ran(-X, X)) for i in range(4)]
  66.        
  67.     for i in range(20):    
  68.         q= rect()
  69.         assert is_square(*q), "{:d} {:s}".format(i, str(q))
  70.        
  71.     for i in range(20000):    
  72.         q= norect()
  73.         s1 = is_square(*q)
  74.         s2 = is_square0(*q)
  75.         assert s1 == s2, str(s1) + " " + str(s2) + " " + str(q)
  76.     print "OK"
clone this paste RAW Paste Data