如何在现有曲线上的两个贝塞尔点之间绘制重叠曲线 p5.js

How to draw an overlapping curve between two bezier points on existing curve p5.js

我正在使用 p5.js 绘制贝塞尔曲线。我想用另一种颜色绘制一条较短的、部分重叠的曲线。基本上,我想在某些地方改变曲线的颜色。 我能够绘制第一条曲线并从曲线中获得两个贝塞尔点,但我无法弄清楚新(较小)曲线使用哪些控制点。

bezier(x1,y1,cpx1,cpy1,cpx2,cpy2,x2,y2)
AX = x1
BX = cpx1
CX = cpx2
DX = x2

AY = y1
BY = cpy1
CY = cpy2
DY = y2

let t = 0.68;
let ncX = bezierPoint(AX, BX, CX, DX, t);
let ncY = bezierPoint(AY, BY, CY, DY, t);

let t1 = 0.93;
let ncX1 = bezierPoint(AX, BX, CX, DX, t1);
let ncY1 = bezierPoint(AY, BY, CY, DY, t1);

bezier(ncX,ncY,BX,BY,CX,CY,ncX1,ncY1)
//I tried using the original curve control points, but that didn't work

您要提取 t 两个值之间的贝塞尔曲线分段。重复此操作,您可以将一条贝塞尔曲线细分为N条曲线,每条曲线都可以单独绘制和着色。

这个Javascript library looks suitable (documentation can be found here)可以满足这个需求。

相关方法是.split(t1,t2).getLUT(steps),其中returns查找table原始贝塞尔曲线的一个分段的点坐标,在[=29=之间]t1 和 t2.

现在使用Processing,遍历坐标table并在点之间调用Processing的line()方法绘制相关曲线部分(原始贝塞尔曲线的一些细分)。

否则,使用 Processing 的 bezierPoint() 方法自行生成点列表(请注意,必须分别为 X 和 Y 坐标调用此方法),将 t 增加一个足够小的值以充分采样较大的贝塞尔曲线.同样,使用 line() 遍历这些点以呈现子部分。

您的问题也已在 math.stackexchange here.

上得到解决(更具描述性)

这是使用 Pomax's Bezier Primer 第 7 节中的 de Casteljau 算法的示例。 您可以根据 t 的值更改 stroke 中的颜色值来更改曲线的颜色。在这里,当 t < .25

时,我将曲线绘制为红色

var setup = function(){
  createCanvas(250, 250);
  noLoop();
}

var draw = function(){
  var points = [];
  points[points.length] = new pt(90, 110);
  points[points.length] = new pt(25, 40);
  points[points.length] = new pt(230, 40);
  points[points.length] = new pt(150, 240);
  var t = 1;
  while (t >= 0){
    drawCurve(points, t);
    t-=.001;
    if (t < .25){
     stroke(250,0,0);     
    }
  }
}

function drawCurve(points, t){
  if(points.length==1){
    drawPoint(points[0])
  }
  else {
   var newpoints= [];
    for(i=0; i< points.length-1; i++){
      x = (1-t) * points[i].x + t * points[i+1].x
      y = (1-t) * points[i].y + t * points[i+1].y
      newpoints[i] = new pt(x,y);
    }
    drawCurve(newpoints, t)
   }
}

function pt(x, y){
  this.x = x;
  this.y = y;
}

function drawPoint(p){
  point(p.x, p.y);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>

你只需要 P5.bezier(), P5.bezierPoint() 和一些绘图函数(点,椭圆)(点击 canvas 绘制颜色)。

let x1 = 500,
 y1 = 250,
 x2 = 0,
 y2 = 125,
 x3 = 0,
 y3 = 125,
 x4 = 500,
 y4 = 0;

let steps = 1000,       //variables needed for color change
    cStep = 250/steps,
    c = cStep;

let clicked = false;
  
function setup(){
 var canvas = createCanvas(500, 250);
 noLoop();
}

function draw(){
 background(50, 50, 100);
 noFill();
 stroke(255);
 bezier(x1, y1, x2, y2, x3, y3, x4, y4);
 stroke(100);
 text('Click', x1/2, y2);
}

mouseClicked = function() {
  if (mouseButton === LEFT) {
    if(clicked){
      clear();
        draw();
    }else{
      for (let i = 0; i <= steps; i++) {
        let t = i / steps;
       stroke(c, 250-c, 0);
          fill(c, 250-c, 0);
          let x = bezierPoint(x1, x2, x3, x4, t);
          let y = bezierPoint(y1, y2, y3, y4, t);
    // to colorize one part of the curve only 
    // you need to check the variable t, e.g.
    // between 0.2 and 0.8
          if(t>0.2 && t<0.8)
            ellipse(x, y, 1, 1)
            c=c+cStep;
      }
    }
    clicked = !clicked;
    c=cStep;
  }
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js"></script>