在 p5.js 中画一条不同宽度的线

Draw a line of varying width in p5.js

我想在我的 canvas 上绘制宽度从头到尾逐渐变化的线条。也就是说,假设该行以 width = 1 开始于 (0, 0)(相当于 strokeWeight)并以 (50, 50) 结束于 width = 3,并且 width必须(线性)从 1 增加到 3 从开始到结束。

关于如何实现这一点有什么想法吗?无法从网上抓取它。

关键是将线分成例如 30 段。你用递增的 strokeWeight() 绘制每个线段。您拥有的线段越多,线条看起来就越平滑。

您可以使用 lerp() 找到两端点之间的 x,y 坐标。

您可以使用 lerp() 查找两端之间的线 strokeWeight()

function setup() {
  createCanvas(200, 200);
  background("black");
  stroke("white");
  gradientLine(0, 0, 50, 50, 1, 3, 30);
  noLoop();
}

function gradientLine(
  start_x,
  start_y,
  end_x,
  end_y,
  start_weight,
  end_weight,
  segments
) {
  let prev_loc_x = start_x;
  let prev_loc_y = start_y;
  for (let i = 1; i <= segments; i++) {
    let cur_loc_x = lerp(start_x, end_x, i / segments);
    let cur_loc_y = lerp(start_y, end_y, i / segments);
    push();
    strokeWeight(lerp(start_weight, end_weight, i / segments));
    line(prev_loc_x, prev_loc_y, cur_loc_x, cur_loc_y);
    pop();
    prev_loc_x = cur_loc_x;
    prev_loc_y = cur_loc_y;
  }
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script>

编辑: 此外,如果使用 alpha < 255 的颜色,可能会出现这样的伪像:

发生这种情况是因为笔划的默认上限设置为 ROUND。设置 strokeCap(SQUARE) 将解决此问题:

这需要在gradientLine(...)函数中的push()...pop()块中设置。 (注意:这会使线的末端看起来很平,需要更精细的工作。)

您也可以使用 beginShape() / endShape() 将线画成“梯形”,并将线的每一端转换成两个单独的点。请参阅下面的代码片段:

function setup() {
  createCanvas(400, 400);
  noStroke();
  fill(220);
}

function draw() {
  background(20);
  drawVaryingWidthLine(0, 0, 50, 50, 1, 3);
  drawVaryingWidthLine(80, 20, 200, 140, 1, 5);
  drawVaryingWidthLine(30, 60, 230, 260, 10, 3);
  drawVaryingWidthLine(210, 180, 360, 330, 40, 20);
}


function drawVaryingWidthLine(x1, y1, x2, y2,  startWidth, endWidth) { 
  const halfStartWidth = startWidth / 2
  const halfEndwidth = endWidth / 2
  beginShape();
    vertex(x1 + halfStartWidth, y1 - halfStartWidth);
    vertex(x2 + halfEndwidth, y2 - halfEndwidth);
    vertex(x2 - halfEndwidth, y2 + halfEndwidth);
    vertex(x1 - halfStartWidth, y1 + halfStartWidth);
    vertex(x1 + halfStartWidth, y1 - halfStartWidth);
  endShape();
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="sketch.js"></script>
  </body>
</html>

与@ffmaer 的解决方案相比,此解决方案没有任何平滑度/透明度瑕疵。 我认为我的速度稍快一些,因为每条线只绘制一个形状(尽管我还没有测试过)。但是,这里的这个版本目前仅限于原始 post 中要求的角度线(右下角 45 度)。通过调整梯形的角位置,可以很容易地适应任意角度。

编辑:根据@ffmaer 的评论,现在使用梯形而不是三角形。