重新审视这一点,当我们想要带有“半径”的圆角时,我们实际上并不想要圆形连接,我们只希望等腰三角形“尖端”被四舍五入。使用贝塞尔曲线实际上很容易做到这一点,所以就这样吧。
我们仍然需要我们的偏移点 p2l 和 p2r,因为我们要对三角形 p2l--p2--p2r 进行四舍五入:
对于 3 个点 p1、p2 和 p3 之间的任意 2 条边,我们可以在 p2 的左右沿边 p1--p2 和 p2--p3 以固定距离创建新点 p2l 和 p2r p2的“半径”:
dx = p2.x-p1.x
dy = p2.y-p1.y
p2l = {x: p2.x - radius * dx, y: p2.y - radius * dy}
和
dx = p3.x-p2.x
dy = p3.y-p2.y
p2r = {x: p2.x + radius * dx, y: p2.y + radius * dy}
(请注意,我们不需要任何额外的指导点)。我们现在可以将舍入操作定义为:
start = p2l
c1 = point somewhere on line p2l--p2, ratio distance `t` from p2l and `1-t` from p2
c2 = point somewhere on line p2r--p2, using same ratio distance
end = p2r
如果我们选择比率距离为 0,那么 c1 == p2l 和 c2 == p2r,我们得到一条直线。如果我们选择比率距离 1,那么c1 == c2 == p2,我们就有可能的最尖的曲线。对于看起来不错的曲线,0.5 或 0.75 的值就可以了。所以首先,让我们定义 c1/c2 抽象函数:
float[] roundIsosceles(Point p1, Point p2, Point p3, float t) {
float mt = 1-t,
c1x = (mt*p1.x + t*p2.x),
c1y = (mt*p1.y + t*p2.y),
c2x = (mt*p3.x + t*p2.x),
c2y = (mt*p3.y + t*p2.y);
return new float[]{ c1x, c1y, c2x, c2y };
}
现在我们可以根据closed 点列表创建合适的形状:
beginShape();
Point p1,p2,p3;
for(int i=0, last=closed.size(); i<last; i+=3) {
p1 = closed.get(i);
p2 = closed.get(i+1);
p3 = closed.get(i+2);
// rounded isosceles triangle connector values:
float[] c = roundIsosceles(p1, p2, p3, 0.75);
// tell Processing that we have points to add to our shape:
vertex(p1.x,p1.y);
bezierVertex(c[0], c[1], c[2], c[3], p3.x, p3.y);
}
endShape(CLOSE);
完成了。结果如何?运行代码:http://jsfiddle.net/drzp6L0g/13,如图:
以及比率 0、0.25、0.5、0.75 和 1 之间差异的简单演示: