SWSpade Reference

Composite Shape (Inverted Heart + SWSpire) — SketchWaveJS

♠ Composite Class Design

SWSpade is a composite class. It draws the traditional playing-card spade ♠ using two parts:

  • Body — the classic inverted heart, rendered as a closed polygon from a 4-harmonic parametric curve sampled at 200 points. The y-axis is negated to flip the standard heart upward into the spade orientation.
  • StemSWSpire with halfShape = true and rotationDeg = 180, producing a downward-pointing cusp arch whose base attaches at the lowest point of the body.

The attachment point of the stem is computed each frame by _getBodyMinLy(), which samples the body curve to find the minimum local y (the lowest point of the two lobes). This keeps the stem correctly positioned even as the scale parameter changes during pulse animation.

Draw order: stem is drawn first (behind), then the body on top. The body fill naturally covers the arch base, hiding the seam.

Mathematical Foundation

Body: Inverted Parametric Heart

The body uses the classic 4-harmonic heart parametric equations, with the y component negated to produce the spade orientation (sharp tip pointing up, lobes curving down):

x(t) = scale · a · sin³(t)
y(t) = −scale · (b·cos(t) + c·cos(2t) + d·cos(3t) + e·cos(4t))

Defaults: a=16, b=13, c=−5, d=−2, e=−1, scale=0.5
t ∈ [0, 2π),   200 sample points

At t = π/2, x = scale · a and y = 0, placing the widest point of the right lobe at the horizontal midline. The sharp upward cusp occurs at t = π/2 (or equivalently t = −π/2 for the top tip) due to the sin³ term collapsing to zero while the y harmonic sum reaches its minimum (most negative).

Coefficient Interpretation

ParamRoleDefaultEffect of increasing
aWidth amplitude16Wider left/right lobes
bPrimary y harmonic (cos 1)13Taller overall shape; deeper lower lobes
cSecond y harmonic (cos 2)−5Sharpens / blunts the tip; more negative = sharper tip
dThird y harmonic (cos 3)−2Adds subtle secondary inflection near the top
eFourth y harmonic (cos 4)−1Fine-tunes lobe curvature near base
scaleUniform scale factor0.5Scales entire body in grid units

Stem: Half SWSpire Arch

The stem is a half-arch traced from t = 0 to t = π:

x(t) = radiusX · |cos(t)|2/power · sign(cos(t))
y(t) = radiusY · |sin(t)|2/power · sign(sin(t))

t ∈ [0, π],  closed with CLOSE

With rotationDeg = 180 + total rotation, the arch base lies horizontally at y = 0 in local space and curves down to a cusp at (0, −radiusY). endShape(CLOSE) closes the arch with a flat base.

Stem Placement (Attachment Math)

Let minLy = _getBodyMinLy() (the minimum local-y of the body, a negative number ≈ −5.3 at defaults). After applying total rotation θ:

stemX = center.x − minLy · sin(θ)
stemY = center.y + minLy · cos(θ)

Because minLy is negative, −minLy is positive, so the formula places the stem below the body at the correct local-y position. The rotation matrix keeps the stem attached during spin.

Constructor

new SWSpade(center, a, b, c, d, e,
           fillColor, strokeColor, thickness, scale,
           stemLength, stemWidth, stemPower, rotationDeg, stemOffset)
ParameterTypeDefaultDescription
centerSWPointrequiredCenter of the body in user (grid) coordinates
anumber16Width amplitude of the heart parametric curve
bnumber13Primary y harmonic (cos 1t coefficient)
cnumber−5Second y harmonic (cos 2t coefficient)
dnumber−2Third y harmonic (cos 3t coefficient)
enumber−1Fourth y harmonic (cos 4t coefficient)
fillColorSWColorundefinedFill color for body and stem; undefined = no fill
strokeColorSWColorundefinedStroke color; undefined = no stroke
thicknessnumber2Stroke weight in pixels
scalenumber0.5Uniform scale factor (grid units); controls overall body size (min 0.01)
stemLengthnumber2.0SWSpire radiusY: depth of the downward cusp arch (grid units, min 0.1)
stemWidthnumber0.6SWSpire radiusX: half-width of the arch base (grid units, min 0.05)
stemPowernumber5SWSpire power exponent: 1 = smooth arch; 9 = sharp spike
stemOffsetnumber0Additional vertical shift of the stem center along the body-bottom axis (grid units); positive moves the stem toward the body
rotationDegnumber0Static base rotation in CCW degrees; persists across reset()

Properties

PropertyTypeDescription
centerSWPointBody center in user coordinates. Move by setting center.x, center.y.
anumberWidth amplitude.
bnumberPrimary y harmonic coefficient.
cnumberSecond y harmonic coefficient.
dnumberThird y harmonic coefficient.
enumberFourth y harmonic coefficient.
scalenumberCurrent uniform scale factor.
stemLengthnumberCurrent stem depth (SWSpire radiusY).
stemWidthnumberCurrent stem half-width (SWSpire radiusX).
stemPowernumberCurrent cusp sharpness exponent.
stemOffsetnumberCurrent vertical stem offset (grid units). Positive = toward body.
fillColorSWColorShared fill color for body and stem.
strokeColorSWColorShared stroke color.
thicknessnumberStroke weight in pixels.
rotationDegnumberStatic base rotation (CCW degrees). Persists across reset().
rotationnumberAccumulated spin from rotate(). Cleared by reset().
SAMPLE_COUNTstatic number200 — number of parametric sample points for the body polygon.
_stemSWSpireInternal. Do not access directly.

Methods

Drawing

MethodDescription
drawOnGrid(grid)Syncs stem then draws stem + body through SWGrid coordinate mapping. Preferred method.
draw()Syncs stem then draws in raw screen (pixel) coordinates. Use only when no grid is present.

Animation

MethodDescription
rotate(deltaAngle)Adds deltaAngle degrees (CCW+, CW−) to rotation. Call once per frame: spade.rotate(speed * deltaT).

Setters

MethodParameterDescription
setA(v)numberSets the width amplitude a.
setB(v)numberSets primary y harmonic b.
setC(v)numberSets second y harmonic c.
setD(v)numberSets third y harmonic d.
setE(v)numberSets fourth y harmonic e.
setScale(s)number ≥ 0.01Sets the uniform scale factor. Stem attachment recalculates automatically on next draw.
setStemLength(l)number ≥ 0.1Sets the stem cusp depth.
setStemWidth(w)number ≥ 0.05Sets the stem base half-width.
setStemPower(p)number ≥ 1Sets the cusp sharpness exponent.
setRotation(deg)numberSets the static base rotation (CCW degrees).
setFillColor(fc)SWColor|undefinedSets the fill color (deep copies the SWColor).
setStrokeColor(sc)SWColor|undefinedSets the stroke color.
setStrokeWeight(w)numberSets stroke thickness in pixels.
setFillAlpha(alpha)0–100Sets fill opacity and rebuilds the p5 color object.
setStrokeAlpha(alpha)0–100Sets stroke opacity and rebuilds the p5 color object.

Reset & Utility

MethodDescription
reset()Restores all parameters to constructor values. Clears rotation. Does not move center.
static copy(other)Returns a deep copy of the SWSpade, preserving all current and original state.
toString()Returns a summary string of current parameter values.

Code Examples

Basic Setup

let spade;
let grid;

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 fillCol    = SWColor.fromHex('#22225a', 100, 'fill');
    const strokeCol  = SWColor.fromHex('#1a1a40', 100, 'stroke');

    spade = new SWSpade(center, 16, 13, -5, -2, -1,
                         fillCol, strokeCol, 2, 0.5,
                         2.0, 0.6, 5, 0);
}

function draw() {
    background(240, 10, 95);
    grid.draw();
    spade.drawOnGrid(grid);
}

Spin Animation

let prevT = 0;

function draw() {
    const t      = millis() / 1000;
    const deltaT = (prevT > 0) ? (t - prevT) : 0;
    prevT = t;

    background(240, 10, 95);
    grid.draw();
    spade.rotate(45 * deltaT);  // 45 °/sec CCW
    spade.drawOnGrid(grid);
}

Pulse Animation

let pulseBase = 0.5;   // base scale

function draw() {
    const t = millis() / 1000;

    background(240, 10, 95);
    grid.draw();

    // Oscillate scale ±0.08 at 0.5 Hz — stem follows automatically
    const s = pulseBase + 0.08 * Math.sin(2 * Math.PI * 0.5 * t);
    spade.setScale(Math.max(0.05, s));

    spade.drawOnGrid(grid);
}

Copy & Reset

// Deep copy
const spade2 = SWSpade.copy(spade);
spade2.center.x += 5;   // moved independently

// Restore factory values
spade.reset();

// Inspect
console.log(spade.toString());
// SWSpade(scale=0.50, a=16, b=13, c=-5, d=-2, e=-1, stemLength=2.0, ...)

Source Code

📄 Toggle Source: swSpade.js
Loading source...
↑ Top