我正在使用 Processing 尝试绘制类似于下图的内容:
我见过一些使用 bezierVertex
来处理规则形状的例子,比如 this one ,但我想构建一个简单的绘图方法,我可以在其中指定形状的顶点,然后指定角半径。类似于 myRoundedShape(x1, y1, x2, y2, x3, y3... xn, yn, cornerRadius)
有什么想法吗?
最佳答案
如果您需要任意角度的圆角,贝塞尔曲线几乎是最糟糕的选择,因为数学非常复杂。相反,让我们使用 Catmull-Rom 曲线,因为它们被定义为“曲线通过以下点:......”而不是简单地由点控制。
对于 p1、p2 和 p3 这 3 个点之间的任意 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}
p2l_guide = {x: p2.x - 3 * radius * dx, y: p2.y - 3 * radius * dy}
和
dx = p3.x-p2.x
dy = p3.y-p2.y
p2r = {x: p2.x + radius * dx, y: p2.y + radius * dy}
p2r_guide = {x: p2.x + 3 * radius * dx, y: p2.y + 3 * radius * dy}
现在我们的边缘看起来像 p1--p2l 和 p2r--p3,诀窍是以一种漂亮的弧形方式“连接”p2l 和 p2r。所以让我们使用 curveVertex
:
beginShape();
curveVertex(p2l_guide.x,p2l_guide.y);
curveVertex(p2l.x,p2l.y);
curveVertex(p2r.x,p2r.y)
curveVertex(p2r_guide.x,p2r_guide.y);
endShape();
当然,您要处理很多边对,因此您需要预处理坐标列表,使其成为管列表 {p2l_guide,p2l,p2r,p2r_guide},然后将它们连接成直线p2r(n)--p2l(n+1) 然后添加由 ..._guide 点引导的从 p2l 到 p2r 的连接曲线。在代码中:http://jsfiddle.net/drzp6L0g/3
这个解决方案确实给我们留下了控制导向强度的神秘变量 f
,因此要解决这个问题,我们将需要贝塞尔曲线,并且我们需要确定同样的p2l和p2r点,然后应用some trigonometry弄清楚我们的控制点需要什么才能实现圆弧的近似值。它会更准确,但也需要更多工作。
当然,理想的解决方案是简单地使用 arcTo 命令,但 Processing 实际上没有。它有一个 arc()
命令,与创建形状分离(因此,如果您只需要轮廓……这可能对您来说就很好!)但如果您需要填充形状,那就不行了。
关于java - 带圆角的多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26995884/