def bench_gdstk(output=None): r = 0.15 c1 = gdstk.Curve((1 / 2 - r, -(3**0.5) / 6), 1e-3) c1.arc(r, numpy.pi, numpy.pi * 2 / 3) c1.segment((1 - 2 * r) * numpy.exp(1j * numpy.pi * 2 / 3), relative=True) c1.arc(r, -numpy.pi / 3, -numpy.pi * 2 / 3) c1.segment((1 - 2 * r) * numpy.exp(-1j * numpy.pi * 2 / 3), relative=True) c1.arc(r, numpy.pi / 3, 0) p1 = gdstk.Polygon(c1.points()) c2 = gdstk.Curve((0, -r), 1e-3) c2.interpolation( [ 2 * r * numpy.exp(-1j * numpy.pi / 6), r * numpy.exp(1j * numpy.pi / 6), (0, 2 * r), r * numpy.exp(1j * numpy.pi * 5 / 6), 2 * r * numpy.exp(-1j * numpy.pi * 5 / 6), ], cycle=True, ) p2 = gdstk.Polygon(c2.points(), layer=1) if output: cell = gdstk.Cell("MAIN") cell.add(p1, p2) cell.write_svg(output, 300)
def bezier_image(): points = [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4), (0, 0)] curve = gdstk.Curve((0, 0)) curve.segment(points) control_poly = gdstk.Polygon(curve.points(), datatype=1) curve = gdstk.Curve((0, 0), tolerance=1e-3) curve.bezier(points) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("bezier").add(polygon, control_poly)
def test_init(): curve = gdstk.Curve(1j) assert curve.tolerance == 1e-2 curve.tolerance = 1e-1 assert curve.tolerance == 1e-1 numpy.testing.assert_array_equal(curve.points(), [[0, 1]]) curve = gdstk.Curve((4, 5), 1e-3) assert curve.tolerance == 1e-3 numpy.testing.assert_array_equal(curve.points(), [[4, 5]])
def arc_image(): curve = gdstk.Curve((-0.6, 0), tolerance=1e-3) curve.segment((1, 0), True) curve.arc(1, 0, numpy.pi / 2) polygon_1 = gdstk.Polygon(curve.points()) curve = gdstk.Curve((0.6, 0), tolerance=1e-3) curve.segment((1, 0), True) curve.arc((2**-0.5, 0.4), -numpy.pi / 4, 3 * numpy.pi / 4, -numpy.pi / 4) polygon_2 = gdstk.Polygon(curve.points()) return gdstk.Cell("arc").add(polygon_1, polygon_2)
def tolerance_image(): curve = gdstk.Curve((-2.5, 0), tolerance=1e-1) curve.arc((2, 3), 0, numpy.pi) polygon_1 = gdstk.Polygon(curve.points()) # print(polygon_1.size) curve = gdstk.Curve((2.5, 0), tolerance=1e-3) curve.arc((2, 3), 0, numpy.pi) polygon_2 = gdstk.Polygon(curve.points()) # print(polygon_2.size) return gdstk.Cell("tolerance").add(polygon_1, polygon_2)
def test_points(): points = [(0, 1), (1, 0), (-1, -1)] curve = gdstk.Curve(points[0]) curve.segment(points[1]) numpy.testing.assert_array_equal(curve.points(), points[:2]) curve.segment(points[2]) numpy.testing.assert_array_equal(curve.points(), points) points = [(0, 1), (1, 0), (1, 0), (-1, -1), (0.02, 1.02)] curve = gdstk.Curve(points[0], 1e-1) curve.segment(points[1:]) numpy.testing.assert_array_equal(curve.points(), points[:-1])
def render_text(text, size=None, position=(0, 0), font_prop=None, tolerance=0.1): tol = 0.1 * tolerance path = TextPath(position, text, size=size, prop=font_prop) polys = [] xmax = position[0] for points, code in path.iter_segments(): if code == path.MOVETO: c = gdstk.Curve(points, tolerance=tolerance) elif code == path.LINETO: c.segment(points.reshape(points.size // 2, 2)) elif code == path.CURVE3: c.quadratic(points.reshape(points.size // 2, 2)) elif code == path.CURVE4: c.cubic(points.reshape(points.size // 2, 2)) elif code == path.CLOSEPOLY: poly = c.points() if poly.size > 0: if poly[:, 0].min() < xmax: i = len(polys) - 1 while i >= 0: if gdstk.inside(poly[:1], [polys[i]], precision=tol)[0]: p = polys.pop(i) b = gdstk.boolean([p], [poly], "xor", tol) poly = b[0].points break elif gdstk.inside(polys[i][:1], [poly], precision=tol)[0]: p = polys.pop(i) b = gdstk.boolean([p], [poly], "xor", tol) poly = b[0].points i -= 1 xmax = max(xmax, poly[:, 0].max()) polys.append(poly) return polys
def cubic_image(): curve = gdstk.Curve((0, 0), tolerance=1e-3) curve.cubic([(1, -2), (2, -2), (3, 0)]) curve.cubic([(2.7, 1), (1.8, 1), (1.5, 0), (1.3, -0.2), (0.3, -0.2), (0, 0)]) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("cubic").add(polygon)
def segment_image(): curve = gdstk.Curve((1, 0)) curve.segment((0, 1)) curve.segment([0j, -1 + 0j]) curve.segment([(0, -1), (2, -1)], True) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("segment").add(polygon)
def init_image(): curve = gdstk.Curve((3, 4), tolerance=1e-3) curve.segment((1, 1), True) curve.turn(1, -numpy.pi / 2) curve.segment((1, -1), True) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("init").add(polygon)
def interpolation_image(): points = [(4, 1), (4, 3), (0, 5), (-4, 3), (-4, -2), (0, -4)] curve = gdstk.Curve((0, 0)) curve.segment(points) control_poly_1 = gdstk.Polygon(curve.points(), datatype=1) curve = gdstk.Curve((0, 0), tolerance=1e-3) curve.interpolation(points, cycle=True) polygon_1 = gdstk.Polygon(curve.points()) half_pi = numpy.pi / 2 angles = [half_pi, None, None, None, -half_pi, -half_pi, None] curve = gdstk.Curve((4, -9)) curve.segment(points, relative=True) control_poly_2 = gdstk.Polygon(curve.points(), datatype=1) curve = gdstk.Curve((4, -9), tolerance=1e-3) curve.interpolation(points, angles, cycle=True, relative=True) polygon_2 = gdstk.Polygon(curve.points()) return gdstk.Cell("interpolation").add(polygon_1, control_poly_1, polygon_2, control_poly_2)
def parametric_image(): def top(u): x = 4 * u y = 1 - numpy.cos(4 * numpy.pi * u) return (x, y) curve = gdstk.Curve((-2, 0), tolerance=1e-3) curve.parametric(top) curve.parametric(lambda u: (4 - 2 * u**0.5) * numpy.exp(-1.5j * numpy.pi * u) - 4) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("parametric").add(polygon)
def _f(p0, v0, p1, v1): p0 = numpy.array(p0) v0 = numpy.array(v0) p1 = numpy.array(p1) v1 = numpy.array(v1) half_trace_width = 0.5 * numpy.sqrt(numpy.sum((p0 - p1)**2)) a = half_trace_width + fillet_radius c = pad_radius + fillet_radius b = (c**2 - a**2)**0.5 alpha = numpy.arccos(a / c) gamma = numpy.arctan2(v0[1], v0[0]) + 0.5 * numpy.pi curve = gdstk.Curve(p0 - v0 * b, tolerance=tolerance) if fillet_radius > 0: curve.arc(fillet_radius, gamma, gamma - alpha) curve.arc(pad_radius, gamma - numpy.pi - alpha, gamma + alpha) if fillet_radius > 0: curve.arc(fillet_radius, gamma - numpy.pi + alpha, gamma - numpy.pi) return curve.points()
def render_text(text, size=None, position=(0, 0), font_prop=None, tolerance=0.1): precision = 0.1 * tolerance path = TextPath(position, text, size=size, prop=font_prop) polys = [] xmax = position[0] for points, code in path.iter_segments(): if code == path.MOVETO: c = gdstk.Curve(points, tolerance=tolerance) elif code == path.LINETO: c.segment(points.reshape(points.size // 2, 2)) elif code == path.CURVE3: c.quadratic(points.reshape(points.size // 2, 2)) elif code == path.CURVE4: c.cubic(points.reshape(points.size // 2, 2)) elif code == path.CLOSEPOLY: pts = c.points() if pts.size > 0: poly = gdstk.Polygon(pts) if pts[:, 0].min() < xmax: i = len(polys) - 1 while i >= 0: if polys[i].contain_any(*poly.points): p = polys.pop(i) poly = gdstk.boolean(p, poly, "xor", precision)[0] break elif poly.contain_any(*polys[i].points): p = polys.pop(i) poly = gdstk.boolean(p, poly, "xor", precision)[0] i -= 1 xmax = max(xmax, poly.points[:, 0].max()) polys.append(poly) return polys
def cubic_smooth_image(): curve = gdstk.Curve((0, 0), tolerance=1e-3) curve.cubic([1 + 0j, 1.5 + 0.5j, 1 + 1j]) curve.cubic_smooth([1j, 0j]) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("cubic_smooth").add(polygon)
ellipse = gdstk.ellipse((4, 0), [1, 2], tolerance=1e-4) # Circular arc example arc = gdstk.ellipse( (2, 4), 2, inner_radius=1, initial_angle=-0.2 * numpy.pi, final_angle=1.2 * numpy.pi, tolerance=0.01, ) draw(gdstk.Cell("circles").add(circle, ellipse, arc), path) # Curves # Construct a curve made of a sequence of line segments c1 = gdstk.Curve((0, 0)).segment([(1, 0), (2, 1), (2, 2), (0, 2)]) p1 = gdstk.Polygon(c1.points()) # Construct another curve using relative coordinates c2 = gdstk.Curve((3, 1)).segment([(1, 0), (2, 1), (2, 2), (0, 2)], relative=True) p2 = gdstk.Polygon(c2.points()) draw(gdstk.Cell("curves").add(p1, p2), path) # Curves 1 # Use complex numbers to facilitate writing polar coordinates c3 = gdstk.Curve(2j).segment(4 * numpy.exp(1j * numpy.pi / 6), relative=True) # Elliptical arcs have syntax similar to gdstk.ellipse c3.arc((4, 2), 0.5 * numpy.pi, -0.5 * numpy.pi) p3 = gdstk.Polygon(c3.points())
def commands_image(): curve = gdstk.Curve((0, 0), tolerance=1e-3) curve.commands("l", 1, 1, "a", 1, -numpy.pi / 2, "l", 1, -1, "S", 1, -2, 0, -2) polygon = gdstk.Polygon(curve.points()) return gdstk.Cell("commands").add(polygon)