diff --git a/axi/drawing.py b/axi/drawing.py index 5577329..2985ecb 100644 --- a/axi/drawing.py +++ b/axi/drawing.py @@ -3,7 +3,8 @@ from __future__ import division from math import sin, cos, radians from .paths import ( - simplify_paths, sort_paths, join_paths, crop_paths, convex_hull) + simplify_paths, sort_paths, join_paths, crop_paths, convex_hull, + expand_quadratics) try: import cairo @@ -19,10 +20,11 @@ class Drawing(object): def loads(cls, data): paths = [] for line in data.split('\n'): - points = line.strip().split() - points = [map(float, x.split(',')) for x in points] - if points: - paths.append(points) + path = line.strip().split() + path = [map(float, x.split(',')) for x in path] + path = expand_quadratics(path) + if path: + paths.append(path) return cls(paths) @classmethod diff --git a/axi/main.py b/axi/main.py index d3a0fa0..55e39cd 100644 --- a/axi/main.py +++ b/axi/main.py @@ -12,6 +12,15 @@ def main(): return command, args = args[0], args[1:] command = command.lower() + if command == 'render': + d = axi.Drawing.load(args[0]) + d = d.rotate_and_scale_to_fit(12, 8.5, step=90) + path = args[1] if len(args) > 1 else 'out.png' + im = d.render( + scale=109 * 1, line_width=0.25/25.4) + # show_axi_bounds=False, use_axi_bounds=False) + im.write_to_png(path) + return device = axi.Device() if command == 'zero': device.zero_position() diff --git a/axi/paths.py b/axi/paths.py index c8400d9..56de34f 100644 --- a/axi/paths.py +++ b/axi/paths.py @@ -119,3 +119,35 @@ def convex_hull(points): if isinstance(hull, geometry.Point): return list(hull.coords) raise Exception('unhandled convex hull geometry') + +def quadratic_path(x0, y0, x1, y1, x2, y2): + n = int(hypot(x1 - x0, y1 - y0) + hypot(x2 - x1, y2 - y1)) + n = max(n, 4) + points = [] + m = 1 / float(n - 1) + for i in range(n): + t = i * m + u = 1 - t + a = u * u + b = 2 * u * t + c = t * t + x = a * x0 + b * x1 + c * x2 + y = a * y0 + b * y1 + c * y2 + points.append((x, y)) + return points + +def expand_quadratics(path): + result = [] + previous = (0, 0) + for point in path: + if len(point) == 2: + result.append(point) + previous = point + elif len(point) == 4: + x0, y0 = previous + x1, y1, x2, y2 = point + result.extend(quadratic_path(x0, y0, x1, y1, x2, y2)) + previous = (x2, y2) + else: + raise Exception('invalid point: %r' % point) + return result