如何“软化”折线的边缘?

时间:2012-04-15 14:25:53

标签: graphics geometry polygon

如果由几个点组成一条线,如何通过添加中间点使线条更平滑/更柔和/更柔和 - 同时保持原始点完整无瑕并且无动于衷?

为了说明,我想在此插图中从上面到下面:

enter image description here

请注意,在上图中,如果我们从底部开始,则右转会更清晰。然而,在底部图像中,通过添加位于两个点的中间的中间点并使用其他线的角度的平均值,使得该尖锐的右转变得有点“更柔和”。 (不同的是,想象一下赛车将会驾驶的线路,因为它不会突然改变方向。)请注意,没有一个原点被“触及”,我只是添加了更多的点。

谢谢!对于它的价值,我正在使用JavaScript和Canvas实现它。

2 个答案:

答案 0 :(得分:4)

每条边(e1和e2)与每个'中间'边缘(我)相邻

  • 让X ='me'的一半长度
  • 找到超出e1和e2的“我”的两端X点距离(见下文)
  • 让这两点成为更好的控制点。
  • 使用DeCasteljau算法(example here)找到三次贝塞尔曲线的中点(2个控制点和“我”的每一端)
  • 在我的两个坐标之间插入新的“中点”。

example

FloatPoint ExtendLine(const FloatPoint A, const FloatPoint B, single distance)
{
  FloatPoint newB;
  float lenAB =  sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
  newB.X = B.x - (B.x - A.x) / lenAB * distance;
  newB.Y = B.Y - (B.Y - A.Y) / lenAB * distance;
  return newB;
}

答案 1 :(得分:-2)

以下代码elsewhere here在我正在使用的JavaScript-Canvas的特定上下文中为我完成了工作 - 但请参阅Angus对更通用方法的回答:

var max = points.length;
context.beginPath();
var i = 0;
context.moveTo(points[i].x, points[i].y);
for (i = 1; i < max - 2; i++) {
    var xc = (points[i].x + points[i + 1].x) * .5;
    var yc = (points[i].y + points[i + 1].y) * .5;
    context.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
}
context.quadraticCurveTo(points[max - 2].x, points[max - 2].y, points[max - 1].x,points[max - 1].y);
context.closePath();
context.stroke();