SWSquare Class Reference

Complete Guide to the SketchWave Square Class (extends SWRectangle)

Overview

SWSquare is a specialization of SWRectangle where width and height are always equal. It is constructed with a single size parameter and inherits all rectangle behavior — breathing animations, rotation, vertex display, trails, color control, and dragging — while adding four square-specific geometric getters and a toRhombus() transform method.

▪ Inheritance Chain: SWSquareSWRectangle → (base SketchWaveJS shape)
💡 Key Difference from SWRectangle: SWRectangle requires separate width and height parameters. SWSquare takes a single size which is applied to both dimensions, guaranteeing isSquare === true at creation time.

Dependencies

  • p5.js (1.6.0+) — rendering engine
  • SWColor — fill and stroke colors
  • SWPoint — center and vertex points
  • SWGrid — user-space coordinate system
  • SWSinusoid — breathing animation curves
  • SWRectangle — parent class (must be loaded first)

Quick Example

// Create a coral square centered at the origin, size 8
const center    = new SWPoint(0, 0);
const fillColor = new SWColor(5, 35, 95, 60, "coral");
const mySquare  = new SWSquare(center, 8, fillColor);

// Draw it on a grid
mySquare.drawOnGrid(grid);

// Square-specific info
console.log(mySquare.diagonal);                // 11.31...
console.log(mySquare.inscribedCircleRadius);   // 4
console.log(mySquare.circumscribedCircleRadius); // 5.656...

// Create its 45°-rotated rhombus twin
const rhombus = mySquare.toRhombus();

Constructor

new SWSquare(center, size, fillColor, options)
ParameterTypeRequiredDescription
centerSWPointYesCenter point of the square (user coordinates)
sizenumberYesSide length (width = height = size)
fillColorSWColorYesFill color (SWColor instance)
optionsObjectNoOptional configuration (see below)

Options Object

KeyTypeDefaultDescription
strokeColorSWColorautoBorder color (derived from fill if omitted)
strokeWeightnumber2Border thickness in pixels
showVerticesbooleanfalseShow corner SWPoints
showCenterbooleanfalseShow center SWPoint
rotationnumber0Initial rotation in degrees (CCW)

Properties

Basic / Inherited Properties

All properties from SWRectangle are available. Key ones are:

size inherited getter

The side length of the square (set in the constructor). Since SWSquare calls super(center, size, size, ...), both rectWidth and rectHeight equal this value.

squareABC.size → number
fillColor / strokeColor inherited

Read/write. Set to a new SWColor instance to change fill or border.

rotation inherited

Current rotation angle in degrees (CCW). Modified by rotateAboutCenter() and by toRhombus() (which adds 45°).

vUL / vUR / vLR / vLL inherited

The four corner SWPoint instances (Upper-Left, Upper-Right, Lower-Right, Lower-Left). Accessible for label, trail, and drag customization.

rCenter inherited

The center SWPoint. Make it draggable with rCenter.setDraggable(true).

Square-Specific Properties (Getters)

sideLength SWSquare only

Alias for size. Provided for semantic clarity.

Returns: number — the side length
mySquare.sideLength  // same as mySquare.size
diagonal SWSquare only

Length of either diagonal of the square. Formula: size × √2.

Returns: number
// For size = 8:
mySquare.diagonal  // → 11.313...
inscribedCircleRadius SWSquare only

Radius of the largest circle that fits inside the square, touching all four sides (incircle). Formula: size / 2.

Returns: number
// For size = 8:
mySquare.inscribedCircleRadius  // → 4
circumscribedCircleRadius SWSquare only

Radius of the circle that passes through all four corners (circumcircle). Formula: size × √2 / 2.

Returns: number
// For size = 8:
mySquare.circumscribedCircleRadius  // → 5.656...

Geometric Properties (Inherited from SWRectangle)

area inherited

Area of the square. Formula: size² (same as width × height).

mySquare.area  // → 64  (for size = 8)
perimeter inherited

Perimeter of the square. Formula: 4 × size.

mySquare.perimeter  // → 32  (for size = 8)
aspectRatio inherited

Always returns 1.0 for a square (width === height).

Classification Properties (Inherited)

isSquare inherited

Always true for SWSquare instances (since width always equals height).

mySquare.isSquare  // → true
isGolden inherited

Always false for a square (aspect ratio is 1, not φ ≈ 1.618).

Methods

Square-Specific Methods

toRhombus() SWSquare only
toRhombus() → SWSquare

Creates and returns a new SWSquare with the same center, size, and colors, but rotated 45° relative to the current rotation. A square rotated 45° appears as a diamond (rhombus shape), even though it remains a square geometrically.

Returns: A new SWSquare instance — does not mutate the original.
const mySquare = new SWSquare(center, 8, fillColor);
// mySquare.rotation === 0

const rhombus = mySquare.toRhombus();
// rhombus.rotation === 45
// rhombus.size === 8 (unchanged)
// rhombus.isSquare === true

// Can chain further:
const doubleRotated = rhombus.toRhombus();
// doubleRotated.rotation === 90
💡 Tip: The returned SWSquare is independent — animating or dragging the original won't affect the rhombus. Call toRhombus() again if you need an updated snapshot.
toString() overridden
toString() → string

Returns a human-readable description of the square, overriding SWRectangle's version to use size instead of separate width/height.

Returns: string
mySquare.toString()
// "SWSquare(center: SWPoint(0.00, 0.00), size: 8.00, area: 64.00, rotation: 0°)"

Rendering Methods (Inherited from SWRectangle)

drawOnGrid(grid) inherited
drawOnGrid(grid: SWGrid) → void

Renders the square (and optionally its vertices and center point) onto an SWGrid. Must be called inside a p5.js draw() loop.

function draw() {
    background(220);
    grid.draw();
    mySquare.drawOnGrid(grid);
}
setShowVertices(bool) / setShowCenter(bool) inherited

Toggle visibility of corner points and the center point. Setting showVertices = true on the square also enables the individual vertex SWPoint objects.

mySquare.setShowVertices(true);
mySquare.setShowCenter(true);

Animation Methods (Inherited from SWRectangle)

breathe(sinX, sinY, t) inherited
breathe(sinusoidX: SWSinusoid|null, sinusoidY: SWSinusoid|null, t: number) → void

Scales the square from its center using sinusoidal animation curves. Pass null for an axis to leave it unscaled. For uniform breathing, pass the same sinusoid for both axes.

  • sinusoidX — horizontal scale driver (or null)
  • sinusoidY — vertical scale driver (or null)
  • t — elapsed time in seconds from millis() / 1000
const sin = new SWSinusoid(0.4, Math.PI, 1.2, -Math.PI/6);
mySquare.breathe(sin, sin, millis() / 1000); // uniform
rotateAboutCenter(degPerSec, t) inherited
rotateAboutCenter(degPerSec: number, t: number) → void

Continuously rotates the square about its center. Negative rates rotate clockwise.

mySquare.rotateAboutCenter(45, totalTime / 1000);
transform({sinusoidX, sinusoidY, t, degPerSec}) inherited
transform(options: Object) → void

Applies breathing and rotation simultaneously without interference. The order of operations is: (1) scale vertices from center, (2) rotate scaled vertices about center.

mySquare.transform({
    sinusoidX: breatheSin,
    sinusoidY: breatheSin,
    t: elapsed,
    degPerSec: 30
});

Utility Methods (Inherited)

containsPoint(px, py, grid, tolerance) inherited

Returns true if screen coordinates (px, py) fall within the square's bounding region (useful for mouse hit-testing).

Usage Examples

Basic Square with Breathing

let grid, mySquare, breatheSin;

function setup() {
    createCanvas(400, 400);
    colorMode(HSB, 360, 100, 100, 100);
    initializeSWColors();

    grid = new SWGrid({
        UL: new SWPoint(-10, 10),
        LR: new SWPoint(10, -10)
    });

    const center    = new SWPoint(0, 0);
    const fillColor = new SWColor(5, 35, 95, 60, "coral");
    mySquare = new SWSquare(center, 8, fillColor);

    // Uniform breathing sinusoid: amp 0.4, period 2s, midpoint 1.2
    const amp  = 0.4;
    const freq = (2 * Math.PI) / 2.0;   // 2-second period
    const mid  = 1.2;
    breatheSin = new SWSinusoid(amp, freq, mid, -Math.PI / 6);
}

function draw() {
    background(0, 0, 93);
    grid.draw();

    const t = millis() / 1000;
    mySquare.breathe(breatheSin, breatheSin, t);  // uniform
    mySquare.drawOnGrid(grid);
}

Rhombus Transform

const sq  = new SWSquare(center, 8, fillColor);          // 0° (flat)
const rho = sq.toRhombus();                              // 45° (diamond)

// Draw both
sq.drawOnGrid(grid);
rho.fillColor = new SWColor(200, 40, 90, 40, "blue");   // different color
rho.drawOnGrid(grid);

Display Square Properties

const sq = new SWSquare(new SWPoint(0,0), 8, fillColor);

console.log("Side:           " + sq.sideLength);            // 8
console.log("Diagonal:       " + sq.diagonal.toFixed(3));   // 11.314
console.log("Inscribed r:    " + sq.inscribedCircleRadius); // 4
console.log("Circumscribed r:" + sq.circumscribedCircleRadius.toFixed(3)); // 5.657
console.log("Area:           " + sq.area);                  // 64
console.log("isSquare:       " + sq.isSquare);              // true
console.log(sq.toString());

Tips & Best Practices

💡 Use SWSquare, not SWRectangle, for squares. SWRectangle with equal width and height will work visually, but it won't give you the square-specific diagonal, inscribedCircleRadius, circumscribedCircleRadius getters or the toRhombus() method.
💡 toRhombus() returns a new instance. The original square is not modified. Store the return value in a variable if you need to use the rhombus for further operations.
⚠️ Don't set rectWidth / rectHeight directly. SWSquare sets both internally from size. If you need a different size, rebuild the square with a new size argument rather than trying to modify rectWidth or rectHeight separately (which would make it non-square).
💡 Combine breathing + rotation seamlessly. Use the inherited transform() method (not separate breathe() + rotateAboutCenter() calls) when running both animations together to avoid compounding errors.
💡 The inscribed/circumscribed circles are purely geometric. SWSquare only computes their radii — it doesn't draw them. If you want to visualize them, draw SWDisk instances using those radii at the square's center.

Source Code

Complete source for swSquare.js:

/*
File: swSquare.js
Date: 2026-02-20
Author: klp
Workspace: SketchWaveTNT2026-02-19-Stg4
Purpose: SWSquare class for SketchWaveJS
Comment(s):

This class represents a square with equal width and height, extending SWRectangle.
It is designed to be compatible with p5.js, SWColor, SWPoint, and SWGrid.
Dependencies: SWRectangle, SWPoint, SWColor, SWGrid, p5.js

*/

console.log("[swSquare.js] SWSquare class loaded.");

class SWSquare extends SWRectangle {
    /**
     * @param {SWPoint} center - Center point of the square (SWPoint)
     * @param {number} size - Side length of the square
     * @param {SWColor} fillColor - Fill color (SWColor instance)
     * @param {Object} [options] - Optional: {strokeColor, strokeWeight, showVertices, showCenter, rotation}
     *   strokeColor: SWColor for border (optional)
     *   strokeWeight: number for border thickness (optional, default 2)
     *   showVertices: boolean (default false) - show corner points
     *   showCenter: boolean (default false) - show center point
     *   rotation: number (default 0) - initial rotation in degrees (CCW)
     */
    constructor(center, size, fillColor, options = {}) {
        // Call parent constructor with size for both width and height
        super(center, size, size, fillColor, options);

        // Store size for convenience
        this.size = size;
    }//end constructor

    /**
     * Getter for side length (alias for size)
     * @returns {number} Side length
     */
    get sideLength() {
        return this.size;
    }//end sideLength

    /**
     * Getter for diagonal length of the square
     * @returns {number} Diagonal = size × √2
     */
    get diagonal() {
        return this.size * Math.sqrt(2);
    }//end diagonal

    /**
     * Getter for inscribed circle radius (incircle)
     * @returns {number} Radius = size / 2
     */
    get inscribedCircleRadius() {
        return this.size / 2;
    }//end inscribedCircleRadius

    /**
     * Getter for circumscribed circle radius (circumcircle)
     * @returns {number} Radius = size × √2 / 2
     */
    get circumscribedCircleRadius() {
        return this.size * Math.sqrt(2) / 2;
    }//end circumscribedCircleRadius

    /**
     * Converts the square to a rhombus by rotating 45 degrees
     * Returns a new SWSquare rotated 45°
     * @returns {SWSquare} New square rotated 45° (appears as a diamond)
     */
    toRhombus() {
        const rhombusRotation = (this.rotation + 45) % 360;
        return new SWSquare(
            new SWPoint(this.rCenter.x, this.rCenter.y, undefined, this.rCenter.strokeWeight, this.rCenter.strokeColor),
            this.size,
            this.fillColor,
            {
                strokeColor: this.strokeColor,
                strokeWeight: this.strokeWeight,
                showVertices: this.showVertices,
                showCenter: this.showCenter,
                rotation: rhombusRotation
            }
        );
    }//end toRhombus

    /**
     * String representation
     */
    toString() {
        return `SWSquare(center: ${this.rCenter.toString()}, size: ${this.size.toFixed(2)}, area: ${this.area.toFixed(2)}, rotation: ${this.rotation}\u00b0)`;
    }//end toString
}//end class SWSquare

// export default SWSquare;