예제 #1
0
def grating_tooth_points(
    ap: float64,
    bp: float64,
    xp: float64,
    width: Union[float64, float],
    taper_angle: float,
    spiked: bool = True,
    angle_step: float = 1.0,
) -> ndarray:
    theta_min = -taper_angle / 2
    theta_max = taper_angle / 2

    backbone_points = ellipse_arc(ap, bp, xp, theta_min, theta_max, angle_step)
    if spiked:
        spike_length = width / 3
    else:
        spike_length = 0.0
    points = extrude_path(
        backbone_points,
        width,
        with_manhattan_facing_angles=False,
        spike_length=spike_length,
    )

    return points
예제 #2
0
def _bend_euler(
    theta: int = 90,
    radius: Union[int, float] = 10.0,
    width: float = 0.5,
    resolution: float = 150.0,
    layer: Tuple[int, int] = LAYER.WG,
) -> Component:
    c = pp.Component()
    backbone = euler_bend_points(theta, radius=radius, resolution=resolution)
    pts = extrude_path(backbone, width)

    c.add_polygon(pts, layer=layer)
    # print(backbone[0])
    # print(backbone[-1])
    c.info["length"] = euler_length(radius, theta)
    c.radius = radius
    c.add_port(
        name="in0",
        midpoint=np.round(backbone[0].xy, 3),
        orientation=180,
        layer=layer,
        width=width,
    )
    c.add_port(
        name="out0",
        midpoint=np.round(backbone[-1].xy, 3),
        orientation=theta,
        layer=layer,
        width=width,
    )

    return c
예제 #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,
    **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
예제 #4
0
def grating_tooth_points(ap, bp, xp, width, taper_angle, spiked=True, angle_step=1.0):
    theta_min = -taper_angle / 2
    theta_max = taper_angle / 2

    backbone_points = ellipse_arc(ap, bp, xp, theta_min, theta_max, angle_step)
    if spiked:
        spike_length = width / 3
    else:
        spike_length = 0.0
    points = extrude_path(
        backbone_points,
        width,
        with_manhattan_facing_angles=False,
        spike_length=spike_length,
    )

    return points
예제 #5
0
def bezier_points(control_points, width, t=np.linspace(0, 1, 101)):
    """t: 1D array of points varying between 0 and 1"""
    points = bezier_curve(t, control_points)
    return extrude_path(points, width)
예제 #6
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