2

给定一条由多个点组成的线,如何通过添加中间点使线更平滑/更曲线/更柔和——同时保持原始点完全完整且不动?

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

在此处输入图像描述

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

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

4

2 回答 2

4

与每个“中间”边缘(我)相邻的每个边缘(e1和e2)做

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

例子

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;
}
于 2012-04-15T15:43:37.937 回答
-2

在我正在使用的 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();
于 2012-04-16T22:56:32.827 回答