Sync all skills and memories 2026-04-14 07:27
This commit is contained in:
300
skills/creative/p5js/references/shapes-and-geometry.md
Normal file
300
skills/creative/p5js/references/shapes-and-geometry.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# Shapes and Geometry
|
||||
|
||||
## 2D Primitives
|
||||
|
||||
```javascript
|
||||
point(x, y);
|
||||
line(x1, y1, x2, y2);
|
||||
rect(x, y, w, h); // default: corner mode
|
||||
rect(x, y, w, h, r); // rounded corners
|
||||
rect(x, y, w, h, tl, tr, br, bl); // per-corner radius
|
||||
square(x, y, size);
|
||||
ellipse(x, y, w, h);
|
||||
circle(x, y, d); // diameter, not radius
|
||||
triangle(x1, y1, x2, y2, x3, y3);
|
||||
quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
arc(x, y, w, h, start, stop, mode); // mode: OPEN, CHORD, PIE
|
||||
```
|
||||
|
||||
### Drawing Modes
|
||||
|
||||
```javascript
|
||||
rectMode(CENTER); // x,y is center (default: CORNER)
|
||||
rectMode(CORNERS); // x1,y1 to x2,y2
|
||||
ellipseMode(CORNER); // x,y is top-left corner
|
||||
ellipseMode(CENTER); // default — x,y is center
|
||||
```
|
||||
|
||||
## Stroke and Fill
|
||||
|
||||
```javascript
|
||||
fill(r, g, b, a); // or fill(gray), fill('#hex'), fill(h, s, b) in HSB mode
|
||||
noFill();
|
||||
stroke(r, g, b, a);
|
||||
noStroke();
|
||||
strokeWeight(2);
|
||||
strokeCap(ROUND); // ROUND, SQUARE, PROJECT
|
||||
strokeJoin(ROUND); // ROUND, MITER, BEVEL
|
||||
```
|
||||
|
||||
## Custom Shapes with Vertices
|
||||
|
||||
### Basic vertex shape
|
||||
|
||||
```javascript
|
||||
beginShape();
|
||||
vertex(100, 100);
|
||||
vertex(200, 50);
|
||||
vertex(300, 100);
|
||||
vertex(250, 200);
|
||||
vertex(150, 200);
|
||||
endShape(CLOSE); // CLOSE connects last vertex to first
|
||||
```
|
||||
|
||||
### Shape modes
|
||||
|
||||
```javascript
|
||||
beginShape(); // default: polygon connecting all vertices
|
||||
beginShape(POINTS); // individual points
|
||||
beginShape(LINES); // pairs of vertices as lines
|
||||
beginShape(TRIANGLES); // triplets as triangles
|
||||
beginShape(TRIANGLE_FAN);
|
||||
beginShape(TRIANGLE_STRIP);
|
||||
beginShape(QUADS); // groups of 4
|
||||
beginShape(QUAD_STRIP);
|
||||
```
|
||||
|
||||
### Contours (holes in shapes)
|
||||
|
||||
```javascript
|
||||
beginShape();
|
||||
// outer shape
|
||||
vertex(100, 100);
|
||||
vertex(300, 100);
|
||||
vertex(300, 300);
|
||||
vertex(100, 300);
|
||||
// inner hole
|
||||
beginContour();
|
||||
vertex(150, 150);
|
||||
vertex(150, 250);
|
||||
vertex(250, 250);
|
||||
vertex(250, 150);
|
||||
endContour();
|
||||
endShape(CLOSE);
|
||||
```
|
||||
|
||||
## Bezier Curves
|
||||
|
||||
### Cubic Bezier
|
||||
|
||||
```javascript
|
||||
bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
|
||||
// x1,y1 = start point
|
||||
// cx1,cy1 = first control point
|
||||
// cx2,cy2 = second control point
|
||||
// x2,y2 = end point
|
||||
```
|
||||
|
||||
### Bezier in custom shapes
|
||||
|
||||
```javascript
|
||||
beginShape();
|
||||
vertex(100, 200);
|
||||
bezierVertex(150, 50, 250, 50, 300, 200);
|
||||
// control1, control2, endpoint
|
||||
endShape();
|
||||
```
|
||||
|
||||
### Quadratic Bezier
|
||||
|
||||
```javascript
|
||||
beginShape();
|
||||
vertex(100, 200);
|
||||
quadraticVertex(200, 50, 300, 200);
|
||||
// single control point + endpoint
|
||||
endShape();
|
||||
```
|
||||
|
||||
### Interpolation along Bezier
|
||||
|
||||
```javascript
|
||||
let x = bezierPoint(x1, cx1, cx2, x2, t); // t = 0..1
|
||||
let y = bezierPoint(y1, cy1, cy2, y2, t);
|
||||
let tx = bezierTangent(x1, cx1, cx2, x2, t); // tangent
|
||||
```
|
||||
|
||||
## Catmull-Rom Splines
|
||||
|
||||
```javascript
|
||||
curve(cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
|
||||
// cpx1,cpy1 = control point before start
|
||||
// x1,y1 = start point (visible)
|
||||
// x2,y2 = end point (visible)
|
||||
// cpx2,cpy2 = control point after end
|
||||
|
||||
curveVertex(x, y); // in beginShape() — smooth curve through all points
|
||||
curveTightness(0); // 0 = Catmull-Rom, 1 = straight lines, -1 = loose
|
||||
```
|
||||
|
||||
### Smooth curve through points
|
||||
|
||||
```javascript
|
||||
let points = [/* array of {x, y} */];
|
||||
beginShape();
|
||||
curveVertex(points[0].x, points[0].y); // repeat first for tangent
|
||||
for (let p of points) {
|
||||
curveVertex(p.x, p.y);
|
||||
}
|
||||
curveVertex(points[points.length-1].x, points[points.length-1].y); // repeat last
|
||||
endShape();
|
||||
```
|
||||
|
||||
## p5.Vector
|
||||
|
||||
Essential for physics, particle systems, and geometric computation.
|
||||
|
||||
```javascript
|
||||
let v = createVector(x, y);
|
||||
|
||||
// Arithmetic (modifies in place)
|
||||
v.add(other); // vector addition
|
||||
v.sub(other); // subtraction
|
||||
v.mult(scalar); // scale
|
||||
v.div(scalar); // inverse scale
|
||||
v.normalize(); // unit vector (length 1)
|
||||
v.limit(max); // cap magnitude
|
||||
v.setMag(len); // set exact magnitude
|
||||
|
||||
// Queries (non-destructive)
|
||||
v.mag(); // magnitude (length)
|
||||
v.magSq(); // squared magnitude (faster, no sqrt)
|
||||
v.heading(); // angle in radians
|
||||
v.dist(other); // distance to other vector
|
||||
v.dot(other); // dot product
|
||||
v.cross(other); // cross product (3D)
|
||||
v.angleBetween(other); // angle between vectors
|
||||
|
||||
// Static methods (return new vector)
|
||||
p5.Vector.add(a, b); // a + b → new vector
|
||||
p5.Vector.sub(a, b); // a - b → new vector
|
||||
p5.Vector.fromAngle(a); // unit vector at angle
|
||||
p5.Vector.random2D(); // random unit vector
|
||||
p5.Vector.lerp(a, b, t); // interpolate
|
||||
|
||||
// Copy
|
||||
let copy = v.copy();
|
||||
```
|
||||
|
||||
## Signed Distance Fields (2D)
|
||||
|
||||
SDFs return the distance from a point to the nearest edge of a shape. Negative inside, positive outside. Useful for smooth shapes, glow effects, boolean operations.
|
||||
|
||||
```javascript
|
||||
// Circle SDF
|
||||
function sdCircle(px, py, cx, cy, r) {
|
||||
return dist(px, py, cx, cy) - r;
|
||||
}
|
||||
|
||||
// Box SDF
|
||||
function sdBox(px, py, cx, cy, hw, hh) {
|
||||
let dx = abs(px - cx) - hw;
|
||||
let dy = abs(py - cy) - hh;
|
||||
return sqrt(max(dx, 0) ** 2 + max(dy, 0) ** 2) + min(max(dx, dy), 0);
|
||||
}
|
||||
|
||||
// Line segment SDF
|
||||
function sdSegment(px, py, ax, ay, bx, by) {
|
||||
let pa = createVector(px - ax, py - ay);
|
||||
let ba = createVector(bx - ax, by - ay);
|
||||
let t = constrain(pa.dot(ba) / ba.dot(ba), 0, 1);
|
||||
let closest = p5.Vector.add(createVector(ax, ay), p5.Vector.mult(ba, t));
|
||||
return dist(px, py, closest.x, closest.y);
|
||||
}
|
||||
|
||||
// Smooth boolean union
|
||||
function opSmoothUnion(d1, d2, k) {
|
||||
let h = constrain(0.5 + 0.5 * (d2 - d1) / k, 0, 1);
|
||||
return lerp(d2, d1, h) - k * h * (1 - h);
|
||||
}
|
||||
|
||||
// Rendering SDF as glow
|
||||
let d = sdCircle(x, y, width/2, height/2, 200);
|
||||
let glow = exp(-abs(d) * 0.02); // exponential falloff
|
||||
fill(glow * 255);
|
||||
```
|
||||
|
||||
## Useful Geometry Patterns
|
||||
|
||||
### Regular Polygon
|
||||
|
||||
```javascript
|
||||
function regularPolygon(cx, cy, r, sides) {
|
||||
beginShape();
|
||||
for (let i = 0; i < sides; i++) {
|
||||
let a = TWO_PI * i / sides - HALF_PI;
|
||||
vertex(cx + cos(a) * r, cy + sin(a) * r);
|
||||
}
|
||||
endShape(CLOSE);
|
||||
}
|
||||
```
|
||||
|
||||
### Star Shape
|
||||
|
||||
```javascript
|
||||
function star(cx, cy, r1, r2, npoints) {
|
||||
beginShape();
|
||||
let angle = TWO_PI / npoints;
|
||||
let halfAngle = angle / 2;
|
||||
for (let a = -HALF_PI; a < TWO_PI - HALF_PI; a += angle) {
|
||||
vertex(cx + cos(a) * r2, cy + sin(a) * r2);
|
||||
vertex(cx + cos(a + halfAngle) * r1, cy + sin(a + halfAngle) * r1);
|
||||
}
|
||||
endShape(CLOSE);
|
||||
}
|
||||
```
|
||||
|
||||
### Rounded Line (Capsule)
|
||||
|
||||
```javascript
|
||||
function capsule(x1, y1, x2, y2, weight) {
|
||||
strokeWeight(weight);
|
||||
strokeCap(ROUND);
|
||||
line(x1, y1, x2, y2);
|
||||
}
|
||||
```
|
||||
|
||||
### Soft Body / Blob
|
||||
|
||||
```javascript
|
||||
function blob(cx, cy, baseR, noiseScale, noiseOffset, detail = 64) {
|
||||
beginShape();
|
||||
for (let i = 0; i < detail; i++) {
|
||||
let a = TWO_PI * i / detail;
|
||||
let r = baseR + noise(cos(a) * noiseScale + noiseOffset,
|
||||
sin(a) * noiseScale + noiseOffset) * baseR * 0.4;
|
||||
vertex(cx + cos(a) * r, cy + sin(a) * r);
|
||||
}
|
||||
endShape(CLOSE);
|
||||
}
|
||||
```
|
||||
|
||||
## Clipping and Masking
|
||||
|
||||
```javascript
|
||||
// Clip shape — everything drawn after is masked by the clip shape
|
||||
beginClip();
|
||||
circle(width/2, height/2, 400);
|
||||
endClip();
|
||||
// Only content inside the circle is visible
|
||||
image(myImage, 0, 0);
|
||||
|
||||
// Or functional form
|
||||
clip(() => {
|
||||
circle(width/2, height/2, 400);
|
||||
});
|
||||
|
||||
// Erase mode — cut holes
|
||||
erase();
|
||||
circle(mouseX, mouseY, 100); // this area becomes transparent
|
||||
noErase();
|
||||
```
|
||||
Reference in New Issue
Block a user