♠ SWSpade Reference
Inverted Heart Curve — Parametric Class — SketchWaveJS
♠ Spade Mathematics
The Inverted Heart Formula
SWSpade draws the classic playing-card spade (♠) using the same parametric formula as SWHeart, but with the y-component negated. This flips the curve vertically: the sharp point moves to the top and the two rounded lobes fall to the bottom, giving the spade silhouette.
Parametric Equations (Local Space)
y(t) = −scale · (b · cos(t) + c · cos(2t) + d · cos(3t) + e · cos(4t))
t ∈ [0, 2π), 200 sample points
The y-negation (compared to the heart) is the key transformation that creates the spade shape.
Default Coefficients & Geometry
With the default parameters (a=16, b=13, c=−5, d=−2, e=−1, scale=0.5):
| Feature | t value | Local y (approx) | Description |
|---|---|---|---|
| Sharp tip (top) | π | +8.5 | The characteristic spade point |
| Notch (center-bottom) | 0 | −2.5 | The V-notch between the two lobes |
| Lobe bottoms | ≈ 0.65, 5.63 rad | ≈ −5.3 | The lowest points; stem attaches here |
| Lobe half-width | ≈ π/2 | x ≈ ±4.0 | Widest extent of the body |
Y-Negation: Heart → Spade
The original heart formula (SWHeart) places the rounded lobes at the top and the sharp point at the bottom. Negating y (multiplying the entire y-formula by −1) produces a vertical mirror image: now the sharp tip is at top and lobes are at bottom — the spade.
Stem Attachment
The stem is a filled trapezoid. Its attachment y-coordinate is found by iterating all 200 body sample points in local space and taking the minimum y (≈ −5.3 for defaults). This ensures the stem always connects flush to the bottom of the body regardless of parameter changes.
- Neck width = stemWidth × 0.22
- Foot width = stemWidth (wider base)
- Height = stemLength (extends downward from attachment point)
Constructor
new SWSpade(center, a, b, c, d, e, fillColor, strokeColor, thickness, scale, stemLength, stemWidth, rotationDeg)
| Parameter | Type | Default | Description |
|---|---|---|---|
center | SWPoint | required | Center position in user (grid) coordinates |
a | number | 16 | Body width coefficient; controls the horizontal extent of the lobes |
b | number | 13 | Primary y-coefficient; controls overall body height |
c | number | −5 | Second harmonic coefficient; deepens the V-notch |
d | number | −2 | Third harmonic coefficient; refines lobe shape |
e | number | −1 | Fourth harmonic coefficient; subtle shape adjustment |
fillColor | SWColor | undefined | Fill color; undefined = no fill |
strokeColor | SWColor | undefined | Stroke color; undefined = no stroke |
thickness | number | 2 | Stroke weight in pixels |
scale | number | 0.5 | Global scale factor applied to both x and y body coordinates |
stemLength | number | 2.0 | Height of the trapezoid stem (grid units) |
stemWidth | number | 5.5 | Foot width of the trapezoid stem (grid units); neck = stemWidth × 0.22 |
rotationDeg | number | 0 | Static base rotation (CCW degrees); preserved across reset() |
// Minimal construction (all defaults) const center = new SWPoint(0, 0, undefined, 8, new SWColor(240, 80, 80, 100)); const fill = SWColor.fromHex('#22225a', 100, 'fill'); const stroke = SWColor.fromHex('#1a1a40', 100, 'stroke'); const spade = new SWSpade(center, 16, 13, -5, -2, -1, fill, stroke, 2, 0.5, 2.0, 5.5, 0); spade.drawOnGrid(grid);
Properties
Live Properties
| Property | Type | Description |
|---|---|---|
center | SWPoint | Center position. Drag to reposition; center.shouldShow controls dot visibility |
a, b, c, d, e | number | Shape coefficients (see Math section) |
scale | number | Global scale factor applied to body |
stemLength | number | Stem trapezoid height in grid units |
stemWidth | number | Stem foot width in grid units |
fillColor | SWColor | Fill color (undefined = no fill) |
strokeColor | SWColor | Stroke color (undefined = no outline) |
thickness | number | Stroke weight in pixels |
rotationDeg | number | Static base rotation (CCW degrees) |
rotation | number | Accumulated spin rotation (degrees); cleared by reset() |
Static Property
| Property | Value | Description |
|---|---|---|
SWSpade.SAMPLE_COUNT | 200 | Number of parametric sample points per full t ∈ [0, 2π) revolution |
Methods
Drawing
| Method | Description |
|---|---|
draw() |
Draws in raw pixel (screen) coordinates. Prefer drawOnGrid() for standard use. |
drawOnGrid(grid) |
Draws body + stem mapped through the given SWGrid. Handles y-flip automatically. Use this in the p5.js draw loop. |
Animation
| Method | Parameters | Description |
|---|---|---|
rotate(deltaAngle) |
deltaAngle: degrees (CCW+, CW−) |
Accumulates spin rotation for body + stem together. Call each frame: spade.rotate(speed * deltaT) |
Setters
| Method | Parameter | Description |
|---|---|---|
setA(v) | number | Sets coefficient a (lobe width). Recalculates body. |
setB(v) | number | Sets coefficient b (primary height). |
setC(v) | number | Sets coefficient c (notch depth). |
setD(v) | number | Sets coefficient d (lobe refinement). |
setE(v) | number | Sets coefficient e (subtle adjustment). |
setScale(s) | number > 0 | Sets global scale. Use during Pulse animation. |
setStemLength(l) | number > 0 | Sets stem trapezoid height. |
setStemWidth(w) | number > 0 | Sets stem foot width. Neck = w × 0.22. |
setRotation(deg) | number | Sets static base rotation (CCW degrees). Does not clear accumulated rotation. |
setFillColor(fc) | SWColor | Replaces fill color (deep copy stored). |
setStrokeColor(sc) | SWColor | Replaces stroke color (deep copy stored). |
setStrokeWeight(w) | number | Sets stroke thickness in pixels. |
setFillAlpha(alpha) | 0–100 | Updates fill opacity and rebuilds the p5 color object. |
setStrokeAlpha(alpha) | 0–100 | Updates stroke opacity and rebuilds the p5 color object. |
Reset & Utility
| Method | Description |
|---|---|
reset() |
Restores a, b, c, d, e, scale, stemLength, stemWidth, colors, and thickness to constructor values. Clears accumulated spin rotation. Does not move center. |
SWSpade.copy(other) (static) |
Returns a deep copy of other (including center SWPoint, colors, and accumulated rotation). |
Code Examples
1. Basic Setup (p5.js global mode)
let grid, spade; 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, undefined, 8, new SWColor(240, 80, 80, 100)); const fill = SWColor.fromHex('#22225a', 100, 'fill'); const stroke = SWColor.fromHex('#1a1a40', 100, 'stroke'); spade = new SWSpade(center, 16, 13, -5, -2, -1, fill, stroke, 2, 0.5, 2.0, 5.5, 0); } function draw() { background(0, 0, 93); grid.draw(); spade.drawOnGrid(grid); grid.updateScreenBounds(); }
2. Spin Animation
let prevT = 0; const SPIN_SPEED = 45; // degrees per second (CCW) function draw() { const t = millis() / 1000; const deltaT = (prevT > 0) ? (t - prevT) : 0; prevT = t; background(0, 0, 93); grid.draw(); spade.rotate(SPIN_SPEED * deltaT); spade.drawOnGrid(grid); grid.updateScreenBounds(); }
3. Pulse Animation (Scale Oscillation)
const BASE_SCALE = 0.5; const PULSE_SPEED = 0.5; // Hz const PULSE_AMOUNT = 0.08; // scale units function draw() { const t = millis() / 1000; background(0, 0, 93); grid.draw(); const s = BASE_SCALE + PULSE_AMOUNT * Math.sin(2 * Math.PI * PULSE_SPEED * t); spade.setScale(Math.max(0.05, s)); spade.drawOnGrid(grid); grid.updateScreenBounds(); }
4. Ghostly Trail Effect
// In setup(): create a semi-transparent background color // bgColor = new SWColor(0, 0, 93, 15, 'bg').col; // 15% opacity background // In draw(): background(bgColor); // semi-transparent clear → old frames fade slowly spade.rotate(2); // fast spin creates a ghostly star trail spade.drawOnGrid(grid);
Source Code
Show / Hide swSpade.js source
// Source will be loaded here — see shapeClasses/swSpade.js