Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # edited 22 Aug 2014 to correct COG scale & print COG
- # brij-diagram.py -- Generates a PS picture of bridge assemblies.
- # Ref: <http://puzzling.stackexchange.com/questions/2138/make-a-wide-tower-of-bridge-shapes>
- # Each program parameter is 2 letters a...e plus an optional depth.
- # Eg: "cd" (or "cd0") says to connect side c of new piece to side d of
- # 0-previous piece, ie the just-previous piece. "ae2" says to connect
- # side a of new piece to side e of 2-previous piece.
- # Examples of use to generate and view three sample diagrams:
- # ./brij-diagram.py da dc ca ca ea3 > t.ps; gs t.ps
- # ./brij-diagram.py ca ae cd ca da ae2 > t.ps; gs t.ps
- # ./brij-diagram.py ee ca ca ca ca > t.ps; gs t.ps
- # Also, can make .jpg files via commands like:
- # gs -sDEVICE=jpeg -sPAPERSIZE=letter -sOutputFile=t.jpg - < t.ps
- from math import sin, cos, pi, sqrt, atan2
- import sys
- #---------------------------------------------------------
- def docInitString(bbx, bby):
- import datetime
- now = str(datetime.datetime.now())[:-7]
- return '''%!PS-Adobe-1.0
- %%Creator: brij-diagram.py
- %%Title: Show "bridge shapes" stackups
- %%CreationDate: {}
- %%Pages: (atend)
- %%DocumentFonts: NewCenturySchlbk-Bold
- %%BoundingBox: 0 0 {} {}
- %%EndComments'''.format(now, bbx, bby)
- #---------------------------------------------------------
- def fontSizeString(fsize):
- return '''% Select a font
- /NewCenturySchlbk-Bold findfont {} scalefont setfont'''.format(fsize)
- #---------------------------------------------------------
- def rotate(angle,point):
- x, y = point
- s, c = sin(angle), cos(angle)
- return (x*c-y*s, x*s+y*c)
- #---------------------------------------------------------
- def pdelta(p1, p2):
- return (p2[0]-p1[0], p2[1]-p1[1])
- #---------------------------------------------------------
- # Compute rotation angle and translation amount so that new side nside
- # coincides with old side oside. The caller can say ra, ro =
- # rotrans(oside, nside) and then for each point p in new polygon can
- # say pt = pdelta(ro, rotate(ra, p)) to get rotated/translated point pt.
- def rotrans(oside, nside):
- (b, c), (h, g) = oside, nside # Unpack side-pairs to points
- (dx, dy), (ex, ey) = pdelta(b, c), pdelta(g, h) # Get deltas of pairs
- ra = atan2(dy, dx)-atan2(ey, ex) # Get angles of sides
- gr, hr = rotate(ra, g), rotate(ra, h) # Rotate ends of new side
- ro = pdelta(c,hr) # ro+hr = c, ro+gr = b
- return ra, ro
- #---------------------------Main program-----------------
- fscale, bbx, bby = 18, 612, 612
- lmarg, rmarg, tmarg, ff = 60, 60, 60, 200
- lx, rx, by, ty = lmarg, bbx-rmarg, 30, bby-tmarg
- bwide, bhigh = 10, 18
- xscale, yscale = (rx-lx)/bwide, (ty-by)/bhigh
- scale = min(xscale, yscale)
- rx, ty = lx + bwide*scale, by + bhigh*scale
- print docInitString(bbx, bby)
- print fontSizeString(fscale)
- brij = [(0,0), (.5,sqrt(3)/2), (1.5,sqrt(3)/2), (2,0), (1,0)]
- brin, cog = ['A', 'B', 'C', 'D', 'E'], (1, sqrt(3)*2/9.)
- cogTotal = (0,0,0)
- legs = zip(brij,brij[1:]+brij[:1])
- hist = [(i,0) for i in range(6)]
- for i, item in enumerate(sys.argv[1:]):
- print '\n% Processing {}'.format(item),
- item += '0 '
- nsidel = (ord(item[0])-1) & 7
- osidel = (ord(item[1])-1) & 7
- deep = ord(item[2]) & 15
- if nsidel>4 or osidel>4 or deep>9:
- break
- print ' : new,old,deep = {} {} {}'.format(brin[nsidel], brin[osidel], deep)
- hinx = -deep*6-6+osidel
- oside = (hist[hinx], hist[hinx+1])
- nside = legs[nsidel]
- ra, ro = rotrans(oside, nside)
- print '{} {} {} setrgbcolor'.format((0==i%3)*1, (1==i%3)*1, (2==i%3)*1)
- (ox, oy) = pdelta(ro, rotate(ra, brij[0]))
- hist.append((ox, oy))
- print '{:3.1f} {:3.1f} moveto'.format(ff+lx+scale*ox, by+scale*oy),
- for p in brij[1:]:
- (px, py) = pdelta(ro, rotate(ra, p))
- hist.append((px, py))
- print ' {:3.1f} {:3.1f} lineto'.format(ff+lx+scale*px, by+scale*py),
- hist.append((ox, oy))
- print ' fill'
- (px, py) = pdelta(ro, rotate(ra, cog))
- print '0 0 0 setrgbcolor {:3.1f} {:3.1f} moveto (.{}) show'.format(ff+lx+scale*px, by+scale*py, i)
- cogTotal = (cogTotal[0]+px, cogTotal[1]+py, cogTotal[2]+1)
- 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)
- 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])
- print fontSizeString(3*fscale)
- 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)
- print 'showpage'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement