问题描述
我正在尝试使用SVG路径创建高性能,美观的铅笔工具.
I am experimenting with creating high-performance, good-looking pencil tools using SVG paths.
我正在记录鼠标坐标以绘制路径.为了获得高保真度的路径(根据用户的运动),我需要为每个像素运动记录一个点.
I am logging the mouse coordinates to draw a path. To get a high-fidelity path (accurate to the user's movements) I need to log a point for every pixel movement.
保留路径中的每个点都会创建大量的点,对于以后的协作功能(来回发送大量的点效率不高),不是的理想选择每当我需要操纵它们时,巨大的道路就是瓶颈
Keeping each and every point in the path creates a huge amount of points which is not ideal for collaborative features later-on (sending huge amount of points back and forth is not efficient), plus parsing huge paths every time I need to manipulate them is a bottleneck
在路径的线性区域上,多余的点被删除,仅保留表示线段所需的点-我使用 Ramer-Douglas-Peucker 算法.
On linear areas of the path, redundant points are removed keeping only the points necessary to represent the segment - I do this using the Ramer-Douglas-Peucker algorithm.
在这一点上,路径实际上只是连接的线-因此,路径看起来参差不齐.
At this point the paths are effectively just connected lines - therefore the paths look jagged.
可能的解决方案是将路径点与Cubic Bezier相连-但是,这在简化路径上效果不佳.每个点之间的距离太大,以至于三次方贝塞尔曲线无法坐好",因此平滑的路径不再准确地表示用户的预期路径.
A possible solution is to connect the path points with Cubic Bezier's - however this doesn't work nice on simplified paths. The distance between each point is too large for the Cubic Bezier's to "sit" nice so the smoothed path no longer accurately represents the intended path of the user.
另一种解决方案是仅使用后处理"算法,例如施耐德算法在原始路径上-尽管该算法是性能猪,但它实际上无法实时运行
Another solution is to simply use a "post-processing" algorithm such as Schneider's Algorithm on the original path - This algorithm won't practically work in real-time though since it's a performance hog
(我认为)可行的解决方案是使用 Centtripetal Catmull -Rom 插值.
A solution that(I think) could work is to use a Centripetal Catmull-Rom interpolation.
在我研究过的所有算法中,这似乎是自以下以来最有前途的:
Out of all the algorithms I researched, this seems to be the most promising since:
- 它不会在拐角处创建自相交
- 它更贴合点,因此可以更准确地表示原始路径.
- It doesn't create self-intersections on tight corners
- It fits more snug on the points thus it more accurately represents theoriginal path.
是 Catmull-Rom 的算法,可对一系列常规的x/y点或原始路径是否需要包含曲线?
Is Catmull-Rom an algorithm that interpolates a series ofregular x/y points or does the original path need to be comprised ofcurves?
推荐答案
直接回答您的问题:
To answer your questions directly:
- 是的. Catmull-Rom样条曲线是一种对一系列(x,y,z)点进行插值的算法.它将在每两个连续的点之间生成三次多项式曲线.
- 您不能将Catmull Rom样条曲线直接用于SVG路径.您需要先将其转换为三次贝塞尔曲线.
对于由点P0,P1,P2和P3和结序列t0,t1,t2,t3定义的曲线段,可以通过提供的递归公式计算向心Catmull-Rom样条曲线(在点P1和P2之间定义)在 https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80% 93Rom_spline .因此,我在这里不再赘述.
For a curve segment defined by point P0, P1, P2 and P3 and knot sequence t0, t1, t2, t3, the centripetal Catmull-Rom spline (defined between point P1 and P2) can be computed by the recursive formula provided in https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline. Therefore, I will not elaborate here.
要将其转换为三次贝塞尔曲线,您需要计算第一个P1和P2处的导数为
To convert it to cubic Bezier curve, you need to compute the firstderivative at P1 and P2 as
M1 = (t2-t1)*(c1*(P1-P0)/(t1-t0) + c2*(P2-P1)/(t2-t1))
M2 = (t2-t1)*(d1*(P2-P1)/(t2-t1) + d2*(P3-P2)/(t3-t2))
哪里
c1 = (t2-t1)/(t2-t0),
c2 = (t1-t0)/(t2-t0),
d1 = (t3-t2)/(t3-t1),
d2 = (t2-t1)/(t3-t1)
然后您可以将其转换为具有4个控制点Q0,Q1,Q2和Q3的三次方贝塞尔曲线:
Then you can convert it to cubic Bezier curve with 4 control points: Q0, Q1, Q2 and Q3:
Q0 = P1
Q1 = P1 + M1/3
Q2 = P2 - M2/3
Q3 = P2
这篇关于SVG路径上的Catmull-Rom插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!