#!/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('') print('') 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'') 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'') 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'') 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'') #delta_a = marker_angle - angle #ex, ey = px, py #print(f'') #print(delta_a, file=sys.stderr) # delta_a + math.pi/2 print('') 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)