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_arc
— Functioncircular_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.
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.
DeviceLayout.SimpleShapes.draw_pixels
— Functiondraw_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.
DeviceLayout.SimpleShapes.hatching_unit
— Functionhatching_unit(w1, w2, pixsize=DEFAULT_HATCHING_PIXSIZE)
DeviceLayout.SimpleShapes.radial_cut
— Functionradial_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)
DeviceLayout.SimpleShapes.radial_stub
— Functionradial_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.
DeviceLayout.SimpleShapes.simple_cross
— Functionsimple_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
| |▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|
| |▓▓▓▓|
| |▓▓▓▓|
| |▓▓▓▓|
| |▓▓▓▓|
_ |▓▓▓▓|
DeviceLayout.SimpleShapes.simple_ell
— Functionsimple_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.
DeviceLayout.SimpleShapes.simple_tee
— Functionsimple_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.
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!
— Functioncheckerboard!(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 squarerows
: number of rows == number of columnsalt
: the square nearestPoint(zero(T), zero(T))
is filled (unfilled) iffalse
(true
). Use this to create a full tiling of the checkerboard, if you wish.
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!
— Functiongrating!(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.
Example:
c = Cell("main", nm)
grating!(c, 100nm, 100nm, 5μm, GDSMeta(3))
save("grating.svg", flatten(c));
DeviceLayout.SimpleShapes.interdigit!
— Functioninterdigit!(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 widthlength
: finger lengthfingeroffset
: x-offset at ends of fingersfingergap
: gap between fingersnpairs
: number of fingersskiplast
: should we skip the last finger, leaving an odd number?
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));