p5.js Starter Article 5

Drawing Shapes

Every shape function in p5.js — rectangles, ellipses, lines, arcs, and custom polygons.

⏱ 15 min read shapes drawing geometry

The basic shape functions

p5.js provides a set of built-in shape functions that cover most drawing needs:

function setup() {
  createCanvas(600, 500);
  background(25);
  noLoop();

  stroke(200);
  strokeWeight(1.5);
  fill(80, 120, 200);

  // Line — no fill, just stroke
  line(50, 50, 200, 50);

  // Rectangle: rect(x, y, w, h)
  rect(50, 80, 120, 70);

  // Ellipse: ellipse(x, y, w, h)  — x,y is the CENTRE
  ellipse(200, 200, 120, 80);

  // Circle: circle(x, y, diameter)
  circle(400, 200, 100);

  // Triangle: triangle(x1,y1, x2,y2, x3,y3)
  triangle(300, 300, 250, 420, 350, 420);

  // Quad: quad(x1,y1, x2,y2, x3,y3, x4,y4)
  quad(420, 300, 500, 320, 520, 420, 400, 430);
}

rect() vs rectangle origins

By default, rect(x, y, w, h) treats x,y as the top-left corner. But ellipse(x, y, w, h) treats x,y as the centre.

This inconsistency is historical — Processing inherited it from its inspirations. You can change the rectangle mode:

rectMode(CENTER);   // x,y is the centre
rectMode(CORNER);   // x,y is top-left (default)
rectMode(CORNERS);  // x,y is top-left, third/fourth args are bottom-right

Similarly for ellipses:

ellipseMode(CENTER);  // default — x,y is centre
ellipseMode(CORNER);  // x,y is top-left of the bounding box

Rounded rectangles

Pass a fifth argument to rect() for rounded corners:

rect(50, 50, 200, 100, 16);          // all corners rounded 16px
rect(50, 200, 200, 100, 16, 16, 0, 0); // top corners only

Arcs

// arc(x, y, w, h, startAngle, stopAngle, mode)
arc(300, 250, 150, 150, 0, PI, OPEN);   // half circle, open
arc(300, 250, 150, 150, 0, PI, CHORD);  // chord line closes it
arc(300, 250, 150, 150, 0, PI, PIE);    // pie slice

// Angles use radians: 0 = right, PI/2 = bottom, PI = left, TWO_PI = full circle
// Convert degrees: radians(90) = PI/2

Custom shapes with beginShape()

For any polygon or freeform path, use beginShape() / endShape():

beginShape();
  vertex(200, 100);
  vertex(300, 50);
  vertex(400, 100);
  vertex(380, 200);
  vertex(220, 200);
endShape(CLOSE);  // CLOSE connects the last vertex back to the first

Curved shapes

Use curveVertex() for Catmull-Rom splines (smooth curves through control points):

beginShape();
  curveVertex(100, 200);  // phantom start point (not drawn)
  curveVertex(150, 100);
  curveVertex(300, 250);
  curveVertex(450, 100);
  curveVertex(500, 200);
  curveVertex(550, 250);  // phantom end point (not drawn)
endShape();

Or bezierVertex() for Bezier curves:

beginShape();
  vertex(100, 200);
  bezierVertex(150, 50, 350, 50, 400, 200);
endShape();

bezierVertex(cp1x, cp1y, cp2x, cp2y, anchorX, anchorY) — the first four values are control points that pull the curve.

Point and lines

point(x, y);          // single pixel (use strokeWeight to make it bigger)
line(x1, y1, x2, y2); // straight line between two points

strokeWeight and strokeCap

strokeWeight(4);       // line thickness in pixels
strokeCap(ROUND);      // ROUND, SQUARE, or PROJECT (default)
strokeJoin(ROUND);     // how line corners join: ROUND, MITER, BEVEL

A composition exercise

Combine shapes to build something recognisable:

function setup() {
  createCanvas(400, 400);
  noLoop();
  background(200, 230, 255);  // sky blue
}

function draw() {
  // Sun
  fill(255, 220, 50);
  noStroke();
  circle(320, 80, 80);

  // Ground
  fill(100, 180, 80);
  rect(0, 300, 400, 100);

  // House body
  fill(230, 200, 160);
  stroke(150);
  strokeWeight(1);
  rect(120, 200, 160, 100);

  // Roof
  fill(180, 80, 80);
  noStroke();
  triangle(100, 200, 200, 120, 300, 200);

  // Door
  fill(100, 70, 40);
  rect(178, 250, 44, 50, 4, 4, 0, 0);

  // Window
  fill(180, 220, 255);
  stroke(100);
  strokeWeight(1);
  rect(130, 215, 35, 35, 2);
  rect(235, 215, 35, 35, 2);
}

Key takeaways

  • rect(x, y, w, h) — top-left corner by default; use rectMode(CENTER) to change
  • ellipse(x, y, w, h) and circle(x, y, d) — centred by default
  • Arcs take start/stop angles in radians and an optional mode (OPEN, CHORD, PIE)
  • beginShape() / endShape(CLOSE) lets you draw any polygon
  • curveVertex() and bezierVertex() create smooth curves inside shapes
  • strokeWeight(), strokeCap(), and strokeJoin() control line appearance