Quick Reference
SWSector is a SketchWave class for representing circular sector ("pizza-slice") shapes in 2D space. A sector is defined by a vertex point (the tip), a radius, and an angular size theta. It supports spin animation, radius breathing, theta breathing, and hue cycling — all independently or simultaneously.
- Extends: Nothing (standalone class)
- Dependencies: SWPoint, SWColor, SWSinusoid, SWGrid, p5.js
- Key Features: Custom fill/stroke colors, arc length/area calculations, spin rotation, radius and theta breathing animations, hue cycling, vertex point display
- Common Uses: Pie charts, compass needles, fan/blade shapes, animated "Pac-Man" effects, interactive angle visualizations
Overview
The SWSector class represents a circular sector — the region bounded by two radii and the arc between them — drawn on an SWGrid. Think of it as a "pizza slice": it has a vertex (the tip), a radius, and an angular opening theta. The sector's starting orientation is controlled by startAngle, and it can be continuously spun via rotate().
Angle Convention
SWSector uses math-space (user-space) angles: angles are measured counterclockwise (CCW) from the positive x-axis, and y increases upward — the standard Cartesian convention. Because p5.js uses a y-down screen space, all angles are negated internally when calling arc(). You never need to worry about this conversion; just pass CCW degrees from +x.
// Default: startAngle=0, theta=90 → sector opens into Q1 (from +x axis upward)
let sector = new SWSector(new SWPoint(0,0), 5, 90);
// startAngle=90 → sector opens into Q2 (from +y axis leftward)
let sector2 = new SWSector(new SWPoint(0,0), 5, 90, 90);
Key Capabilities
- Flexible Positioning: Vertex defined by an SWPoint instance
- Full Styling Control: Independent fill and stroke colors using SWColor
- Geometric Properties: Automatic arc length and area calculations
- Spin Animation: Continuous rotation about the vertex via
rotate() - Breathing Animations: Oscillate radius or theta independently with SWSinusoid
- Hue Cycling: Animate fill color hue externally via SWSinusoid
- Dual Coordinate Systems: Draw in screen pixels or grid coordinates
- Vertex Point Display: Optional visualization of the sector tip
Typical Workflow
- Create an SWSector with vertex point, radius, theta, startAngle, and colors
- Draw the sector each frame using
drawOnGrid() - Call
rotate()before drawing to spin; callbreatheRadius()orbreatheTheta()after drawing to modulate next frame - Use the elapsed-time pattern for pause/resume of each animation
- Call
reset()to restore the original geometry and color
Constructor
new SWSector(vertex, radius, theta, startAngle, thickness, fillColor, strokeColor)Creates a new SWSector instance with the given geometry and styling.
| Parameter | Type | Default | Description |
|---|---|---|---|
vertex |
SWPoint | required | Tip/origin point of the sector (the pizza crust point) |
radius |
number | required | Radius in user units (> 0) |
theta |
number | required | Angular size in degrees; clamped to [0, 360] |
startAngle |
number | 0 | First-edge angle in degrees CCW from +x axis; sets initial orientation |
thickness |
number | 2 | Border (stroke) thickness in pixels |
fillColor |
SWColor | undefined | Interior fill color (no fill if undefined) |
strokeColor |
SWColor | undefined | Border color (no stroke if undefined) |
// Minimal: vertex, radius, and theta
let s1 = new SWSector(new SWPoint(0, 0), 5, 90);
// With explicit startAngle (opens into Q2)
let s2 = new SWSector(new SWPoint(0, 0), 5, 90, 90);
// With fill color and border
let fillCol = new SWColor(30, 100, 80, 80, "orange");
let strokeCol = new SWColor(0, 0, 0, 100, "black");
let s3 = new SWSector(new SWPoint(0, 0), 5, 120, 0, 2, fillCol, strokeCol);
// Fully positioned sector pointing right, half open
let v = new SWPoint(-4, 2);
let s4 = new SWSector(v, 6, 60, 270, 3, fillCol, strokeCol);
Properties
vertex SWPointThe tip point of the sector. Changing this moves the whole sector.
sector.vertex.x = 3; sector.vertex.y = -2;
radius numberThe radius of the sector in user units. Changing this directly does not update arcLength or area — use setRadius() for that.
sector.setRadius(8); // also updates arcLength and area
theta numberThe angular size of the sector in degrees, clamped to [0, 360]. Use setTheta() to keep geometry in sync.
sector.setTheta(180); // half-circle sector
startAngle numberThe static starting angle (degrees CCW from +x) for the first edge. This is the orientation before any rotation accumulates. Use setStartAngle() to change it.
sector.setStartAngle(45); // first edge at 45°
rotation numberAccumulated rotation in degrees (CCW positive). Set to 0 by the constructor; incremented by rotate(). The effective angle of the first edge is startAngle + rotation.
// Read current rotation
console.log(sector.rotation.toFixed(1) + "°");
thickness numberThe stroke (border) thickness in pixels. Use setStrokeWeight() to update.
sector.setStrokeWeight(4);
fillColor SWColorThe interior fill color as an SWColor instance. Colors are always copied to avoid shared-mutation bugs.
sector.setFillColor(new SWColor(120, 80, 90, 80, "green"));
strokeColor SWColorThe border color as an SWColor instance.
sector.setStrokeColor(swBlack);
originalRadius / originalTheta / originalStartAngle / originalRotation / originalFillColor various restore targetsSnapshot values taken at construction. reset() uses all of these to restore the sector to its initial state.
// Read-only; used internally by reset()
shouldShowVertex booleanWhether to draw the vertex SWPoint marker. Default is true.
sector.setShowVertex(false); // hide vertex dot
arcLength number computedThe arc length of the sector's curved edge: (theta / 360) × 2πr. Updated automatically when radius or theta changes.
console.log(`Arc length: ${sector.arcLength.toFixed(2)}`);
area number computedThe area of the sector: (theta / 360) × πr². Updated automatically when radius or theta changes.
console.log(`Area: ${sector.area.toFixed(2)}`);
Methods
Core Drawing Methods
draw()Draws the sector in screen (pixel) coordinates using p5.js. Rarely used directly — prefer drawOnGrid().
void
function draw() {
background(220);
sector.draw(); // vertex.x/y treated as screen pixels
}
drawOnGrid(grid)Draws the sector in user (grid) coordinates. Converts the vertex position and radius through the SWGrid's coordinate mapping.
grid(SWGrid) — the coordinate grid
void
function draw() {
background(220);
grid.draw();
sector.drawOnGrid(grid);
}
Rotation Animation
rotate(deltaAngle)Increments the sector's accumulated rotation by deltaAngle degrees (CCW positive, CW negative). Call each frame to spin the sector about its vertex.
deltaAngle(number) — degrees to add torotation
// Spin at 45°/second using elapsed time (deltaT)
sector.rotate(spinSpeed * deltaT); // call BEFORE drawOnGrid
// Or use p5 millis() for a fixed-step spin
sector.rotate(1); // 1 degree per frame
Breathing Animations
breatheRadius(sinusoid, t)Modulates the radius using an SWSinusoid. The radius is set to the sinusoid's value at time t; clamped to a minimum of 0.01. Call after drawOnGrid() so the new value takes effect on the next frame.
sinusoid(SWSinusoid) — controls radius oscillationt(number) — elapsed time in seconds
// Radius oscillates between 2 and 8 over 4 seconds
let radSin = new SWSinusoid(5, 3, 1/4, 0); // center=5, amp=3, freq=0.25 Hz
sector.drawOnGrid(grid);
sector.breatheRadius(radSin, elapsedSeconds);
breatheTheta(sinusoid, t)Modulates the angular size (theta) using an SWSinusoid. Call after drawOnGrid(). _updateGeometry() is called automatically to clamp theta and refresh area/arcLength.
sinusoid(SWSinusoid) — controls theta oscillationt(number) — elapsed time in seconds
// Theta oscillates between 20° and 160° over 3 seconds
let thetaSin = new SWSinusoid(90, 70, 1/3, 0); // center=90°, amp=70°, freq=0.33 Hz
sector.drawOnGrid(grid);
sector.breatheTheta(thetaSin, elapsedSeconds);
Color and Styling Methods
setFillColor(swColor)Sets the fill color. A copy is made automatically.
swColor(SWColor) — new fill color
sector.setFillColor(swBlue);
resetFillColor()Restores the fill color to the original stored at construction.
sector.resetFillColor();
setStrokeColor(swColor)Sets the border (stroke) color.
swColor(SWColor) — new stroke color
sector.setStrokeColor(swBlack);
setStrokeWeight(w)Sets the border thickness in pixels.
w(number) — thickness in pixels
sector.setStrokeWeight(4);
setFillAlpha(alpha)Sets the alpha (transparency) of the fill color. Clamped to [0, 100]; updates the underlying p5.js color immediately.
alpha(number) — 0 = fully transparent, 100 = fully opaque
sector.setFillAlpha(60); // 60% opaque fill
setStrokeAlpha(alpha)Sets the alpha of the stroke (border) color. Clamped to [0, 100].
alpha(number) — 0 = fully transparent, 100 = fully opaque
sector.setStrokeAlpha(80);
Geometry Methods
setRadius(r)Sets the radius and automatically updates arcLength and area.
r(number) — new radius in user units
sector.setRadius(7);
console.log(sector.area.toFixed(2));
setTheta(degrees)Sets the angular size (theta) and automatically updates arcLength and area. Value is clamped to [0, 360].
degrees(number) — new angular size in degrees
sector.setTheta(45); // narrow sector
setStartAngle(degrees)Sets the static starting angle (degrees CCW from +x) without affecting accumulated rotation.
degrees(number) — new start angle
sector.setStartAngle(180); // first edge pointing left
setShowVertex(show)Controls whether the vertex SWPoint dot is drawn.
show(boolean) — true to show, false to hide (default: true)
sector.setShowVertex(false);
Reset Methods
reset()Restores all animated properties — radius, theta, startAngle, rotation, and fillColor — to their originals captured at construction.
sector.reset(); // full restore to factory state
Utility Methods
static copy(other)Returns a deep copy of an SWSector instance. All geometry and color values are independently duplicated.
other(SWSector) — the sector to copy
SWSector — a new independent instance
let copy = SWSector.copy(sector1);
toString()Returns a string representation of the sector with all its key properties.
string
console.log(sector.toString());
// "SWSector(vertex: SWPoint(x: 0, y: 0), radius: 5.00, theta: 90.0°, startAngle: 0°, rotation: 0.0°, area: 19.63, arcLength: 7.85)"
Usage Examples
Example 1: Basic Sector with Grid
let grid;
let sector;
function setup() {
createCanvas(400, 400);
colorMode(HSB, 360, 100, 100, 100);
grid = new SWGrid({UL: new SWPoint(-10, 10), LR: new SWPoint(10, -10)});
let vertex = new SWPoint(0, 0);
let fillColor = new SWColor(30, 100, 80, 80, "orange");
let strokeCol = new SWColor(0, 0, 0, 100, "black");
sector = new SWSector(vertex, 5, 90, 0, 2, fillColor, strokeCol);
}
function draw() {
background(0, 0, 95);
grid.draw();
sector.drawOnGrid(grid);
}
Example 2: Spinning Sector (Elapsed-Time Approach)
let grid, sector;
let prevT = 0;
const SPIN_SPEED = 60; // degrees per second
function setup() {
createCanvas(400, 400);
colorMode(HSB, 360, 100, 100, 100);
grid = new SWGrid({UL: new SWPoint(-10, 10), LR: new SWPoint(10, -10)});
sector = new SWSector(new SWPoint(0, 0), 5, 60, 0, 2,
new SWColor(200, 80, 90, 80, "blue"), swBlack);
}
function draw() {
background(0, 0, 95);
grid.draw();
// Compute deltaT in seconds; spin BEFORE drawing
const t = millis() / 1000;
const deltaT = (prevT > 0) ? (t - prevT) : 0;
prevT = t;
sector.rotate(SPIN_SPEED * deltaT); // CCW positive
sector.drawOnGrid(grid);
}
Example 3: Breathing Radius
let grid, sector, radSin;
let breathStart = 0, breathElapsed = 0;
let shouldBreathe = false;
function setup() {
createCanvas(400, 400);
colorMode(HSB, 360, 100, 100, 100);
grid = new SWGrid({UL: new SWPoint(-10, 10), LR: new SWPoint(10, -10)});
sector = new SWSector(new SWPoint(0, 0), 5, 90, 0, 2,
new SWColor(120, 80, 80, 80, "green"), swBlack);
// Center=5, amplitude=3 → range [2, 8], period=4 sec → freq=0.25 Hz
radSin = new SWSinusoid(5, 3, 0.25, 0);
}
function draw() {
background(0, 0, 95);
grid.draw();
sector.drawOnGrid(grid);
if (shouldBreathe) {
const t = millis() / 1000;
breathElapsed += (t - breathStart);
breathStart = t;
sector.breatheRadius(radSin, breathElapsed); // call AFTER draw
}
text(`radius: ${sector.radius.toFixed(2)} area: ${sector.area.toFixed(2)}`, 10, 20);
}
function keyPressed() {
if (key === 'b') {
shouldBreathe = !shouldBreathe;
breathStart = millis() / 1000;
}
if (key === 'r') { sector.reset(); breathElapsed = 0; }
}
Example 4: Breathing Theta (Pac-Man Effect)
let grid, sector, thetaSin;
let thetaStart = 0, thetaElapsed = 0;
function setup() {
createCanvas(400, 400);
colorMode(HSB, 360, 100, 100, 100);
grid = new SWGrid({UL: new SWPoint(-10, 10), LR: new SWPoint(10, -10)});
sector = new SWSector(new SWPoint(0, 0), 5, 300, 30, 2,
new SWColor(55, 100, 95, 100, "yellow"), swBlack);
// Theta oscillates between 20° and 340°, period=2 sec
thetaSin = new SWSinusoid(180, 160, 0.5, 0);
thetaStart = millis() / 1000;
}
function draw() {
background(0, 0, 20); // dark background
grid.draw();
sector.drawOnGrid(grid);
const t = millis() / 1000;
thetaElapsed += (t - thetaStart);
thetaStart = t;
sector.breatheTheta(thetaSin, thetaElapsed);
}
Example 5: Simultaneous Spin + Radius Breathe + Hue Cycle
let grid, sector, radSin, hueSin;
let prevT = 0;
let rStart = 0, rElapsed = 0;
let hStart = 0, hElapsed = 0;
function setup() {
createCanvas(400, 400);
colorMode(HSB, 360, 100, 100, 100);
grid = new SWGrid({UL: new SWPoint(-10, 10), LR: new SWPoint(10, -10)});
sector = new SWSector(new SWPoint(0, 0), 5, 90, 0, 2,
new SWColor(30, 100, 80, 80, "orange"), swBlack);
radSin = new SWSinusoid(5, 3, 0.25, 0); // radius 2–8
hueSin = new SWSinusoid(180, 180, 1/3, 0); // hue 0–360
}
function draw() {
background(0, 0, 95);
grid.draw();
const t = millis() / 1000;
const deltaT = (prevT > 0) ? (t - prevT) : 0;
prevT = t;
// 1. Apply spin BEFORE draw
sector.rotate(45 * deltaT);
// 2. Apply hue cycling BEFORE draw
hElapsed += deltaT;
sector.fillColor.h = hueSin.getValue(hElapsed);
sector.fillColor.col = color(sector.fillColor.h,
sector.fillColor.s,
sector.fillColor.b,
sector.fillColor.a);
sector.drawOnGrid(grid);
// 3. Apply breathing AFTER draw
rElapsed += deltaT;
sector.breatheRadius(radSin, rElapsed);
}
Example 6: Pie Chart Sectors
let grid;
let sectors = [];
function setup() {
createCanvas(400, 400);
colorMode(HSB, 360, 100, 100, 100);
grid = new SWGrid({UL: new SWPoint(-10, 10), LR: new SWPoint(10, -10)});
// Data: percentage slices
const data = [30, 25, 20, 15, 10]; // must sum to 100
const origin = new SWPoint(0, 0);
let cumAngle = 0;
data.forEach((pct, i) => {
const theta = (pct / 100) * 360;
const hue = (i / data.length) * 360;
const fillColor = new SWColor(hue, 80, 85, 90, `slice${i}`);
const strokeCol = new SWColor(0, 0, 100, 100, "white");
sectors.push(new SWSector(SWPoint.copy(origin), 6, theta, cumAngle, 2, fillColor, strokeCol));
cumAngle += theta;
});
}
function draw() {
background(0, 0, 95);
grid.draw();
sectors.forEach(s => s.drawOnGrid(grid));
}
Best Practices
1. Animation Ordering
- Spin/hue changes BEFORE draw: These affect what is rendered this frame
- Breathing AFTER draw: The new value takes effect next frame, matching SWDisk convention
sector.rotate(speed * deltaT); // spin → before draw
sector.drawOnGrid(grid); // draw
sector.breatheRadius(sin, t); // breathe → after draw
2. Elapsed Time vs. frameCount
- Use elapsed seconds (not frame count) for all sinusoid time parameters; this decouples animation speed from frame rate
- Track
startTimeandelapsedseparately per animation so each can be paused and resumed independently
// Pattern for pauseable elapsed-time animation
let breathStart = 0, breathElapsed = 0, isBrething = false;
function toggleBreathe() {
isBrething = !isBrething;
if (isBrething) breathStart = millis() / 1000;
}
// In draw():
if (isBrething) {
const t = millis() / 1000;
breathElapsed += (t - breathStart);
breathStart = t;
sector.breatheRadius(radSin, breathElapsed);
}
3. Angle Convention
- Always pass user-space degrees (CCW from +x) to SWSector; the class handles the p5.js y-flip internally
startAngle=0means the first edge lies on the +x axis, opening CCW into Q1 by default- Positive
rotate()deltas spin CCW; negative values spin CW
4. Color Management
- Always pass SWColor instances; the constructor copies them to prevent shared-mutation bugs
- For hue cycling, modify
sector.fillColor.hdirectly and rebuild.colbefore drawing - Call
reset()orresetFillColor()to cleanly restore original colors
5. SWSinusoid Setup for Breathing
- The sinusoid's center value is the midpoint of the animation range
- The amplitude is half the desired peak-to-peak swing
- Example: range [2, 8] → center = 5, amplitude = 3
// Radius breathes between minVal and maxVal
const center = (minVal + maxVal) / 2;
const amplitude = (maxVal - minVal) / 2;
const frequency = 1 / period; // Hz (cycles per second)
let radSin = new SWSinusoid(center, amplitude, frequency, 0);
Integration with Other SketchWave Classes
Script Loading Order
Load dependencies before SWSector:
<!-- p5.js library -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.6.0/lib/p5.js"></script>
<!-- SketchWaveJS classes in dependency order -->
<script src="shapeClasses/swSinusoid.js"></script>
<script src="shapeClasses/swColor.js"></script>
<script src="shapeClasses/swPoint.js"></script>
<script src="shapeClasses/swGrid.js"></script>
<script src="shapeClasses/swSector.js"></script>
<!-- Your sketch -->
<script src="sketches/yourSketch.js"></script>
Working with SWPoint
SWSector uses SWPoint for its vertex (tip):
- The vertex is a full SWPoint instance — it is drawn as a small dot when
shouldShowVertexis true - Drag or reposition the sector by changing
sector.vertex.xandsector.vertex.y
// Move vertex to user coordinates (2, -3)
sector.vertex.x = 2;
sector.vertex.y = -3;
Working with SWColor
SWSector uses SWColor for all color management (HSB mode):
- Colors are automatically copied to prevent shared-mutation bugs
- For hue cycling, mutate
sector.fillColor.hthen rebuildsector.fillColor.col
// Hue cycling by direct mutation (done before drawOnGrid)
sector.fillColor.h = hueSin.getValue(hElapsed);
sector.fillColor.col = color(sector.fillColor.h,
sector.fillColor.s,
sector.fillColor.b,
sector.fillColor.a);
Working with SWGrid
SWSector integrates with SWGrid for coordinate mapping:
- Use
drawOnGrid(grid)to draw in user units — the grid converts both position and radius to screen pixels - The average of
grid.xScaleandgrid.yScaleis used for the radius, keeping the sector circular even on non-square grids
Working with SWSinusoid
SWSector's breathing methods accept SWSinusoid instances:
- One sinusoid for
breatheRadius(), a separate one forbreatheTheta() - The sinusoid's
getValue(t)is called with elapsed time in seconds
Source Code
The complete SWSector class implementation:
Show/Hide Source Code
/*
File: swSector.js
Date: 2026-03-28
Author: klp
App: SketchWaveTNT2026-03-19-Stg7
Purpose: SWSector class for SketchWaveJS
SWSector represents a "pizza-slice" (sector) shape defined by:
- A vertex SWPoint (the tip of the slice)
- A radius (in user units)
- A theta (angular size in degrees)
- A startAngle (degrees CCW from the +x axis, where the first edge lies)
- A rotation offset (degrees, accumulated via rotate())
Default orientation: one edge lies along the +x axis, sector opens CCW
into the first quadrant. Set startAngle to establish a different static
starting position before rotation begins.
Animations (all independent, all composable):
- rotate(delta): call each frame to spin the sector about its vertex.
- breatheRadius(sinusoid, t): oscillates the radius with an SWSinusoid.
- breatheTheta(sinusoid, t): oscillates the angular size with an SWSinusoid.
Color cycling: mutate fillColor.h and rebuild fillColor.col before drawing.
Angle convention:
User space (math): angles are CCW from +x axis, y increases upward.
p5 / screen space: angles are CW from +x axis, y increases downward.
Conversion: p5_angle = -user_angle (negate because y is flipped).
Drawing a sector whose first edge is at totalAngle = startAngle + rotation,
spanning theta degrees CCW:
p5 arc start = -radians(totalAngle + theta)
p5 arc stop = -radians(totalAngle)
arc(cx, cy, 2r, 2r, p5Start, p5Stop, PIE) — p5 arc is clockwise.
*/
console.log("[swSector.js] SWSector class loaded.");
class SWSector {
constructor(vertex, radius, theta, startAngle = 0, thickness = 2,
fillColor = undefined, strokeColor = undefined) {
this.vertex = vertex;
this.radius = radius;
this.theta = theta;
this.startAngle = startAngle;
this.rotation = 0;
this.thickness = thickness;
this.fillColor = fillColor ? SWColor.copy(fillColor) : undefined;
this.strokeColor = strokeColor ? SWColor.copy(strokeColor) : undefined;
this.originalRadius = radius;
this.originalTheta = theta;
this.originalStartAngle = startAngle;
this.originalRotation = 0;
this.originalFillColor = fillColor ? SWColor.copy(fillColor) : undefined;
this.shouldShowVertex = true;
this._updateGeometry();
}
_updateGeometry() {
this.theta = Math.max(0, Math.min(360, this.theta));
this.arcLength = (this.theta / 360) * 2 * Math.PI * this.radius;
this.area = (this.theta / 360) * Math.PI * this.radius * this.radius;
}
draw() {
this._drawArc(this.vertex.x, this.vertex.y, this.radius);
if (this.shouldShowVertex && this.vertex && this.vertex.draw) {
this.vertex.draw(this.strokeColor);
}
}
drawOnGrid(grid) {
const { x: cx, y: cy } = grid.userToScreen(this.vertex.x, this.vertex.y);
const rScreen = (grid.xScale * this.radius + grid.yScale * this.radius) / 2;
this._drawArc(cx, cy, rScreen);
if (this.shouldShowVertex && this.vertex && this.vertex.drawOnGrid) {
this.vertex.drawOnGrid(grid, this.strokeColor);
}
}
_drawArc(cx, cy, r) {
const totalAngle = this.startAngle + this.rotation;
const p5Start = -radians(totalAngle + this.theta);
const p5Stop = -radians(totalAngle);
if (this.fillColor && this.fillColor.col) {
fill(this.fillColor.col);
} else {
noFill();
}
if (this.strokeColor && this.strokeColor.col) {
stroke(this.strokeColor.col);
} else {
noStroke();
}
strokeWeight(this.thickness);
arc(cx, cy, 2 * r, 2 * r, p5Start, p5Stop, PIE);
noStroke();
noFill();
strokeWeight(1);
}
rotate(deltaAngle) {
this.rotation += deltaAngle;
}
breatheRadius(sinusoid, t) {
this.radius = Math.max(0.01, sinusoid.getValue(t));
this._updateGeometry();
}
breatheTheta(sinusoid, t) {
this.theta = sinusoid.getValue(t);
this._updateGeometry();
}
setFillAlpha(alpha) {
if (this.fillColor) {
this.fillColor.a = Math.max(0, Math.min(100, alpha));
this.fillColor.col = color(
this.fillColor.h, this.fillColor.s,
this.fillColor.b, this.fillColor.a
);
}
}
setStrokeAlpha(alpha) {
if (this.strokeColor) {
this.strokeColor.a = Math.max(0, Math.min(100, alpha));
this.strokeColor.col = color(
this.strokeColor.h, this.strokeColor.s,
this.strokeColor.b, this.strokeColor.a
);
}
}
reset() {
this.radius = this.originalRadius;
this.theta = this.originalTheta;
this.startAngle = this.originalStartAngle;
this.rotation = this.originalRotation;
if (this.originalFillColor) {
this.fillColor = SWColor.copy(this.originalFillColor);
}
this._updateGeometry();
}
resetFillColor() {
if (this.originalFillColor) {
this.fillColor = SWColor.copy(this.originalFillColor);
}
}
setFillColor(swColor) { this.fillColor = swColor ? SWColor.copy(swColor) : undefined; }
setStrokeColor(swColor) { this.strokeColor = swColor ? SWColor.copy(swColor) : undefined; }
setStrokeWeight(w) { this.thickness = w; }
setRadius(r) { this.radius = r; this._updateGeometry(); }
setTheta(degrees) { this.theta = degrees; this._updateGeometry(); }
setStartAngle(degrees) { this.startAngle = degrees; }
setShowVertex(show = true) { this.shouldShowVertex = show; }
static copy(other) {
if (!(other instanceof SWSector)) {
throw new Error('Argument to SWSector.copy must be an SWSector instance');
}
const s = new SWSector(
SWPoint.copy(other.vertex),
other.originalRadius,
other.originalTheta,
other.originalStartAngle,
other.thickness,
other.fillColor,
other.strokeColor
);
s.radius = other.radius;
s.theta = other.theta;
s.startAngle = other.startAngle;
s.rotation = other.rotation;
s.shouldShowVertex = other.shouldShowVertex;
s._updateGeometry();
return s;
}
toString() {
return `SWSector(vertex: ${this.vertex.toString()}, ` +
`radius: ${this.radius.toFixed(2)}, theta: ${this.theta.toFixed(1) + String.fromCharCode(176)}, ` +
`startAngle: ${this.startAngle + String.fromCharCode(176)}, ` +
`rotation: ${this.rotation.toFixed(1) + String.fromCharCode(176)}, ` +
`area: ${this.area.toFixed(2)}, arcLength: ${this.arcLength.toFixed(2)})`;
}
}//end SWSector class