SHARE
TWEET

brij-diagram.py

jwpb7 Aug 21st, 2014 313 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2. # edited 22 Aug 2014 to correct COG scale & print COG
  3. # brij-diagram.py -- Generates a PS picture of bridge assemblies.
  4. # Ref: <http://puzzling.stackexchange.com/questions/2138/make-a-wide-tower-of-bridge-shapes>
  5.  
  6. # Each program parameter is 2 letters a...e plus an optional depth.
  7. # Eg: "cd" (or "cd0") says to connect side c of new piece to side d of
  8. # 0-previous piece, ie the just-previous piece.  "ae2" says to connect
  9. # side a of new piece to side e of 2-previous piece.
  10.  
  11. # Examples of use to generate and view three sample diagrams:
  12. #   ./brij-diagram.py da dc ca ca ea3 > t.ps; gs t.ps
  13. #   ./brij-diagram.py ca ae cd ca da ae2 > t.ps; gs t.ps
  14. #   ./brij-diagram.py ee ca ca ca ca > t.ps; gs t.ps
  15. # Also, can make .jpg files via commands like:
  16. # gs -sDEVICE=jpeg -sPAPERSIZE=letter -sOutputFile=t.jpg - < t.ps
  17.  
  18. from math import sin, cos, pi, sqrt, atan2
  19. import sys
  20. #---------------------------------------------------------
  21. def docInitString(bbx, bby):
  22.     import datetime
  23.     now = str(datetime.datetime.now())[:-7]
  24.     return '''%!PS-Adobe-1.0
  25. %%Creator: brij-diagram.py
  26. %%Title: Show "bridge shapes" stackups
  27. %%CreationDate: {}
  28. %%Pages: (atend)
  29. %%DocumentFonts: NewCenturySchlbk-Bold
  30. %%BoundingBox: 0 0 {} {}
  31. %%EndComments'''.format(now, bbx, bby)
  32. #---------------------------------------------------------
  33. def fontSizeString(fsize):
  34.     return '''% Select a font
  35. /NewCenturySchlbk-Bold findfont {} scalefont setfont'''.format(fsize)
  36. #---------------------------------------------------------
  37. def rotate(angle,point):
  38.     x, y = point
  39.     s, c = sin(angle), cos(angle)
  40.     return (x*c-y*s, x*s+y*c)
  41. #---------------------------------------------------------
  42. def pdelta(p1, p2):
  43.     return (p2[0]-p1[0], p2[1]-p1[1])
  44. #---------------------------------------------------------
  45. # Compute rotation angle and translation amount so that new side nside
  46. # coincides with old side oside. The caller can say ra, ro =
  47. # rotrans(oside, nside) and then for each point p in new polygon can
  48. # say pt = pdelta(ro, rotate(ra, p)) to get rotated/translated point pt.
  49. def rotrans(oside, nside):
  50.     (b, c),   (h, g)   = oside, nside     # Unpack side-pairs to points
  51.     (dx, dy), (ex, ey) = pdelta(b, c), pdelta(g, h) # Get deltas of pairs
  52.     ra = atan2(dy, dx)-atan2(ey, ex)      # Get angles of sides
  53.     gr, hr = rotate(ra, g), rotate(ra, h) # Rotate ends of new side
  54.     ro = pdelta(c,hr)                     # ro+hr = c, ro+gr = b
  55.     return ra, ro
  56. #---------------------------Main program-----------------
  57. fscale, bbx, bby = 18, 612, 612
  58. lmarg, rmarg, tmarg, ff = 60, 60, 60, 200
  59. lx, rx, by, ty = lmarg, bbx-rmarg, 30, bby-tmarg
  60. bwide, bhigh = 10, 18
  61. xscale, yscale = (rx-lx)/bwide, (ty-by)/bhigh
  62. scale = min(xscale, yscale)
  63. rx, ty = lx + bwide*scale, by + bhigh*scale
  64. print docInitString(bbx, bby)
  65. print fontSizeString(fscale)
  66. brij = [(0,0), (.5,sqrt(3)/2), (1.5,sqrt(3)/2), (2,0), (1,0)]
  67. brin, cog = ['A', 'B', 'C', 'D', 'E'], (1, sqrt(3)*2/9.)
  68. cogTotal = (0,0,0)
  69. legs = zip(brij,brij[1:]+brij[:1])
  70. hist = [(i,0) for i in range(6)]
  71.  
  72. for i, item in enumerate(sys.argv[1:]):
  73.     print '\n% Processing  {}'.format(item),
  74.     item += '0  '
  75.     nsidel = (ord(item[0])-1) & 7
  76.     osidel = (ord(item[1])-1) & 7
  77.     deep = ord(item[2]) & 15
  78.     if nsidel>4 or osidel>4 or deep>9:
  79.         break
  80.     print ' :  new,old,deep = {} {} {}'.format(brin[nsidel], brin[osidel], deep)
  81.     hinx = -deep*6-6+osidel
  82.     oside = (hist[hinx], hist[hinx+1])
  83.     nside = legs[nsidel]
  84.     ra, ro = rotrans(oside, nside)
  85.     print '{} {} {} setrgbcolor'.format((0==i%3)*1, (1==i%3)*1, (2==i%3)*1)
  86.     (ox, oy) = pdelta(ro, rotate(ra, brij[0]))
  87.     hist.append((ox, oy))
  88.     print '{:3.1f} {:3.1f} moveto'.format(ff+lx+scale*ox, by+scale*oy),
  89.     for p in brij[1:]:
  90.         (px, py) = pdelta(ro, rotate(ra, p))
  91.         hist.append((px, py))
  92.         print ' {:3.1f} {:3.1f} lineto'.format(ff+lx+scale*px, by+scale*py),
  93.     hist.append((ox, oy))
  94.     print ' fill'
  95.     (px, py) = pdelta(ro, rotate(ra, cog))
  96.     print '0 0 0 setrgbcolor {:3.1f} {:3.1f} moveto (.{}) show'.format(ff+lx+scale*px, by+scale*py, i)
  97.     cogTotal = (cogTotal[0]+px, cogTotal[1]+py, cogTotal[2]+1)
  98.     print '0.3 0.2 0.1 setrgbcolor {:3.1f} {:3.1f} moveto (*) show'.format(ff+lx+scale*cogTotal[0]/cogTotal[2]-fscale/8, by+scale*cogTotal[1]/cogTotal[2]-fscale/2)
  99.     print '% new COG = ( {:6.3f}, {:6.3f} ), ox ox = {:8.3f} {:8.3f}'.format(cogTotal[0]/cogTotal[2], cogTotal[1]/cogTotal[2], oside[0][0], oside[1][0])
  100.  
  101. print fontSizeString(3*fscale)
  102. print '0.3 0.2 0.1 setrgbcolor {:3.1f} {:3.1f} moveto (*) show'.format(ff+lx+scale*cogTotal[0]/cogTotal[2]-fscale/3, by+scale*cogTotal[1]/cogTotal[2]-1.5*fscale)
  103. print 'showpage'
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top