@@ -12,7 +12,7 @@ function curves(p5, fn){
12
12
* Bézier curves can form shapes and curves that slope gently. They're defined
13
13
* by two anchor points and two control points. Bézier curves provide more
14
14
* control than the spline curves created with the
15
- * <a href="#/p5/curve">curve ()</a> function.
15
+ * <a href="#/p5/spline">spline ()</a> function.
16
16
*
17
17
* The first two parameters, `x1` and `y1`, set the first anchor point. The
18
18
* first anchor point is where the curve starts.
@@ -462,63 +462,81 @@ function curves(p5, fn){
462
462
463
463
/**
464
464
* Draws a curve using a Catmull-Rom spline.
465
- *
465
+ *
466
466
* Spline curves can form shapes and curves that slope gently. They’re like
467
- * cables that are attached to a set of points. Splines are defined by two
468
- * anchor points and two control points.
469
- *
470
- * The first two parameters, `x1` and `y1`, set the first control point. This
471
- * point isn’t drawn and can be thought of as the curve’s starting point.
472
- *
473
- * The next four parameters, `x2`, `y2`, `x3`, and `y3`, set the two anchor
474
- * points. The anchor points are the start and end points of the curve’s
475
- * visible segment.
476
- *
477
- * The seventh and eighth parameters, `x4` and `y4`, set the last control
478
- * point. This point isn’t drawn and can be thought of as the curve’s ending
479
- * point.
467
+ * cables that are attached to a set of points. By default (`ends: INCLUDE`),
468
+ * the curve passes through all four points you provide, in order
469
+ * `p0(x1,y1)` -> `p1(x2,y2)` -> `p2(x3,y3)` -> `p3(x4,y4)`. Think of them as
470
+ * points on a curve. If you switch to `ends: EXCLUDE`, p0 and p3 act
471
+ * like control points and only the middle span `p1->p2` is drawn.
480
472
*
481
473
* Spline curves can also be drawn in 3D using WebGL mode. The 3D version of
482
474
* `spline()` has twelve arguments because each point has x-, y-, and
483
475
* z-coordinates.
484
476
*
485
477
* @method spline
486
- * @param {Number } x1 x-coordinate of the first control point.
487
- * @param {Number } y1 y-coordinate of the first control point.
488
- * @param {Number } x2 x-coordinate of the first anchor point.
489
- * @param {Number } y2 y-coordinate of the first anchor point.
490
- * @param {Number } x3 x-coordinate of the second anchor point.
491
- * @param {Number } y3 y-coordinate of the second anchor point.
492
- * @param {Number } x4 x-coordinate of the second control point.
493
- * @param {Number } y4 y-coordinate of the second control point.
478
+ * @param {Number } x1 x-coordinate of point p0 .
479
+ * @param {Number } y1 y-coordinate of point p0 .
480
+ * @param {Number } x2 x-coordinate of point p1 .
481
+ * @param {Number } y2 y-coordinate of point p1 .
482
+ * @param {Number } x3 x-coordinate of point p2 .
483
+ * @param {Number } y3 y-coordinate of point p2 .
484
+ * @param {Number } x4 x-coordinate of point p3 .
485
+ * @param {Number } y4 y-coordinate of point p3 .
494
486
* @chainable
495
487
*
496
488
* @example
489
+ *
490
+ * <div>
491
+ * <code>
492
+ * function setup() {
493
+ * createCanvas(200, 200);
494
+ * background(240);
495
+ * noFill();
496
+ *
497
+ * stroke(0);
498
+ * strokeWeight(2);
499
+ * spline(40, 60, 100, 40, 120, 120, 60, 140);
500
+ *
501
+ * strokeWeight(5);
502
+ * point(40, 60);
503
+ * point(100, 40);
504
+ * point(120, 120);
505
+ * point(60, 140);
506
+ *
507
+ * describe('A black spline passes smoothly through four points');
508
+ * }
509
+ * </code>
510
+ * </div>
511
+ *
497
512
* <div>
498
513
* <code>
499
514
* function setup() {
500
515
* createCanvas(100, 100);
501
516
*
502
517
* background(200);
503
518
*
519
+ * // Exclude the ends—skip the outer spans (p0→p1 and p2→p3) so only the middle span (p1→p2) is drawn.
520
+ * splineProperty('ends', EXCLUDE);
521
+ *
504
522
* // Draw a black spline curve.
505
523
* noFill();
506
524
* strokeWeight(1);
507
525
* stroke(0);
508
526
* spline(5, 26, 73, 24, 73, 61, 15, 65);
509
527
*
510
- * // Draw red spline curves from the anchor points to the control points.
528
+ * // Draw red spline curves from the points.
511
529
* stroke(255, 0, 0);
512
530
* spline(5, 26, 5, 26, 73, 24, 73, 61);
513
531
* spline(73, 24, 73, 61, 15, 65, 15, 65);
514
532
*
515
- * // Draw the anchor points in black.
533
+ * // Draw the points in black.
516
534
* strokeWeight(5);
517
535
* stroke(0);
518
536
* point(73, 24);
519
537
* point(73, 61);
520
538
*
521
- * // Draw the control points in red.
539
+ * // Draw the points in red.
522
540
* stroke(255, 0, 0);
523
541
* point(5, 26);
524
542
* point(15, 65);
@@ -546,14 +564,17 @@ function curves(p5, fn){
546
564
*
547
565
* function draw() {
548
566
* background(200);
549
- *
567
+ *
568
+ * // Exclude the ends—skip the outer spans (p0→p1 and p2→p3) so only the middle span (p1→p2) is drawn.
569
+ * splineProperty('ends', EXCLUDE);
570
+ *
550
571
* // Draw a black spline curve.
551
572
* noFill();
552
573
* strokeWeight(1);
553
574
* stroke(0);
554
575
* spline(x1, y1, 73, 24, 73, 61, 15, 65);
555
576
*
556
- * // Draw red spline curves from the anchor points to the control points.
577
+ * // Draw red spline curves from the points.
557
578
* stroke(255, 0, 0);
558
579
* spline(x1, y1, x1, y1, 73, 24, 73, 61);
559
580
* spline(73, 24, 73, 61, 15, 65, 15, 65);
@@ -564,25 +585,25 @@ function curves(p5, fn){
564
585
* point(73, 24);
565
586
* point(73, 61);
566
587
*
567
- * // Draw the control points in red.
588
+ * // Draw the points in red.
568
589
* stroke(255, 0, 0);
569
590
* point(x1, y1);
570
591
* point(15, 65);
571
592
* }
572
593
*
573
- * // Start changing the first control point if the user clicks near it.
594
+ * // Start changing the first point if the user clicks near it.
574
595
* function mousePressed() {
575
596
* if (dist(mouseX, mouseY, x1, y1) < 20) {
576
597
* isChanging = true;
577
598
* }
578
599
* }
579
600
*
580
- * // Stop changing the first control point when the user releases the mouse.
601
+ * // Stop changing the first point when the user releases the mouse.
581
602
* function mouseReleased() {
582
603
* isChanging = false;
583
604
* }
584
605
*
585
- * // Update the first control point while the user drags the mouse.
606
+ * // Update the first point while the user drags the mouse.
586
607
* function mouseDragged() {
587
608
* if (isChanging === true) {
588
609
* x1 = mouseX;
@@ -598,7 +619,10 @@ function curves(p5, fn){
598
619
* createCanvas(100, 100);
599
620
*
600
621
* background('skyblue');
601
- *
622
+ *
623
+ * // Exclude the ends—skip the outer spans (p0→p1 and p2→p3) so only the middle span (p1→p2) is drawn.
624
+ * splineProperty('ends', EXCLUDE);
625
+ *
602
626
* // Draw the red balloon.
603
627
* fill('red');
604
628
* spline(-150, 275, 50, 60, 50, 60, 250, 275);
@@ -621,7 +645,10 @@ function curves(p5, fn){
621
645
*
622
646
* function draw() {
623
647
* background('skyblue');
624
- *
648
+ *
649
+ * // Exclude the ends—skip the outer spans (p0→p1 and p2→p3) so only the middle span (p1→p2) is drawn.
650
+ * splineProperty('ends', EXCLUDE);
651
+ *
625
652
* // Rotate around the y-axis.
626
653
* rotateY(frameCount * 0.01);
627
654
*
@@ -640,16 +667,16 @@ function curves(p5, fn){
640
667
* @method spline
641
668
* @param {Number } x1
642
669
* @param {Number } y1
643
- * @param {Number } z1 z-coordinate of the first control point.
670
+ * @param {Number } z1 z-coordinate of point p0 .
644
671
* @param {Number } x2
645
672
* @param {Number } y2
646
- * @param {Number } z2 z-coordinate of the first anchor point.
673
+ * @param {Number } z2 z-coordinate of point p1 .
647
674
* @param {Number } x3
648
675
* @param {Number } y3
649
- * @param {Number } z3 z-coordinate of the second anchor point.
676
+ * @param {Number } z3 z-coordinate of point p2 .
650
677
* @param {Number } x4
651
678
* @param {Number } y4
652
- * @param {Number } z4 z-coordinate of the second control point.
679
+ * @param {Number } z4 z-coordinate of point p3 .
653
680
* @chainable
654
681
*/
655
682
fn . spline = function ( ...args ) {
@@ -664,30 +691,30 @@ function curves(p5, fn){
664
691
/**
665
692
* Calculates coordinates along a spline curve using interpolation.
666
693
*
667
- * `splinePoint()` calculates coordinates along a spline curve using the
668
- * anchor and control points . It expects points in the same order as the
694
+ * `splinePoint()` calculates coordinates along a spline curve using four
695
+ * points p0, p1, p2, p3 . It expects points in the same order as the
669
696
* <a href="#/p5/spline">spline()</a> function. `splinePoint()` works one axis
670
- * at a time. Passing the anchor and control points' x-coordinates will
671
- * calculate the x-coordinate of a point on the curve. Passing the anchor and
672
- * control points' y-coordinates will calculate the y-coordinate of a point on
697
+ * at a time. Passing the points' x-coordinates will
698
+ * calculate the x-coordinate of a point on the curve. Passing the
699
+ * points' y-coordinates will calculate the y-coordinate of a point on
673
700
* the curve.
674
701
*
675
- * The first parameter, `a`, is the coordinate of the first control point.
702
+ * The first parameter, `a`, is the coordinate of point p0 .
676
703
*
677
- * The second and third parameters, `b` and `c`, are the coordinates of the
678
- * anchor points.
704
+ * The second and third parameters, `b` and `c`, are the coordinates of
705
+ * points p1 and p2 .
679
706
*
680
- * The fourth parameter, `d`, is the coordinate of the last control point.
707
+ * The fourth parameter, `d`, is the coordinate of point p3 .
681
708
*
682
- * The fifth parameter, `t`, is the amount to interpolate along the curve. 0
683
- * is the first anchor point, 1 is the second anchor point , and 0.5 is halfway
709
+ * The fifth parameter, `t`, is the amount to interpolate along the span
710
+ * from p1 to p2. `t = 0` is p1, `t = 1` is p2 , and `t = 0.5` is halfway
684
711
* between them.
685
712
*
686
713
* @method splinePoint
687
- * @param {Number } a coordinate of first control point.
688
- * @param {Number } b coordinate of first anchor point.
689
- * @param {Number } c coordinate of second anchor point.
690
- * @param {Number } d coordinate of second control point.
714
+ * @param {Number } a coordinate of point p0 .
715
+ * @param {Number } b coordinate of point p1 .
716
+ * @param {Number } c coordinate of point p2 .
717
+ * @param {Number } d coordinate of point p3 .
691
718
* @param {Number } t amount to interpolate between 0 and 1.
692
719
* @return {Number } coordinate of a point on the curve.
693
720
*
@@ -699,7 +726,8 @@ function curves(p5, fn){
699
726
*
700
727
* background(200);
701
728
*
702
- * // Set the coordinates for the curve's anchor and control points.
729
+ *
730
+ * // Set the coordinates for the curve's four points (p0, p1, p2, p3).
703
731
* let x1 = 5;
704
732
* let y1 = 26;
705
733
* let x2 = 73;
@@ -747,7 +775,7 @@ function curves(p5, fn){
747
775
* function draw() {
748
776
* background(200);
749
777
*
750
- * // Set the coordinates for the curve's anchor and control points .
778
+ * // Set the coordinates for the curve's four points (p0, p1, p2, p3) .
751
779
* let x1 = 5;
752
780
* let y1 = 26;
753
781
* let x2 = 73;
@@ -773,6 +801,7 @@ function curves(p5, fn){
773
801
* </code>
774
802
* </div>
775
803
*/
804
+
776
805
fn . splinePoint = function ( a , b , c , d , t ) {
777
806
const s = this . _renderer . states . splineProperties . tightness ,
778
807
t3 = t * t * t ,
@@ -790,42 +819,82 @@ function curves(p5, fn){
790
819
* Tangent lines skim the surface of a curve. A tangent line's slope equals
791
820
* the curve's slope at the point where it intersects.
792
821
*
793
- * `splineTangent()` calculates coordinates along a tangent line using the
794
- * spline curve's anchor and control points. It expects points in the same
795
- * order as the <a href="#/p5/spline">spline()</a> function. `splineTangent()`
796
- * works one axis at a time. Passing the anchor and control points'
797
- * x-coordinates will calculate the x-coordinate of a point on the tangent
798
- * line. Passing the anchor and control points' y-coordinates will calculate
799
- * the y-coordinate of a point on the tangent line.
800
- *
801
- * The first parameter, `a`, is the coordinate of the first control point.
822
+ * `splineTangent()` calculates coordinates along a tangent line using four
823
+ * points p0, p1, p2, p3. It expects points in the same order as the
824
+ * <a href="#/p5/spline">spline()</a> function. `splineTangent()` works one
825
+ * axis at a time. Passing the points' x-coordinates returns the x-component of
826
+ * the tangent vector; passing the points' y-coordinates returns the y-component.
827
+ * The first parameter, `a`, is the coordinate of point p0.
802
828
*
803
- * The second and third parameters, `b` and `c`, are the coordinates of the
804
- * anchor points.
829
+ * The second and third parameters, `b` and `c`, are the coordinates of
830
+ * points p1 and p2 .
805
831
*
806
- * The fourth parameter, `d`, is the coordinate of the last control point.
832
+ * The fourth parameter, `d`, is the coordinate of point p3 .
807
833
*
808
- * The fifth parameter, `t`, is the amount to interpolate along the curve. 0
809
- * is the first anchor point, 1 is the second anchor point , and 0.5 is halfway
834
+ * The fifth parameter, `t`, is the amount to interpolate along the span
835
+ * from p1 to p2. `t = 0` is p1, `t = 1` is p2 , and `t = 0.5` is halfway
810
836
* between them.
811
837
*
812
838
* @method splineTangent
813
- * @param {Number } a coordinate of first control point.
814
- * @param {Number } b coordinate of first anchor point.
815
- * @param {Number } c coordinate of second anchor point.
816
- * @param {Number } d coordinate of second control point.
839
+ * @param {Number } a coordinate of point p0 .
840
+ * @param {Number } b coordinate of point p1 .
841
+ * @param {Number } c coordinate of point p2 .
842
+ * @param {Number } d coordinate of point p3 .
817
843
* @param {Number } t amount to interpolate between 0 and 1.
818
844
* @return {Number } coordinate of a point on the tangent line.
819
845
*
820
846
* @example
821
847
* <div>
822
848
* <code>
823
849
* function setup() {
850
+ * createCanvas(120, 120);
851
+ * describe('A black spline on a gray canvas. A red dot moves along the curve on its own. A short line shows the tangent direction at the dot.');
852
+ * }
853
+ *
854
+ * function draw() {
855
+ * background(240);
856
+ *
857
+ * const x1 = 15, y1 = 40;
858
+ * const x2 = 90, y2 = 25;
859
+ * const x3 = 95, y3 = 95;
860
+ * const x4 = 30, y4 = 110;
861
+ *
862
+ * noFill();
863
+ * stroke(0);
864
+ * strokeWeight(2);
865
+ * spline(x1, y1, x2, y2, x3, y3, x4, y4);
866
+ *
867
+ * const t = 0.5 + 0.5 * sin(frameCount * 0.03);
868
+ *
869
+ * const px = splinePoint(x1, x2, x3, x4, t);
870
+ * const py = splinePoint(y1, y2, y3, y4, t);
871
+ *
872
+ * let tx = splineTangent(x1, x2, x3, x4, t);
873
+ * let ty = splineTangent(y1, y2, y3, y4, t);
874
+ *
875
+ * const m = Math.hypot(tx, ty) || 1;
876
+ * tx = (tx / m) * 16;
877
+ * ty = (ty / m) * 16;
878
+ *
879
+ * stroke(0);
880
+ * strokeWeight(2);
881
+ * line(px, py, px + tx, py + ty);
882
+ *
883
+ * noStroke();
884
+ * fill('red');
885
+ * circle(px, py, 7);
886
+ * }
887
+ * </code>
888
+ * </div>
889
+ *
890
+ * <div>
891
+ * <code>
892
+ * function setup() {
824
893
* createCanvas(100, 100);
825
894
*
826
895
* background(200);
827
896
*
828
- * // Set the coordinates for the curve's anchor and control points .
897
+ * // Set the coordinates for the curve's four points (p0, p1, p2, p3) .
829
898
* let x1 = 5;
830
899
* let y1 = 26;
831
900
* let x2 = 73;
0 commit comments