# Demonstrates the use of add_bitmap and image from miniipe import Document, Matrix, Scale, Stretch, Rotate, Translate from base64 import b64encode doc = Document() doc.import_stylefile() doc.add_layout(page=(90, 160)) # First define a bitmap in the Ipe style. Images are identified by an integer id. # We don't really provide any convenience features for bitmap images. There # are other options, but here we show the basic usage: a base64-encoded jpeg. # Note that the actual image data is included in the Ipe file, not just a reference. image_id = 1 filename = 'logo.jpg' width = 635 height = 433 with open(filename, 'rb') as f: jpg = f.read() blob = b64encode(jpg).decode('utf-8') doc.add_bitmap(image_id, width, height, blob=blob, Filter='DCTDecode', encoding='base64', length=len(blob)) # Then put the image on the page. This supports transformation matrices. doc.image(image_id, (0, 0) + (width, height), matrix=Translate((1, 116)) @ Scale(0.1))
# Demonstrates various kinds of splines in Ipe. from miniipe import Document, polyline, spline, cardinal_spline, clothoid, splinegon doc = Document() doc.import_stylefile() doc.add_layout(page=(400, 400)) # Basic shape ps = [(100, 100), (100, 300), (200, 300), (200, 200), (300, 200), (300, 100)] # Normal splines, which are B-splines doc.add_layer('spline') doc.path(spline(ps), stroke='red', layer='spline') # A closed polygon, but as a B-spline doc.add_layer('splinegon') doc.path(splinegon(ps), stroke='orange', layer='splinegon') # Cardinal splines are also available, with variable tension [0,1] doc.add_layer('cardinal spline') for t in range(11): doc.path(cardinal_spline(ps, t / 10), stroke='lightblue', layer='cardinal spline') # Clothoids are really cool interpolating splines doc.add_layer('clothoid') doc.path(clothoid(ps), stroke='blue', layer='clothoid') # Overlay the control points
# Demonstrates various features in one drawing. from miniipe import Document, RotateAt, Matrix, polyline, ellipse # Make a miniipe.Document doc = Document() doc.import_stylefile() doc.add_layout(page=(620, 850)) doc.add_layer('alpha') # Text doc.text('Hello, this is miniipe!', pos=(64, 768), size='Huge') # Plot a function doc.add_layer('plot') from math import sin, cos, atan2, pi def f(x): return 400 + x * sin(x / 30) points = [(x, f(x)) for x in range(500)] doc.path(polyline(points), stroke='black', layer='plot') # Place a symbol every so many points fewer_points = points[::40] doc.add_layer('points') for p in fewer_points: doc.use(pos=p, layer='points')
# Demonstrates making and using symbols from miniipe import Document, symbol_name, segment, circle, arc from math import pi doc = Document() doc.add_layout(page=(48, 48)) ### A diagonal cross symbol # Symbols have a name. If you want them to show up in the marks # list in the Ipe interface, they must start with 'mark/' x = symbol_name('mark/x') # Add a symbol with this name to the style x_symbol = doc.add_symbol(x) # A symbol can only contain a single object. # We want two lines, so we nest it in a group x_group = doc.group(parent=x_symbol) doc.path(segment((-1, -1), (1, 1)), parent=x_group) doc.path(segment((1, -1), (-1, 1)), parent=x_group) # Now put it on the page a couple of times doc.use(x, pos=(16, 16)) doc.use(x, pos=(16, 32)) doc.use(x, pos=(32, 16)) doc.use(x, pos=(32, 32)) ### A scalable circle symbol # Whether a symbol reacts to scale depends on its name. o = symbol_name('mark/o', size=True)
b = [ val for e in edges for val in (sqrt(e[2]**2+e[3]**2),0) ] + [0,0] # Solve least squares problem by solving Gauß normal form: `A^T A positions = A^T b` AtA = A.transpose()*A Atb = A.transpose()*b positions = sparse_solve(AtA,Atb) # read the solution and apply scale scale = float(arguments['--scale']) pos = [ (scale*positions[x_var(i)],scale*positions[y_var(i)]) for i in range(n) ] ## Output if( arguments['--ipe']): from miniipe import Document, polyline doc = Document() doc.import_stylefile() doc.add_layer('edges') doc.add_layer('nodes') doc.add_layer('labels') for e in edges: doc.path( polyline([ pos[e[0]], pos[e[1]] ]), layer='edges' ) for i, p in enumerate(pos): doc.use( pos=p, layer='nodes' ) doc.text( str(old_name[i]), pos=p, layer='labels') print(doc.tostring()) else: # not ipe for i, p in enumerate(pos): print( old_name[i], p[0], p[1] )
# Demonstrates the use of transformation matrices. from miniipe import Document, Rotate, Translate, Scale, polyline doc = Document() doc.import_stylefile() doc.add_layout( page=(640,640) ) doc.add_layer('alpha') # Iteratively tweak a transformation matrix. # (Matrix multiplication with the @ operator.) ps = [(10,0),(20,0),(19,1),(19,-1),(20,0)] M = Translate( (300,300) ) for _ in range(207): doc.use( pos=(0,0), name='mark/cross(sx)', matrix=M ) doc.path( polyline(ps), matrix=M) M @= Rotate(0.1) @ Translate( (3,1) ) @ Scale(1.01) doc.write('matrix_fun.ipe')
# Demonstrates the use of arcs and wedges from miniipe import Document, Translate, Scale, rectangle, circle, arc from math import pi doc = Document() doc.import_stylefile() doc.add_layout(page=(400, 320)) doc.add_layer('waves') for r in range(1, 15): doc.path(arc((0, 0), r * r, 0, pi / 2), stroke='lightblue', opacity='50%', pen='ultrafat', layer='waves') doc.path(arc((200, 0), r * r, 0, pi), stroke='lightblue', opacity='50%', pen='ultrafat', layer='waves') doc.path(arc((400, 0), r * r, pi, pi / 2, cw=True), stroke='lightblue', opacity='50%', pen='ultrafat', layer='waves') dropshadow = Translate((0, -5)) doc.add_layer('pie')
from miniipe import Document, Path, Translate, segment, arc_fromto from math import sqrt doc = Document() doc.add_layout(page=(1536, 320)) p1 = (100, 100) p2 = (100, 200) p3 = (200, 200) doc.text('Use helper functions for separate paths.', pos=(128, 32), halign='center') doc.path(segment(p1, p2), pen=16) doc.path(arc_fromto(p1, p2, p3, cw=True), pen=16) doc.path(segment(p3, p1), pen=16) M = Translate((256, 0)) doc.text('Use helper functions and concatenate; make 1 object.', pos=(128, 32), halign='center', matrix=M) instructions = segment(p1, p2) + arc_fromto(p1, p2, p3, cw=True) + segment( p3, p1) doc.path(instructions, matrix=M, pen=16) M = Translate((512, 0)) doc.text('Use Path object; `move\' everywhere.', pos=(128, 32), halign='center', matrix=M)
# A very small example. It draws a triangle. from miniipe import Document, polygon # Make a miniipe.Document. doc = Document() # Ipe files usually need a style file. # If this line gives an error, check the README. doc.import_stylefile() # Add a layer. doc.add_layer('my layer') # Draw a triangle. ps = [(100, 100), (200, 200), (300, 100)] doc.path(polygon(ps), stroke='black', layer='my layer') # Write it to a file. doc.write('simple.ipe')
# Demonstrates defining custom styles: does not include the # basic Ipe style file and instead makes some other styles. from miniipe import Document, add_gradient_stop, sort_gradient, rectangle, polygon doc = Document() doc.add_layout(page=(400, 400)) doc.add_gridsize('quarters', 25) doc.add_gridsize('hundreds', 100) gradient = doc.add_gradient('my gradient', type_='axial', coords='0 0 400 400') add_gradient_stop(gradient, 1, '0.5 0.5 1') add_gradient_stop(gradient, 0, '1 0.5 0.5') # Gradients need to be sorted by offset, or you'll get a 'parse error' from Ipe # Just do it correctly yourself, or use sort_gradient. sort_gradient(gradient) doc.path(rectangle((0, 0), (400, 400)), gradient='my gradient', fill='1') doc.add_color_rgb('my color', 1, 0.8, 0) doc.add_color_rgb('my other color', 0, 0.1, 1) doc.add_pen('my pen', 5) doc.add_dashstyle('dashing', '[6 1 5 1 4 1 3 2 1 2 1 3 1 4 1 5 1] 0') doc.add_tiling('my tiling', 45, 5, 2) ps = [(100, 100), (200, 300), (300, 100)] doc.path(polygon(ps), pen='my pen', stroke='my color',
# Test our own matrix transformation versus letting Ipe do it. # Both layers should look the same. from miniipe import Document, Matrix, polygon from random import random doc = Document() doc.import_stylefile() doc.add_layout( page=(200,200) ) doc.add_layer('ipe') doc.add_layer('miniipe') # basic rectangle ps = [(-20,-20) ,( 20,-20) ,( 20, 20) ,(-20, 20)] for _ in range(100): # random matrix M = Matrix( 2*random()-1, 2*random()-1, 2*random()-1, 2*random()-1, 200*random(), 200*random()) # just give the matrix to Ipe doc.path( polygon(ps), matrix=M, stroke='lightblue', pen='ultrafat', layer='ipe') # or transform it ourselves using Matrix.transform tps = list(map( lambda p: M.transform(p), ps )) doc.path( polygon(tps), stroke='blue', layer='miniipe' ) doc.write('transform.ipe')