我一直在研究这个问题一段时间,并且因此无法提出一个好的解决方案。在Bezier曲线中放置“好”控制点
问题:我有一个三维(或更多)2D点的有序列表,我想用三次贝塞尔曲线对它们进行描边,使其“看起来很好”。 “看起来不错”的部分非常简单:我只想让第二点上的楔子变平滑(例如,曲线本身并不是双重的)。因此,给定三点时,在绘制曲线时,应该在哪里放置两个控制点,这些控制点将围绕三重点中的第二个点。
到目前为止,我的解决方案如下,但不完整。这个想法也可能有助于传达我所追求的外观。给定三点(x1,y1),(x2,y2),(x3,y3)。以每个三重点所刻出的圆(如果它们是共线的,我们只是在它们之间划一条直线并继续前进)。在点(x2,y2)取与该圆相切的直线 - 我们将在此切线上放置围绕(x2,y2)的控制点。
这是我被卡住的最后一部分。我遇到的问题是找到一种方法将两个控制点放置在该切线上 - 我有足够的启发式方法来确定它们应该位于这条线上的距离(x2,y2)有多远,但是当然,有这条线上的两点就是那么远。如果我们计算出“错误”方向的曲线,曲线就会自行循环。
为了找到由三个点(如果有任何点都具有相同的x值,简单地重新排序在下面的计算中的点)所描述的圆的中心:
double ma = (point2.y - point1.y)/(point2.x - point1.x);
double mb = (point3.y - point2.y)/(point3.x - point2.x);
CGPoint c; // Center of a circle passing through all three points.
c.x = (((ma * mb * (point1.y - point3.y)) + (mb * (point1.x + point2.x)) - (ma * (point2.x + point3.x)))/(2 * (mb - ma)));
c.y = (((-1/ma) * (c.x - ((point1.x + point2.x)/2))) + ((point1.y + point2.y)/2));
然后,找到点上切线,在这种情况下,找到了曲线会从点2至POINT3控制点:
double d = ...; // distance we want the point. Based on the distance between
// point2 and point3.
// mc: Slope of the line perpendicular to the line between
// point2 and c.
double mc = - (c.x - point2.x)/(c.y - point2.y);
CGPoint tp; // point on the tangent line
double c = point2.y - mc * point2.x; // c == y intercept
tp.x = ???; // can't figure this out, the question is whether it should be
// less than point2.x, or greater than?
tp.y = mc * tp.x + c;
// then, compute a point cp that is distance d from point2 going in the direction
// of tp.
我不怀疑这是基本的想法。数学很难。 – 2012-02-03 19:12:27