Shape library

Examples on this page assume you have done using DeviceLayout, DeviceLayout.PreferredUnits, FileIO.

Simple shapes

A library of simple shapes is available from the SimpleShapes module. All of these functions are exported by the top-level DeviceLayout module and are directly accessible to the user.

DeviceLayout.SimpleShapes.circular_arcFunction
circular_arc(θ, r::T, tolerance; θ_0=0, center=zero(Point{T})) where
            {T <: Coordinate}

Discretizes a circular arc to meet a tolerance, ignoring rounding to a grid.

θ is the angular position of the end of the arc and r is its radius. The maximum distance between any segment and the actual circle will be roughly equal to the tolerance (for small tolerance). Returns an array of Points. Includes both endpoints.

If θ > θ_0, the arc is drawn counterclockwise.

source
circular_arc(θ::Vector, r::T, tolerance; center=zero(Point{T})) where {T <: Coordinate}

Discretizes a circular arc of radius r from θ[1] to θ[2], choosing the shorter direction (defaults to counterclockwise for a semicircle). r is its radius. The maximum distance between any segment and the actual circle will be roughly equal to the tolerance (for small tolerance). Returns an array of Points, including both endpoints.

source
DeviceLayout.SimpleShapes.draw_pixelsFunction
draw_pixels(pixpattern::AbstractMatrix{Int}, pixsize)

Given a matrix pixpattern, make a bitmap of Rectangle where the presence of a pixel corresponds to a positive value in the matrix. Returns an array of polygons.

source
DeviceLayout.SimpleShapes.radial_cutFunction
radial_cut(r, Θ, h; narc::Int=197)

Renders a polygon representing a radial cut (like a radial stub with no metal). The polygon has to be subtracted from a ground plane.

The parameter h is made available in the method signature rather than a because the focus of the arc (top of polygon) can easily centered in a waveguide. If it is desirable to control a instead, use trig: a/2 = h*tan(Θ/2).

Parameters as follows, where X marks the origin and (nothing above the origin is part of the resulting polygon):

                       Λ
                      /│\
                     / │ \
                    /  |  \
              .    /   │Θ/2\
             .    /    │----\
            /    /   h │     \
           /    /      │      \
          /    /       │       \
         r    /        │        \
        /    /         │         \
       /    /----------X----------\
      /    /{--------- a ---------}\
     .    /                         \
    .    /                           \
        /                             \
       /                               \
      /                                 \
      --┐                             ┌--
        └--┐                       ┌--┘
           └--┐                 ┌--┘
              └--┐           ┌--┘
                 └-----------┘
                 (circular arc)
source
DeviceLayout.SimpleShapes.radial_stubFunction
radial_stub(r, Θ, h, t; narc::Int=197)

See also the documentation for radial_cut.

Return a polygon for a radial stub. The polygon has to be subtracted from a ground plane, and will leave a defect in the ground plane of uniform width t that outlines the (metallic) radial stub. r refers to the radius of the actual stub, not the radius of the circular arc bounding the ground plane defect. Likewise h has an analogous meaning to that in radial_cut except it refers here to the radial stub, not the ground plane defect.

source
DeviceLayout.SimpleShapes.simple_crossFunction
simple_cross(lv_x, lv_y; lh_x=lv_y, lh_y=lv_x)

A simple cross centered at the origin. The only required inputs are lv_x and lv_y, the length of the vertical strip along the x and y directions, respectively. The corresponding dimensions of the horizontal strip are given as keyword arguments, with the defaults producing identical horizontal and vertical strips.

_ |<--------- lh_x ----------->|
|            |▓▓▓▓|
|            |▓▓▓▓|
lv_y         |▓▓▓▓|
|            |<  >| lv_x
|            |▓▓▓▓|
| |▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓| lh_y
| |▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|
|            |▓▓▓▓|
|            |▓▓▓▓|
|            |▓▓▓▓|
|            |▓▓▓▓|
_            |▓▓▓▓|
source
DeviceLayout.SimpleShapes.simple_ellFunction
simple_ell(w1, h1; w2=h1, h2=w1)

Return an L-shaped polygon with its bottom left corner at the origin.

Note that the parameters describe the L as two overlapping rectangles. The result is identical if you switch "rectangle 1" and "rectangle 2". By default, the rectangles have the same "stroke width" and length.

_           |<------w2------->|
|           |▓▓▓▓|
|           |▓▓▓▓|
h1          |▓▓▓▓|
|           |<w1>|
|           |▓▓▓▓|
v           |▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓| h2
            ^ (x,y) = (0,0) at the lower-left corner of the L.
source
DeviceLayout.SimpleShapes.simple_teeFunction
simple_tee(w1, h1; w2=h1, h2=w1)

Parameters are named in typical handwritten stroke order (like cross, vertical stem first). Note that h1 is the full height of the T.

_    _______w2________
|   |▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓| h2
|          |▓▓▓▓|
h1         |▓▓▓▓|
|          |<w1>|
v          |▓▓▓▓|
             ^ (x,y) = (0,0) at center of baseline of T.
source

Example:

c = Cell("main", nm)
p = radial_cut(20μm, π / 2, 5μm)
render!(c, p, GDSMeta(1))
save("radial_cut.svg", flatten(c));

Example:

c = Cell("main", nm)
p = radial_stub(20μm, π / 2, 5μm, 1μm)
render!(c, p, GDSMeta(1))
save("radial_stub.svg", flatten(c));

Compound shapes

We also provide methods for a few "compound shapes" that render multiple entities to a coordinate system rather than return a single entity.

DeviceLayout.SimpleShapes.checkerboard!Function
checkerboard!(c::Cell{T,S}, pixsize, rows::Integer, alt, meta::Meta=GDSMeta()) where {T,S}

In cell c, generate a checkerboard pattern suitable for contrast curve measurement, or getting the base dose for PEC.

  • pixsize: length of one side of a square
  • rows: number of rows == number of columns
  • alt: the square nearest Point(zero(T), zero(T)) is filled (unfilled) if false (true). Use this to create a full tiling of the checkerboard, if you wish.
source

Example:

c = Cell("main", nm)
checkerboard!(c, 20μm, 10, false, GDSMeta(2))
checkerboard!(c, 20μm, 10, true, GDSMeta(3))
save("checkers.svg", flatten(c));
DeviceLayout.SimpleShapes.grating!Function
grating!(c::Cell{T,S}, line, space, size, meta::Meta=GDSMeta()) where {T,S}

Generate a square grating suitable e.g. for obtaining the base dose for PEC.

source

Example:

c = Cell("main", nm)
grating!(c, 100nm, 100nm, 5μm, GDSMeta(3))
save("grating.svg", flatten(c));
DeviceLayout.SimpleShapes.interdigit!Function
interdigit!(c::AbstractCoordinateSystem{T}, width, length, fingergap, fingeroffset, npairs::Integer,
    skiplast, meta::Meta=GDSMeta(0,0)) where {T}

Creates interdigitated fingers, e.g. for a lumped element capacitor.

  • width: finger width
  • length: finger length
  • fingeroffset: x-offset at ends of fingers
  • fingergap: gap between fingers
  • npairs: number of fingers
  • skiplast: should we skip the last finger, leaving an odd number?
source

Simple usage for interdigit!:

fingers = Cell("fingers", nm)
wide, length, fingergap, fingeroffset, npairs, skiplast = 1μm, 20μm, 1μm, 3μm, 5, true
interdigit!(fingers, wide, length, fingergap, fingeroffset, npairs, skiplast, GDSMeta(5))
save("fingers_only.svg", flatten(fingers));

Example of how to make an interdigitated capacitor inline with a feedline:

c = Cell("main", nm)
p = Path(μm)
trace, gap = 17μm, 3μm
straight!(p, 50μm, Paths.CPW(trace, gap))
straight!(p, 23μm, Paths.NoRender())
straight!(p, 50μm, Paths.CPW(trace, gap))
fingers = Cell("fingers", nm)
wide, length, fingergap, fingeroffset, npairs, skiplast = 1μm, 20μm, 1μm, 3μm, 5, true
interdigit!(fingers, wide, length, fingergap, fingeroffset, npairs, skiplast, GDSMeta(5))
finger_mask =
    Rectangle(width(bounds(fingers)), height(bounds(fingers)) + 2 * gap) - Point(0μm, gap)
inverse_fingers = Cell("invfingers", nm)
plgs = difference2d(finger_mask, elements(fingers))
render!(inverse_fingers, plgs, GDSMeta(0))
attach!(
    p,
    CellReference(inverse_fingers, Point(0μm, -upperright(bounds(fingers)).y / 2)),
    0μm,
    i=2
)
render!(c, p, GDSMeta(0))
save("fingers.svg", flatten(c));