Example #1
0
def bezier(
    name: None = None,
    width: float = 0.5,
    control_points: List[Tuple[float, float]] = [
        (0.0, 0.0),
        (5.0, 0.0),
        (5.0, 2.0),
        (10.0, 2.0),
    ],
    t: ndarray = np.linspace(0, 1, 201),
    layer: Tuple[int, int] = LAYER.WG,
    **extrude_path_params
) -> Component:
    """ bezier bend """

    def _fmt_f(x):
        return "{:.3f}".format(x).rstrip("0").rstrip(".")

    def _fmt_cp(cps):
        return "_".join(["({},{})".format(_fmt_f(p[0]), _fmt_f(p[1])) for p in cps])

    if name is None:
        points_hash = hashlib.md5(_fmt_cp(control_points).encode()).hexdigest()
        name = "bezier_w{}_{}_{}".format(int(width * 1e3), points_hash, layer)

    c = pp.Component(name=name)
    path_points = bezier_curve(t, control_points)
    polygon_points = extrude_path(path_points, width, **extrude_path_params)
    angles = angles_deg(path_points)

    c.info["start_angle"] = angles[0]
    c.info["end_angle"] = angles[-2]

    a0 = angles[0] + 180
    a1 = angles[-2]

    a0 = snap_angle(a0)
    a1 = snap_angle(a1)

    p0 = path_points[0]
    p1 = path_points[-1]
    c.add_polygon(polygon_points, layer=layer)
    c.add_port(name="0", midpoint=p0, width=width, orientation=a0, layer=layer)
    c.add_port(name="1", midpoint=p1, width=width, orientation=a1, layer=layer)

    c.info["length"] = path_length(path_points)
    curv = curvature(path_points, t)
    c.info["min_bend_radius"] = 1 / max(np.abs(curv))
    c.info["curvature"] = curv
    c.info["t"] = t

    return c
Example #2
0
    def objective_func(p):
        """
        We want to minimize a combination of:
            - max curvature
            - negligible mismatch with start angle and end angle
        """

        ps = array_1d_to_cpts(p)
        control_points = [start_point] + ps + [end_point]
        path_points = bezier_curve(t, control_points)

        max_curv = max(np.abs(curvature(path_points, t)))

        angles = angles_deg(path_points)
        dstart_angle = abs(angles[0] - start_angle)
        dend_angle = abs(angles[-2] - end_angle)
        angle_mismatch = dstart_angle + dend_angle
        return angle_mismatch * alpha + max_curv
Example #3
0
def bezier(
    name: None = None,
    width: float = 0.5,
    control_points: List[Tuple[float, float]] = [
        (0.0, 0.0),
        (5.0, 0.0),
        (5.0, 2.0),
        (10.0, 2.0),
    ],
    t: ndarray = np.linspace(0, 1, 201),
    layer: Tuple[int, int] = LAYER.WG,
    with_manhattan_facing_angles: bool = True,
    spike_length: float = 0.0,
    start_angle: Optional[int] = None,
    end_angle: Optional[int] = None,
    grid: float = 0.001,
) -> Component:
    """Bezier bend
    We avoid autoname control_points and t spacing

    Args:
        width: waveguide width
        control_points: list of points
        t: 1D array of points varying between 0 and 1
        layer: layer
    """
    def format_float(x):
        return "{:.3f}".format(x).rstrip("0").rstrip(".")

    def _fmt_cp(cps):
        return "_".join(
            [f"({format_float(p[0])},{format_float(p[1])})" for p in cps])

    if name is None:
        points_hash = hashlib.md5(_fmt_cp(control_points).encode()).hexdigest()
        name = f"bezier_w{int(width*1e3)}_{points_hash}_{layer[0]}_{layer[1]}"

    c = pp.Component(name=name)
    c.ignore.add("control_points")
    c.ignore.add("t")
    path_points = bezier_curve(t, control_points)
    polygon_points = extrude_path(
        path_points,
        width=width,
        with_manhattan_facing_angles=with_manhattan_facing_angles,
        spike_length=spike_length,
        start_angle=start_angle,
        end_angle=end_angle,
        grid=grid,
    )
    angles = angles_deg(path_points)

    c.info["start_angle"] = pp.drc.snap_to_1nm_grid(angles[0])
    c.info["end_angle"] = pp.drc.snap_to_1nm_grid(angles[-2])

    a0 = angles[0] + 180
    a1 = angles[-2]

    a0 = snap_angle(a0)
    a1 = snap_angle(a1)

    p0 = path_points[0]
    p1 = path_points[-1]
    c.add_polygon(polygon_points, layer=layer)
    c.add_port(name="0", midpoint=p0, width=width, orientation=a0, layer=layer)
    c.add_port(name="1", midpoint=p1, width=width, orientation=a1, layer=layer)

    curv = curvature(path_points, t)
    c.info["length"] = pp.drc.snap_to_1nm_grid(path_length(path_points))
    c.info["min_bend_radius"] = pp.drc.snap_to_1nm_grid(1 / max(np.abs(curv)))
    # c.info["curvature"] = curv
    # c.info["t"] = t
    return c