我正在使用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
答案 0 :(得分:0)
您要提取两个 t 值之间的贝塞尔曲线的子部分。重复执行此操作,您可以将贝塞尔曲线细分为N条曲线,每个曲线可以分别绘制和着色。
此Javascript library看起来很合适(可以找到文档here)来满足这一需求。
相关方法是.split(t1,t2)
和.getLUT(steps)
,它们返回原始Bézier子区域的点坐标的查找表,在 t1 和 t2 < / em>。
现在,使用Processing,遍历坐标表并在点之间调用Processing的line()
方法以绘制相关的曲线部分(原始Bézier曲线的一些细分)。
如果失败,请使用Processing的bezierPoint()
方法自己生成点列表(请注意,必须分别为X和Y坐标调用此点),将t增加一个足够小的值以充分采样较大的Bézier曲线。再次,使用line()
遍历这些点以呈现小节。
您的问题也已经在 math.stackexchange here上得到了解决(更具描述性)。
答案 1 :(得分:0)
这里是Pomax's Bezier Primer第7节中使用de Casteljau算法的示例。 您可以通过根据t的值更改笔触中的颜色值来更改曲线的颜色。在这里,当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>
答案 2 :(得分:0)
您需要的只是P5.bezier(),P5.bezierPoint()和一些绘图功能(点,椭圆)(单击画布以绘制颜色)。
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>