8.2 2D Shapes and Transforms

Aligned outcomes:

SLO 3

Describe, design, implement, and test structured programs using currently accepted methodology.

Learning Objectives

By the end of this section, you will be able to:

In this section, you will learn to:
  • create the main 2D primitives in JSCAD — rectangle, circle, ellipse, rounded rectangle, polygon, and star;
  • read each primitive's option table and pick the options you need;
  • build a custom polygon from a list of points;
  • move, rotate, and resize a shape with the translate, rotate, and scale transforms;
  • flip, center, and align a shape with the mirror, center, and align transforms.

All 2D primitives live in JSCAD → primitives. Each returns a geom2 object. Options are always passed as a single object; every option shown below is optional unless noted, with its documented default.

One object of options

Every primitive takes its settings as a single object, like { size: [10, 20] }. That keeps the call tidy and lets you leave out any option you want to keep at its default.

rectangle(options?) → geom2

Axis-aligned rectangle with four right-angle sides.

Option Type Default Meaning
center Array [0,0] rectangle center point
size Array [2,2] [width, length]
Editor
renders in your browser

Axis-aligned means no tilt

An axis-aligned rectangle's sides run straight along the x and y axes — it never leans. If you want a tilted rectangle, you build it upright and then rotate it with a transform.

Try It Now 8.2.1

Create a rectangle that is 30 wide and 8 long, centered at the origin. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — pick the primitive. We need a rectangle, so we use rectangle.

Step 2 — set the size. The size option takes [width, length]. We want width 30 and length 8, so size: [30, 8].

Step 3 — leave the center at its default. The default center is [0,0], which is the origin, so we do not need to pass center.

Editor
renders in your browser

Answer: rectangle({ size: [30, 8] }) — a 30-by-8 rectangle centered at the origin.

circle(options?) → geom2

Every point on the boundary is an equal distance from the center.

Option Type Default Meaning
center Array [0,0] circle center
radius Number 1 distance from center
startAngle Number 0 beginning angle, radians
endAngle Number TAU ending angle, radians
segments Number 32 divisions per full rotation
Editor
renders in your browser

Segments make the circle

A computer cannot draw a perfect curve, so a circle is built from straight segments. More segments means a smoother circle but a heavier model — 32 is a good default for most parts.

Try It Now 8.2.2

Create a circle with radius 5 centered at the point (2, 3). Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — pick the primitive. We need a circle, so we use circle.

Step 2 — set the radius. We want radius 5, so radius: 5.

Step 3 — set the center. The center is (2, 3), so center: [2, 3].

Editor
renders in your browser

Answer: circle({ radius: 5, center: [2, 3] }) — a radius-5 circle centered at (2, 3).

ellipse(options?) → geom2

Axis-aligned ellipse.

Option Type Default Meaning
center Array [0,0] ellipse center
radius Array [1,1] [xRadius, yRadius]
startAngle Number 0 beginning angle, radians
endAngle Number TAU ending angle, radians
segments Number 32 divisions per full rotation
Editor
renders in your browser

An ellipse is a stretched circle

A circle has one radius; an ellipse has two — one along x and one along y. When the two radii are equal, the ellipse is a circle.

Try It Now 8.2.3

Create an ellipse with an x-radius of 4 and a y-radius of 9. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — pick the primitive. We need an ellipse, so we use ellipse.

Step 2 — set the two radii. The radius option takes [xRadius, yRadius]. We want x-radius 4 and y-radius 9, so radius: [4, 9].

Editor
renders in your browser

Answer: ellipse({ radius: [4, 9] }) — an ellipse with x-radius 4 and y-radius 9.

roundedRectangle(options?) → geom2

Rectangle with rounded corners — useful whenever sharp corners are undesirable on a real part.

Option Type Default Meaning
center Array [0,0] center location
size Array [2,2] [width, length]
roundRadius Number 0.2 corner rounding radius
segments Number 32 segments per full rotation
Editor
renders in your browser

Why round the corners

Sharp corners on a real part can catch, snag, or stress the material. A rounded corner spreads the load and feels better in the hand — that is why phone cases and tool handles use them.

Try It Now 8.2.4

Create a rounded rectangle that is 40 wide and 20 long, with a corner rounding radius of 5. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — pick the primitive. We need a rounded rectangle, so we use roundedRectangle.

Step 2 — set the size. The size option takes [width, length]. We want width 40 and length 20, so size: [40, 20].

Step 3 — set the corner radius. We want roundRadius: 5.

Editor
renders in your browser

Answer: roundedRectangle({ size: [40, 20], roundRadius: 5 }) — a 40-by-20 rounded rectangle with corner radius 5.

polygon(options) → geom2

Builds an arbitrary 2D polygon from a list of points. Points must run counter-clockwise.

Option Type Default Meaning
points Array — (required) flat or nested array of 2D points
paths Array optional point indices defining sub-paths
orientation String 'counterclockwise' winding order
Editor
renders in your browser

Winding order matters

A polygon's points must run counter-clockwise. Think of it as the direction you walk around the shape — JSCAD needs to know which side is the inside, and the winding order tells it.

Example 8.2.1: Building a polygon counter-clockwise

A polygon's points must run counter-clockwise, or JSCAD can get confused about which side is the inside. Build a triangle whose points already run that way — each comment below is one line for you to write. Press Run when you are done.

Editor
renders in your browser

Solution
Editor
renders in your browser

You should see a triangle with vertices at (0,0), (6,0), and (3,5). Going (0,0)(6,0)(3,5) walks counter-clockwise, so the winding is correct. List the same three points in the opposite order and run it again — the triangle flips over, because the inside is now on the other side.

Try It Now 8.2.5

Build a triangle polygon from the points (0, 0), (6, 0), and (3, 5). Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — pick the primitive. We need a polygon, so we use polygon.

Step 2 — list the points. The points option takes an array of 2D points. Our three points are [0, 0], [6, 0], and [3, 5].

Step 3 — check the winding order. Going (0,0)(6,0)(3,5) runs counter-clockwise, which is the default orientation.

Editor
renders in your browser

Answer: polygon({ points: [[0, 0], [6, 0], [3, 5]] }) — a triangle with those three vertices.

star(options?) → geom2

Star polygon with a configurable point count and density.

Option Type Default Meaning
center Array [0,0] star center
vertices Number 5 number of outer points
density Number 2 star density factor
outerRadius Number 1 outer vertex distance
innerRadius Number 0 inner vertex distance (auto if 0)
startAngle Number 0 angle of the first vertex, radians
Editor
renders in your browser

Density changes the star's shape

The density factor controls how the points connect. A low density gives a simple star; a higher density makes the points skip and cross, producing a more complex, spiky shape.

Try It Now 8.2.6

Create a star with 6 outer points and an outer radius of 12. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — pick the primitive. We need a star, so we use star.

Step 2 — set the point count. We want 6 outer points, so vertices: 6.

Step 3 — set the outer radius. We want outerRadius: 12.

Editor
renders in your browser

Answer: star({ vertices: 6, outerRadius: 12 }) — a 6-point star with outer radius 12.

translate(offset, ...objects) → geom2

Moves a shape by a given offset without changing its size or orientation.

Option Type Default Meaning
offset Array — (required) [x, y] distance to move the shape
objects geom2 — (required) the shape or shapes to move
Editor
renders in your browser

Positional arguments, not an options object

The primitives take one options object, but transforms take their settings as plain positional arguments — translate([5, 0], myshape), not translate({ offset: [5, 0] }, myshape). The offset comes first, then the shape.

Example 8.2.2: Moving a shape with translate

Transforms are the way a built shape finds its place on the page. Here a rectangle is built at the origin and then nudged to the right — each comment below is one line for you to write. Press Run when you are done.

Editor
renders in your browser

Solution
Editor
renders in your browser

You should see the same 10-by-20 rectangle, but 5 units further right. The offset comes first and the shape second — translate([5, 0], myshape), not the other way round. Change the offset to [0, 5] and run it again to move it up instead.

Try It Now 8.2.7

Move a 10-by-20 rectangle 5 units to the right. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — build the shape. We need a rectangle, so we use rectangle with size: [10, 20].

Step 2 — pick the transform. We are moving the shape, so we use translate.

Step 3 — pass the offset and the shape. The offset is [5, 0] (5 right, 0 up), and the shape comes second.

Editor
renders in your browser

Answer: translate([5, 0], rectangle({ size: [10, 20] })) — the rectangle shifted 5 units to the right.

rotate(angles, ...objects) → geom2

Turns a shape around the origin by the given angles.

Option Type Default Meaning
angles Array — (required) [x, y, z] rotation in radians
objects geom2 — (required) the shape or shapes to rotate
Editor
renders in your browser

Angles are in radians

JSCAD measures rotation in radians, not degrees. A full turn is TAU (about 6.28) radians, so a quarter turn is Math.PI / 2. For 2D work you rotate around the z axis, and rotateZ(angle, myshape) is a handy shortcut for rotate([0, 0, angle], myshape).

Try It Now 8.2.8

Rotate a 10-by-20 rectangle by a quarter turn. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — build the shape. We need a rectangle, so we use rectangle with size: [10, 20].

Step 2 — pick the transform. We are turning the shape, so we use rotate.

Step 3 — pass the angles and the shape. A quarter turn is Math.PI / 2 radians around the z axis, so the angles are [0, 0, Math.PI / 2].

Editor
renders in your browser

Answer: rotate([0, 0, Math.PI / 2], rectangle({ size: [10, 20] })) — the rectangle turned a quarter turn.

scale(factors, ...objects) → geom2

Stretches or shrinks a shape by the given factors along each axis.

Option Type Default Meaning
factors Array — (required) [x, y] multiplier along each axis
objects geom2 — (required) the shape or shapes to scale
Editor
renders in your browser

Scaling is a multiplier, not a size

A factor of 2 doubles the shape along that axis, and a factor of 0.5 halves it. A factor of 1 leaves that axis unchanged. Unequal factors stretch the shape out of proportion.

Try It Now 8.2.9

Double the width of a 10-by-20 rectangle. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — build the shape. We need a rectangle, so we use rectangle with size: [10, 20].

Step 2 — pick the transform. We are resizing the shape, so we use scale.

Step 3 — pass the factors and the shape. Doubling the width means an x factor of 2; the y factor stays 1.

Editor
renders in your browser

Answer: scale([2, 1], rectangle({ size: [10, 20] })) — the rectangle now 20 wide and 20 long.

mirror(options, ...objects) → geom2

Flips a shape across a mirror plane.

Option Type Default Meaning
normal Array [0,0,1] direction perpendicular to the mirror plane
origin Array [0,0,0] a point the mirror plane passes through
objects geom2 — (required) the shape or shapes to mirror
Editor
renders in your browser

The mirror plane

A mirror plane is the flat surface the shape is flipped across, like a pane of glass. It is defined by a point on it (origin) and a direction pointing straight out of it (normal). A normal of [0, 1, 0] mirrors across the x axis.

Example 8.2.3: Flipping a triangle with mirror

Mirroring an already-symmetric shape teaches nothing — it looks the same after the flip. Start from an off-centre triangle so the mirror actually moves it, and pick the right normal — each comment below is one line for you to write. Press Run when you are done.

Editor
renders in your browser

Solution
Editor
renders in your browser

You should see a second triangle below the x axis, the mirror image of the first. The normal [0, 1, 0] points along y, so the plane it describes is the x axis. Change the normal to [1, 0, 0] and run it again to flip across the y axis instead.

Try It Now 8.2.10

Flip the triangle with vertices (0, 0), (10, 0), and (5, 8) across the x axis. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — build the shape. We need a triangle, so we build it with polygon from its three points.

Step 2 — pick the transform. We are flipping the shape, so we use mirror.

Step 3 — set the mirror plane. Flipping across the x axis means the plane's normal points along y, so normal: [0, 1, 0].

Editor
renders in your browser

Answer: mirror({ normal: [0, 1, 0] }, polygon({ points: [[0, 0], [10, 0], [5, 8]] })) — the triangle flipped across the x axis.

center(options, ...objects) → geom2

Centers a shape on the origin along the chosen axes.

Option Type Default Meaning
axes Array [true,true,true] which axes to center on
relativeTo Array [0,0,0] point to center relative to
objects geom2 — (required) the shape or shapes to center
Editor
renders in your browser

Centering is a move, not a resize

Centering slides a shape so its middle sits on the origin — it does not change the shape's size. The axes array tells JSCAD which directions to center in; a false leaves that axis alone.

Try It Now 8.2.11

Center a 10-by-20 rectangle on the origin. The rectangle's center is [12, 8], so it starts off-centre. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — build the shape. We need a rectangle, so we use rectangle with size: [10, 20]. We also pass center: [12, 8] so the rectangle starts off-centre and the centering visibly moves it.

Step 2 — pick the transform. We are centering the shape, so we use center.

Step 3 — set the axes. We want to center on both x and y, so axes: [true, true, false].

Editor
renders in your browser

Answer: center({ axes: [true, true, false] }, rectangle({ size: [10, 20], center: [12, 8] })) — the rectangle slides from [12, 8] to sit centered on the origin.

align(options, ...objects) → geom2

Aligns a shape to a reference point along each axis.

Option Type Default Meaning
modes Array ['center','center','min'] how to align on each axis
relativeTo Array [0,0,0] point to align to
grouped Boolean false align shapes as one group
objects geom2 — (required) the shape or shapes to align
Editor
renders in your browser

Align modes pick the edge

Each axis has a mode: min puts the shape's low edge on the reference, max puts the high edge there, and center puts the middle there. The default centers on x and y and sets the low edge on z.

Try It Now 8.2.12

Align a 10-by-20 rectangle so its low edge sits on the x axis. The rectangle's center is [12, 8], so it starts off-centre and aligning visibly moves it. Write the JSCAD call.

Editor
renders in your browser

Solution

Step 1 — build the shape. We need a rectangle, so we use rectangle with size: [10, 20]. We also pass center: [12, 8] so the rectangle starts off-centre and the aligning visibly moves it.

Step 2 — pick the transform. We are aligning the shape, so we use align.

Step 3 — set the modes. We want the low edge on y, so the y mode is min; the x mode can stay center.

Editor
renders in your browser

Answer: align({ modes: ['center', 'min', 'min'] }, rectangle({ size: [10, 20], center: [12, 8] })) — the rectangle's low edge slides to the x axis.

Problem Set

Problem 1. Write a JSCAD call that creates a rectangle 50 wide and 25 long.

Problem 2. Write a JSCAD call that creates a circle with radius 7 centered at (1, 1).

Problem 3. Write a JSCAD call that creates an ellipse with x-radius 3 and y-radius 6.

Problem 4. Write a JSCAD call that creates a rounded rectangle 30 by 15 with a corner radius of 3.

Problem 5. Write a JSCAD call that builds a square polygon from the points (0, 0), (4, 0), (4, 4), and (0, 4).

Problem 6. Write a JSCAD call that creates a star with 5 outer points and an outer radius of 8.

Problem 7. Write a JSCAD call that moves a 10-by-20 rectangle 5 units to the right.

Problem 8. Write a JSCAD call that rotates a 10-by-20 rectangle by a quarter turn.

Problem 9. Write a JSCAD call that doubles the width of a 10-by-20 rectangle.

Problem 10. Write a JSCAD call that flips the triangle with vertices (0, 0), (10, 0), and (5, 8) across the x axis.

Problem 11. Write a JSCAD call that centers a 10-by-20 rectangle (whose center is [12, 8]) on the origin.

Problem 12. Write a JSCAD call that aligns a 10-by-20 rectangle (whose center is [12, 8]) so its low edge sits on the x axis.

Key Terms

primitive — a basic built-in shape (rectangle, circle, ellipse, polygon, star) that JSCAD can create.

geom2 — the object type JSCAD uses to represent a 2D geometry.

option — a setting passed to a primitive inside a single object, such as size or radius.

axis-aligned — running straight along the x and y axes, with no tilt.

segments — the straight divisions used to build a curved shape; more segments means a smoother curve.

winding order — the direction (counter-clockwise) in which a polygon's points are listed.

transform — an operation that moves, rotates, resizes, flips, or aligns an existing shape.

radians — the unit JSCAD uses for angles; a full turn is TAU radians.

mirror plane — the flat surface a shape is flipped across when mirrored.