diff --git a/src/core/shape/curves.js b/src/core/shape/curves.js index 0932cbaa9c..0a3695118c 100644 --- a/src/core/shape/curves.js +++ b/src/core/shape/curves.js @@ -11,68 +11,197 @@ import '../friendly_errors/file_errors'; import '../friendly_errors/validate_params'; /** - * Draws a cubic Bezier curve on the screen. These curves are defined by a - * series of anchor and control points. The first two parameters specify - * the first anchor point and the last two parameters specify the other - * anchor point, which become the first and last points on the curve. The - * middle parameters specify the two control points which define the shape - * of the curve. Approximately speaking, control points "pull" the curve - * towards them. - * - * Bezier curves were developed by French automotive engineer Pierre Bezier, - * and are commonly used in computer graphics to define gently sloping curves. - * See also curve(). + * Draws a Bézier curve. + * + * Bézier curves can form shapes and curves that slope gently. They're defined + * by two anchor points and two control points. Bézier curves provide more + * control than the spline curves created with the + * curve() function. + * + * The first two parameters, `x1` and `y1`, set the first anchor point. The + * first anchor point is where the curve starts. + * + * The next four parameters, `x2`, `y2`, `x3`, and `y3`, set the two control + * points. The control points "pull" the curve towards them. + * + * The seventh and eighth parameters, `x4` and `y4`, set the last anchor + * point. The last anchor point is where the curve ends. + * + * Bézier curves can also be drawn in 3D using WebGL mode. The 3D version of + * `bezier()` has twelve arguments because each point has x-, y-, + * and z-coordinates. * * @method bezier - * @param {Number} x1 x-coordinate for the first anchor point - * @param {Number} y1 y-coordinate for the first anchor point - * @param {Number} x2 x-coordinate for the first control point - * @param {Number} y2 y-coordinate for the first control point - * @param {Number} x3 x-coordinate for the second control point - * @param {Number} y3 y-coordinate for the second control point - * @param {Number} x4 x-coordinate for the second anchor point - * @param {Number} y4 y-coordinate for the second anchor point + * @param {Number} x1 x-coordinate of the first anchor point. + * @param {Number} y1 y-coordinate of the first anchor point. + * @param {Number} x2 x-coordinate of the first control point. + * @param {Number} y2 y-coordinate of the first control point. + * @param {Number} x3 x-coordinate of the second control point. + * @param {Number} y3 y-coordinate of the second control point. + * @param {Number} x4 x-coordinate of the second anchor point. + * @param {Number} y4 y-coordinate of the second anchor point. * @chainable + * * @example *
- * noFill();
- * stroke(255, 102, 0);
- * line(85, 20, 10, 10);
- * line(90, 90, 15, 80);
- * stroke(0, 0, 0);
- * bezier(85, 20, 10, 10, 90, 90, 15, 80);
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * strokeWeight(5);
+ * point(85, 20);
+ * point(15, 80);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(10, 10);
+ * point(90, 90);
+ *
+ * // Draw a black bezier curve.
+ * noFill();
+ * stroke(0);
+ * strokeWeight(1);
+ * bezier(85, 20, 10, 10, 90, 90, 15, 80);
+ *
+ * // Draw red lines from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * line(85, 20, 10, 10);
+ * line(15, 80, 90, 90);
+ *
+ * describe(
+ * 'A gray square with three curves. A black s-curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
+ * );
+ * }
*
*
- * background(0, 0, 0);
- * noFill();
- * stroke(255);
- * bezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);
+ * // Click the mouse near the red dot in the top-left corner
+ * // and drag to change the curve's shape.
+ *
+ * let x2 = 10;
+ * let y2 = 10;
+ * let isChanging = false;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe(
+ * 'A gray square with three curves. A black s-curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * strokeWeight(5);
+ * point(85, 20);
+ * point(15, 80);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(x2, y2);
+ * point(90, 90);
+ *
+ * // Draw a black bezier curve.
+ * noFill();
+ * stroke(0);
+ * strokeWeight(1);
+ * bezier(85, 20, x2, y2, 90, 90, 15, 80);
+ *
+ * // Draw red lines from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * line(85, 20, x2, y2);
+ * line(15, 80, 90, 90);
+ * }
+ *
+ * // Start changing the first control point if the user clicks near it.
+ * function mousePressed() {
+ * if (dist(mouseX, mouseY, x2, y2) < 20) {
+ * isChanging = true;
+ * }
+ * }
+ *
+ * // Stop changing the first control point when the user releases the mouse.
+ * function mouseReleased() {
+ * isChanging = false;
+ * }
+ *
+ * // Update the first control point while the user drags the mouse.
+ * function mouseDragged() {
+ * if (isChanging === true) {
+ * x2 = mouseX;
+ * y2 = mouseY;
+ * }
+ * }
*
*
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background('skyblue');
+ *
+ * // Draw the red balloon.
+ * fill('red');
+ * bezier(50, 60, 5, 15, 95, 15, 50, 60);
+ *
+ * // Draw the balloon string.
+ * line(50, 60, 50, 80);
+ *
+ * describe('A red balloon in a blue sky.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A red balloon in a blue sky. The balloon rotates slowly, revealing that it is flat.');
+ * }
+ *
+ * function draw() {
+ * background('skyblue');
+ *
+ * // Rotate around the y-axis.
+ * rotateY(frameCount * 0.01);
+ *
+ * // Draw the red balloon.
+ * fill('red');
+ * bezier(0, 0, 0, -45, -45, 0, 45, -45, 0, 0, 0, 0);
+ *
+ * // Draw the balloon string.
+ * line(0, 0, 0, 0, 20, 0);
+ * }
+ *
+ *
+ * // Draw the original curve.
+ *
* function setup() {
- * createCanvas(100, 100, WEBGL);
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * strokeWeight(5);
+ * point(85, 20);
+ * point(15, 80);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(10, 10);
+ * point(90, 90);
+ *
+ * // Draw a black bezier curve.
* noFill();
- * bezierDetail(5);
+ * stroke(0);
+ * strokeWeight(1);
+ * bezier(85, 20, 10, 10, 90, 90, 15, 80);
+ *
+ * // Draw red lines from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * line(85, 20, 10, 10);
+ * line(15, 80, 90, 90);
+ *
+ * describe(
+ * 'A gray square with three curves. A black s-curve has two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
+ * );
* }
+ *
+ *
+ * // Draw the curve with less detail.
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
*
- * function draw() {
* background(200);
- * bezier(
- * -40, -40, 0,
- * 90, -40, 0,
- * -90, 40, 0,
- * 40, 40, 0
+ *
+ * // Set the curveDetail() to 5.
+ * bezierDetail(5);
+ *
+ * // Draw the anchor points in black.
+ * stroke(0);
+ * strokeWeight(5);
+ * point(35, -30, 0);
+ * point(-35, 30, 0);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(-40, -40, 0);
+ * point(40, 40, 0);
+ *
+ * // Draw a black bezier curve.
+ * noFill();
+ * stroke(0);
+ * strokeWeight(1);
+ * bezier(35, -30, 0, -40, -40, 0, 40, 40, 0, -35, 30, 0);
+ *
+ * // Draw red lines from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * line(35, -30, -40, -40);
+ * line(-35, 30, 40, 40);
+ *
+ * describe(
+ * 'A gray square with three curves. A black s-curve is drawn with jagged segments. Two straight, red lines that extend from its ends. The endpoints of all the curves are marked with dots.'
* );
* }
*
*
- * noFill();
- * let x1 = 85,
- x2 = 10,
- x3 = 90,
- x4 = 15;
- * let y1 = 20,
- y2 = 10,
- y3 = 90,
- y4 = 80;
- * bezier(x1, y1, x2, y2, x3, y3, x4, y4);
- * fill(255);
- * let steps = 10;
- * for (let i = 0; i <= steps; i++) {
- * let t = i / steps;
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Set the coordinates for the curve's anchor and control points.
+ * let x1 = 85;
+ * let x2 = 10;
+ * let x3 = 90;
+ * let x4 = 15;
+ * let y1 = 20;
+ * let y2 = 10;
+ * let y3 = 90;
+ * let y4 = 80;
+ *
+ * // Style the curve.
+ * noFill();
+ *
+ * // Draw the curve.
+ * bezier(x1, y1, x2, y2, x3, y3, x4, y4);
+ *
+ * // Draw circles along the curve's path.
+ * fill(255);
+ *
+ * // Top-right.
+ * let x = bezierPoint(x1, x2, x3, x4, 0);
+ * let y = bezierPoint(y1, y2, y3, y4, 0);
+ * circle(x, y, 5);
+ *
+ * // Center.
+ * x = bezierPoint(x1, x2, x3, x4, 0.5);
+ * y = bezierPoint(y1, y2, y3, y4, 0.5);
+ * circle(x, y, 5);
+ *
+ * // Bottom-left.
+ * x = bezierPoint(x1, x2, x3, x4, 1);
+ * y = bezierPoint(y1, y2, y3, y4, 1);
+ * circle(x, y, 5);
+ *
+ * describe('A black s-curve on a gray square. The endpoints and center of the curve are marked with white circles.');
+ * }
+ *
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe('A black s-curve on a gray square. A white circle moves back and forth along the curve.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Set the coordinates for the curve's anchor and control points.
+ * let x1 = 85;
+ * let x2 = 10;
+ * let x3 = 90;
+ * let x4 = 15;
+ * let y1 = 20;
+ * let y2 = 10;
+ * let y3 = 90;
+ * let y4 = 80;
+ *
+ * // Draw the curve.
+ * noFill();
+ * bezier(x1, y1, x2, y2, x3, y3, x4, y4);
+ *
+ * // Calculate the circle's coordinates.
+ * let t = 0.5 * sin(frameCount * 0.01) + 0.5;
* let x = bezierPoint(x1, x2, x3, x4, t);
* let y = bezierPoint(y1, y2, y3, y4, t);
+ *
+ * // Draw the circle.
+ * fill(255);
* circle(x, y, 5);
* }
*
*
- * noFill();
- * bezier(85, 20, 10, 10, 90, 90, 15, 80);
- * let steps = 6;
- * fill(255);
- * for (let i = 0; i <= steps; i++) {
- * let t = i / steps;
- * // Get the location of the point
- * let x = bezierPoint(85, 10, 90, 15, t);
- * let y = bezierPoint(20, 10, 90, 80, t);
- * // Get the tangent points
- * let tx = bezierTangent(85, 10, 90, 15, t);
- * let ty = bezierTangent(20, 10, 90, 80, t);
- * // Calculate an angle from the tangent points
- * let a = atan2(ty, tx);
- * a += PI;
- * stroke(255, 102, 0);
- * line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);
- * // The following line of code makes a line
- * // inverse of the above line
- * //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Set the coordinates for the curve's anchor and control points.
+ * let x1 = 85;
+ * let x2 = 10;
+ * let x3 = 90;
+ * let x4 = 15;
+ * let y1 = 20;
+ * let y2 = 10;
+ * let y3 = 90;
+ * let y4 = 80;
+ *
+ * // Style the curve.
+ * noFill();
+ *
+ * // Draw the curve.
+ * bezier(x1, y1, x2, y2, x3, y3, x4, y4);
+ *
+ * // Draw tangents along the curve's path.
+ * fill(255);
+ *
+ * // Top-right circle.
* stroke(0);
- * ellipse(x, y, 5, 5);
- * }
- *
- *
- * noFill();
- * bezier(85, 20, 10, 10, 90, 90, 15, 80);
- * stroke(255, 102, 0);
- * let steps = 16;
- * for (let i = 0; i <= steps; i++) {
- * let t = i / steps;
- * let x = bezierPoint(85, 10, 90, 15, t);
- * let y = bezierPoint(20, 10, 90, 80, t);
- * let tx = bezierTangent(85, 10, 90, 15, t);
- * let ty = bezierTangent(20, 10, 90, 80, t);
- * let a = atan2(ty, tx);
- * a -= HALF_PI;
- * line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);
+ * // Top-right tangent line.
+ * // Scale the tangent point to draw a shorter line.
+ * stroke(255, 0, 0);
+ * let tx = 0.1 * bezierTangent(x1, x2, x3, x4, 0);
+ * let ty = 0.1 * bezierTangent(y1, y2, y3, y4, 0);
+ * line(x + tx, y + ty, x - tx, y - ty);
+ *
+ * // Center circle.
+ * stroke(0);
+ * x = bezierPoint(x1, x2, x3, x4, 0.5);
+ * y = bezierPoint(y1, y2, y3, y4, 0.5);
+ * circle(x, y, 5);
+ *
+ * // Center tangent line.
+ * // Scale the tangent point to draw a shorter line.
+ * stroke(255, 0, 0);
+ * tx = 0.1 * bezierTangent(x1, x2, x3, x4, 0.5);
+ * ty = 0.1 * bezierTangent(y1, y2, y3, y4, 0.5);
+ * line(x + tx, y + ty, x - tx, y - ty);
+ *
+ * // Bottom-left circle.
+ * stroke(0);
+ * x = bezierPoint(x1, x2, x3, x4, 1);
+ * y = bezierPoint(y1, y2, y3, y4, 1);
+ * circle(x, y, 5);
+ *
+ * // Bottom-left tangent.
+ * // Scale the tangent point to draw a shorter line.
+ * stroke(255, 0, 0);
+ * tx = 0.1 * bezierTangent(x1, x2, x3, x4, 1);
+ * ty = 0.1 * bezierTangent(y1, y2, y3, y4, 1);
+ * line(x + tx, y + ty, x - tx, y - ty);
+ *
+ * describe(
+ * 'A black s-curve on a gray square. The endpoints and center of the curve are marked with white circles. Red tangent lines extend from the white circles.'
+ * );
* }
*
*
- * noFill();
- * stroke(255, 102, 0);
- * curve(5, 26, 5, 26, 73, 24, 73, 61);
- * stroke(0);
- * curve(5, 26, 73, 24, 73, 61, 15, 65);
- * stroke(255, 102, 0);
- * curve(73, 24, 73, 61, 15, 65, 15, 65);
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Draw a black spline curve.
+ * noFill();
+ * strokeWeight(1);
+ * stroke(0);
+ * curve(5, 26, 73, 24, 73, 61, 15, 65);
+ *
+ * // Draw red spline curves from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * curve(5, 26, 5, 26, 73, 24, 73, 61);
+ * curve(73, 24, 73, 61, 15, 65, 15, 65);
+ *
+ * // Draw the anchor points in black.
+ * strokeWeight(5);
+ * stroke(0);
+ * point(73, 24);
+ * point(73, 61);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(5, 26);
+ * point(15, 65);
+ *
+ * describe(
+ * 'A gray square with a curve drawn in three segments. The curve is a sideways U shape with red segments on top and bottom, and a black segment on the right. The endpoints of all the segments are marked with dots.'
+ * );
+ * }
*
*
- * // Define the curve points as JavaScript objects
- * let p1 = { x: 5, y: 26 };
- * let p2 = { x: 73, y: 24 };
- * let p3 = { x: 73, y: 61 };
- * let p4 = { x: 15, y: 65 };
- * noFill();
- * stroke(255, 102, 0);
- * curve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
- * stroke(0);
- * curve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
- * stroke(255, 102, 0);
- * curve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);
+ * let x1 = 5;
+ * let y1 = 26;
+ * let isChanging = false;
+ *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe(
+ * 'A gray square with a curve drawn in three segments. The curve is a sideways U shape with red segments on top and bottom, and a black segment on the right. The endpoints of all the segments are marked with dots.'
+ * );
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Draw a black spline curve.
+ * noFill();
+ * strokeWeight(1);
+ * stroke(0);
+ * curve(x1, y1, 73, 24, 73, 61, 15, 65);
+ *
+ * // Draw red spline curves from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * curve(x1, y1, x1, y1, 73, 24, 73, 61);
+ * curve(73, 24, 73, 61, 15, 65, 15, 65);
+ *
+ * // Draw the anchor points in black.
+ * strokeWeight(5);
+ * stroke(0);
+ * point(73, 24);
+ * point(73, 61);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(x1, y1);
+ * point(15, 65);
+ * }
+ *
+ * // Start changing the first control point if the user clicks near it.
+ * function mousePressed() {
+ * if (dist(mouseX, mouseY, x1, y1) < 20) {
+ * isChanging = true;
+ * }
+ * }
+ *
+ * // Stop changing the first control point when the user releases the mouse.
+ * function mouseReleased() {
+ * isChanging = false;
+ * }
+ *
+ * // Update the first control point while the user drags the mouse.
+ * function mouseDragged() {
+ * if (isChanging === true) {
+ * x1 = mouseX;
+ * y1 = mouseY;
+ * }
+ * }
*
*
- * noFill();
- * stroke(255, 102, 0);
- * curve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);
- * stroke(0);
- * curve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);
- * stroke(255, 102, 0);
- * curve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background('skyblue');
+ *
+ * // Draw the red balloon.
+ * fill('red');
+ * curve(-150, 275, 50, 60, 50, 60, 250, 275);
+ *
+ * // Draw the balloon string.
+ * line(50, 60, 50, 80);
+ *
+ * describe('A red balloon in a blue sky.');
+ * }
*
*
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * describe('A red balloon in a blue sky.');
+ * }
+ *
+ * function draw() {
+ * background('skyblue');
+ *
+ * // Rotate around the y-axis.
+ * rotateY(frameCount * 0.01);
+ *
+ * // Draw the red balloon.
+ * fill('red');
+ * curve(-200, 225, 0, 0, 10, 0, 0, 10, 0, 200, 225, 0);
+ *
+ * // Draw the balloon string.
+ * line(0, 10, 0, 0, 30, 0);
+ * }
+ *
+ *
* function setup() {
- * createCanvas(100, 100, WEBGL);
+ * createCanvas(100, 100);
*
- * curveDetail(5);
- * }
- * function draw() {
* background(200);
*
- * curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);
+ * // Draw a black spline curve.
+ * noFill();
+ * strokeWeight(1);
+ * stroke(0);
+ * curve(5, 26, 73, 24, 73, 61, 15, 65);
+ *
+ * // Draw red spline curves from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * curve(5, 26, 5, 26, 73, 24, 73, 61);
+ * curve(73, 24, 73, 61, 15, 65, 15, 65);
+ *
+ * // Draw the anchor points in black.
+ * strokeWeight(5);
+ * stroke(0);
+ * point(73, 24);
+ * point(73, 61);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(5, 26);
+ * point(15, 65);
+ *
+ * describe(
+ * 'A gray square with a curve drawn in three segments. The curve is a sideways U shape with red segments on top and bottom, and a black segment on the right. The endpoints of all the segments are marked with dots.'
+ * );
* }
*
*
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * background(200);
+ *
+ * // Set the curveDetail() to 3.
+ * curveDetail(3);
+ *
+ * // Draw a black spline curve.
+ * noFill();
+ * strokeWeight(1);
+ * stroke(0);
+ * curve(-45, -24, 0, 23, -26, 0, 23, 11, 0, -35, 15, 0);
+ *
+ * // Draw red spline curves from the anchor points to the control points.
+ * stroke(255, 0, 0);
+ * curve(-45, -24, 0, -45, -24, 0, 23, -26, 0, 23, 11, 0);
+ * curve(23, -26, 0, 23, 11, 0, -35, 15, 0, -35, 15, 0);
+ *
+ * // Draw the anchor points in black.
+ * strokeWeight(5);
+ * stroke(0);
+ * point(23, -26);
+ * point(23, 11);
+ *
+ * // Draw the control points in red.
+ * stroke(255, 0, 0);
+ * point(-45, -24);
+ * point(-35, 15);
+ *
+ * describe(
+ * 'A gray square with a jagged curve drawn in three segments. The curve is a sideways U shape with red segments on top and bottom, and a black segment on the right. The endpoints of all the segments are marked with dots.'
+ * );
+ * }
+ *
+ *
- * // Move the mouse left and right to see the curve change
+ * // Move the mouse left and right to see the curve change.
+ *
* function setup() {
* createCanvas(100, 100);
- * noFill();
+ *
+ * describe('A black curve forms a sideways U shape. The curve deforms as the user moves the mouse from left to right');
* }
*
* function draw() {
- * background(204);
- * let t = map(mouseX, 0, width, -5, 5);
+ * background(200);
+ *
+ * // Set the curve's tightness using the mouse.
+ * let t = map(mouseX, 0, 100, -5, 5, true);
* curveTightness(t);
+ *
+ * // Draw the curve.
+ * noFill();
* beginShape();
* curveVertex(10, 26);
* curveVertex(10, 26);
@@ -432,9 +920,6 @@ p5.prototype.curveDetail = function(d) {
* }
*
*
- * noFill();
- * curve(5, 26, 5, 26, 73, 24, 73, 61);
- * curve(5, 26, 73, 24, 73, 61, 15, 65);
- * fill(255);
- * ellipseMode(CENTER);
- * let steps = 6;
- * for (let i = 0; i <= steps; i++) {
- * let t = i / steps;
- * let x = curvePoint(5, 5, 73, 73, t);
- * let y = curvePoint(26, 26, 24, 61, t);
- * ellipse(x, y, 5, 5);
- * x = curvePoint(5, 73, 73, 15, t);
- * y = curvePoint(26, 24, 61, 65, t);
- * ellipse(x, y, 5, 5);
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Set the coordinates for the curve's anchor and control points.
+ * let x1 = 5;
+ * let y1 = 26;
+ * let x2 = 73;
+ * let y2 = 24;
+ * let x3 = 73;
+ * let y3 = 61;
+ * let x4 = 15;
+ * let y4 = 65;
+ *
+ * // Draw the curve.
+ * noFill();
+ * curve(x1, y1, x2, y2, x3, y3, x4, y4);
+ *
+ * // Draw circles along the curve's path.
+ * fill(255);
+ *
+ * // Top.
+ * let x = curvePoint(x1, x2, x3, x4, 0);
+ * let y = curvePoint(y1, y2, y3, y4, 0);
+ * circle(x, y, 5);
+ *
+ * // Center.
+ * x = curvePoint(x1, x2, x3, x4, 0.5);
+ * y = curvePoint(y1, y2, y3, y4, 0.5);
+ * circle(x, y, 5);
+ *
+ * // Bottom.
+ * x = curvePoint(x1, x2, x3, x4, 1);
+ * y = curvePoint(y1, y2, y3, y4, 1);
+ * circle(x, y, 5);
+ *
+ * describe('A black curve on a gray square. The endpoints and center of the curve are marked with white circles.');
* }
*
*
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe('A black curve on a gray square. A white circle moves back and forth along the curve.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Set the coordinates for the curve's anchor and control points.
+ * let x1 = 5;
+ * let y1 = 26;
+ * let x2 = 73;
+ * let y2 = 24;
+ * let x3 = 73;
+ * let y3 = 61;
+ * let x4 = 15;
+ * let y4 = 65;
+ *
+ * // Draw the curve.
+ * noFill();
+ * curve(x1, y1, x2, y2, x3, y3, x4, y4);
+ *
+ * // Calculate the circle's coordinates.
+ * let t = 0.5 * sin(frameCount * 0.01) + 0.5;
+ * let x = curvePoint(x1, x2, x3, x4, t);
+ * let y = curvePoint(y1, y2, y3, y4, t);
+ *
+ * // Draw the circle.
+ * fill(255);
+ * circle(x, y, 5);
+ * }
+ *
+ *
- * noFill();
- * curve(5, 26, 73, 24, 73, 61, 15, 65);
- * let steps = 6;
- * for (let i = 0; i <= steps; i++) {
- * let t = i / steps;
- * let x = curvePoint(5, 73, 73, 15, t);
- * let y = curvePoint(26, 24, 61, 65, t);
- * //ellipse(x, y, 5, 5);
- * let tx = curveTangent(5, 73, 73, 15, t);
- * let ty = curveTangent(26, 24, 61, 65, t);
- * let a = atan2(ty, tx);
- * a -= PI / 2.0;
- * line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * // Set the coordinates for the curve's anchor and control points.
+ * let x1 = 5;
+ * let y1 = 26;
+ * let x2 = 73;
+ * let y2 = 24;
+ * let x3 = 73;
+ * let y3 = 61;
+ * let x4 = 15;
+ * let y4 = 65;
+ *
+ * // Draw the curve.
+ * noFill();
+ * curve(x1, y1, x2, y2, x3, y3, x4, y4);
+ *
+ * // Draw tangents along the curve's path.
+ * fill(255);
+ *
+ * // Top circle.
+ * stroke(0);
+ * let x = curvePoint(x1, x2, x3, x4, 0);
+ * let y = curvePoint(y1, y2, y3, y4, 0);
+ * circle(x, y, 5);
+ *
+ * // Top tangent line.
+ * // Scale the tangent point to draw a shorter line.
+ * stroke(255, 0, 0);
+ * let tx = 0.2 * curveTangent(x1, x2, x3, x4, 0);
+ * let ty = 0.2 * curveTangent(y1, y2, y3, y4, 0);
+ * line(x + tx, y + ty, x - tx, y - ty);
+ *
+ * // Center circle.
+ * stroke(0);
+ * x = curvePoint(x1, x2, x3, x4, 0.5);
+ * y = curvePoint(y1, y2, y3, y4, 0.5);
+ * circle(x, y, 5);
+ *
+ * // Center tangent line.
+ * // Scale the tangent point to draw a shorter line.
+ * stroke(255, 0, 0);
+ * tx = 0.2 * curveTangent(x1, x2, x3, x4, 0.5);
+ * ty = 0.2 * curveTangent(y1, y2, y3, y4, 0.5);
+ * line(x + tx, y + ty, x - tx, y - ty);
+ *
+ * // Bottom circle.
+ * stroke(0);
+ * x = curvePoint(x1, x2, x3, x4, 1);
+ * y = curvePoint(y1, y2, y3, y4, 1);
+ * circle(x, y, 5);
+ *
+ * // Bottom tangent line.
+ * // Scale the tangent point to draw a shorter line.
+ * stroke(255, 0, 0);
+ * tx = 0.2 * curveTangent(x1, x2, x3, x4, 1);
+ * ty = 0.2 * curveTangent(y1, y2, y3, y4, 1);
+ * line(x + tx, y + ty, x - tx, y - ty);
+ *
+ * describe(
+ * 'A black curve on a gray square. A white circle moves back and forth along the curve.'
+ * );
* }
*
*