diff options
Diffstat (limited to 'examples/highlight_outline.py')
-rw-r--r-- | examples/highlight_outline.py | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/examples/highlight_outline.py b/examples/highlight_outline.py new file mode 100644 index 0000000..a73b79b --- /dev/null +++ b/examples/highlight_outline.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 + +import math +import sys + +from gerbonara import LayerStack +from gerbonara.graphic_objects import Line, Arc +from gerbonara.apertures import CircleAperture +from gerbonara.utils import MM + +def highlight_outline(input_dir, output_dir): + #stack = LayerStack.from_directory(input_dir) + + #outline = [] + #for obj in stack.outline.objects: + # if isinstance(obj, Line): + # outline.append(obj) +# +# elif isinstance(obj, Arc): +# outline += obj.approximate(0.1, 'mm') + + # FIXME test code + print('<?xml version="1.0" encoding="utf-8"?>') + print('<svg width="300mm" height="300mm" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">') + from gerbonara.utils import rotate_point + outline = [] + for i in range(16): + for j in range(16): + cx, cy = i*3, j*3 + w = i/8 + angle = j*2*math.pi/16 + x1, y1 = cx-w/2, cy + x2, y2 = cx+w/2, cy + + x1, y1 = rotate_point(x1, y1, angle, cx, cy) + x2, y2 = rotate_point(x2, y2, angle, cx, cy) + + outline.append(Line(x1, y1, x2, y2, aperture=CircleAperture(1.0, unit=MM), unit=MM)) + print(f'<path style="stroke: red; stroke-width: 0.01mm;" d="M {x1} {y1} L {x2} {y2}"/>') + + marker_angle = math.pi/4 + marker_spacing = 0.2 + marker_width = 0.01 + + marker_dx, marker_dy = math.sin(marker_angle)*marker_spacing, -math.cos(marker_angle)*marker_spacing + marker_nx, marker_ny = math.sin(marker_angle), math.cos(marker_angle) + + for line in outline: + cx, cy = (line.x1 + line.x2)/2, (line.y1 + line.y2)/2 + dx, dy = line.x1 - cx, line.y1 - cy + + angle = math.atan2(dy, dx) + r = math.hypot(dx, dy) + if r == 0: + continue + + cr = math.hypot(cx, cy) + w = line.aperture.equivalent_width('mm') + + tl_x, tl_y = line.x1 + math.sin(angle)*w/2, line.y1 - math.cos(angle)*w/2 + tr_x, tr_y = line.x2 + math.sin(angle)*w/2, line.y2 - math.cos(angle)*w/2 + br_x, br_y = line.x2 - math.sin(angle)*w/2, line.y2 + math.cos(angle)*w/2 + bl_x, bl_y = line.x1 - math.sin(angle)*w/2, line.y1 + math.cos(angle)*w/2 + + tr = math.dist((tl_x, tl_y), (br_x, br_y))/2 + + print(f'<path style="stroke: red; stroke-width: 0.01mm; fill: none;" d="M {tl_x} {tl_y} L {tr_x} {tr_y} L {br_x} {br_y} L {bl_x} {bl_y} Z"/>') + + rot_cx, rot_cy = rotate_point(cx, cy, -marker_angle) + offx = (rot_cy % marker_spacing) / marker_spacing + n = math.ceil(tr/marker_spacing) + for i in range(-n, n+1): + px, py = cx + (i+offx)*marker_dx, cy + (i+offx)*marker_dy + + lx1, ly1 = px + tr*marker_nx, py + tr*marker_ny + lx2, ly2 = px - tr*marker_nx, py - tr*marker_ny + + lx1, ly1 = rotate_point(lx1, ly1, angle, cx, cy) + lx2, ly2 = rotate_point(lx2, ly2, angle, cx, cy) + #print(f'<circle style="fill: blue; stroke: none;" r="{marker_spacing/2}" cx="{px}" cy="{py}"/>') + + def clip_line_point(x1, y1, x2, y2, xabs, yabs): + print(x1, y1, x2, y2, end=' -> ', file=sys.stderr) + if x2 != x1: + a = (y2 - y1) / (x2 - x1) + x2 = min(xabs, max(-xabs, x2)) + y2 = y1 + a*(x2 - x1) + + elif abs(x1) > xabs: + return None + + if y2 != y1: + a = (x2 - x1) / (y2 - y1) + y2 = min(yabs, max(-yabs, y2)) + x2 = x1 + a*(y2 - y1) + + elif abs(y1) > yabs: + return None + + print(x1, y1, x2, y2, file=sys.stderr) + return x1, y1, x2, y2 + + if not (foo := clip_line_point(lx1-cx, ly1-cy, lx2-cx, ly2-cy, r, w/2)): + continue + lx1, ly1, lx2, ly2 = foo + + if not (foo := clip_line_point(lx2, ly2, lx1, ly1, r, w/2)): + continue + lx1, ly1, lx2, ly2 = foo + + lx1, ly1, lx2, ly2 = lx1+cx, ly1+cy, lx2+cx, ly2+cy + + lx1, ly1 = rotate_point(lx1, ly1, -angle, cx, cy) + lx2, ly2 = rotate_point(lx2, ly2, -angle, cx, cy) + + print(f'<path style="stroke: blue; stroke-width: 0.01mm; opacity: 0.2;" d="M {lx1} {ly1} L {lx2} {ly2}"/>') + + #delta_a = marker_angle - angle + #ex, ey = px, py + #print(f'<circle style="fill: blue; stroke: none;" r="{marker_spacing/5}" cx="{ex}" cy="{ey}"/>') + #print(delta_a, file=sys.stderr) + # delta_a + math.pi/2 + + print('</svg>') + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('input') + parser.add_argument('output') + args = parser.parse_args() + highlight_outline(args.input, args.output) |