如何平滑徒手绘制的SVG路径? [英] How to smooth a freehand drawn SVG path?

查看:117
本文介绍了如何平滑徒手绘制的SVG路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种解决方案,将徒手用户绘制的SVG路径(包括许多auf LineTo段)转换为更平滑的路径。

I am looking for a solution to convert a freehand, user drawn SVG path, consisting of lots auf LineTo segments, into a smoother one.

首选语言将是JavaScript,但欢迎任何建议。

Preferred language would be JavaScript, but any advice is welcome.

推荐答案

首先,我建议使用一个好的图形库,例如raphael。它将简化实际使用javascript来执行绘图的过程。

first of all, I would recommend using a good graphics library, such as raphael. It will simplify the process of actually using javascript to perform the drawing.

一种非常简单的平滑方法是使用等效的curveto命令转换所有lineto命令并计算一些控制点基于每个线段的角度。例如,

A very simple method of smoothing is to convert all lineto commands with equivalent curveto commands and calculate some control points based on the angles of each line segment. For example,

<svg width="1000" height="1000" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<path d="
M250 150 
L150 350
L350 350
L250 150
" />

</svg> 

变为

<svg width="1000" height="1000" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<path d="
M250 150 
C250 150 150 350 150 350
C150 350 350 350 350 350
C350 350 250 150 250 150
" />

</svg> 

这两个都应画一个等边三角形

Both of these should draw an equilateral triangle

下一步是计算控制点的位置。通常,您希望平滑角两侧的控制点落在穿过顶点的假想线上。在等边三角形的顶点的情况下,这将是水平线。经过一些操作后,你可以得到这样的结果:

The next step would be to calculate the position of the control points. Generally, you will want the control points on either side of a smooth corner to fall on an imaginary line that passes through the vertex. In the case of the top point of the equilateral triangle, this would be horizontal line. After some manipulation, you can get something like this:

<svg width="1000" height="1000" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<path d="
M250 150 
C230 150 140 333 150 350
C160 367 340 367 350 350
C360 333 270 150 250 150
" />

</svg> 

棘手的部分是计算控制点,但这不仅仅是一个简单的触发问题。正如我之前提到的,这里的目标是将两个控制点放在一条平分角点顶点的线上。例如,假设我们有两个线段:

The tricky part is calculating the control points, but that turns into not much more than a simple trig problem. As I mentioned previously, the goal here is to put the two control points on a line that bisects the corner vertex. For example, suppose we have two line segments:

A. (0,0) to (3,2)
B. (0,0) to (1,-4)

the absolute angle of A is arctan(2/3) = 33.69 deg
the absolute angle of B is arctan(-4/1) = -75.96 deg
the bisection angle of AB is (33.69 + -75.96)/2 = -21.135
the tangent angle is AB is (-21.135 + 90) = 68.865

知道切线角度,我们可以计算出控制点头寸

knowing the tangent angle, we can calculate the control point positions

smoothness = radius = r
tangent angle = T
Vertex X = Xv
Vertex Y = Yv

Control Point 1:
Xcp1 = cos(T)*r
Ycp1 = sin(T)*r

Control Point 2:
Xcp2 = cos(T)*(-r)
Ycp2 = sin(T)*(-r)

最后一个问题是将每个控制点放在实际的curveTo命令中:

The last problem is where to put each control point in the actual curveTo command:

CX1 Y1 X2 Y2 X3 Y3

X3和Y3定义顶点位置。 X1 Y1和X2 Y2定义控制点。您可以将X1 Y1视为定义如何进入顶点的向量,将X2 Y2定义为定义如何离开的向量。既然您有两个控制点,您必须决定

X3 and Y3 define the vertex location. X1 Y1 and X2 Y2 define the control points. You can think of X1 Y1 as defining the vector of how to enter the vertex and X2 Y2 as defining the vector of how to leave. Now that you have the two control points you must decide on

CXcp1 Ycp1 Xcp2 Ycp2 0 0

CXcp2 Ycp2 Xcp1 Ycp1 0 0

这是一个重要的决定。如果你向后移动它们,形状将看起来像一个循环。到目前为止,您应该能够确定如何做出这个决定......

this is an important decision. If you get them backwards, the shape will look like a loop. By this point you should be able to determine how this decision should be made...

同样,这是一个非常简单的解决方案,但它往往看起来很好用手绘制的路径。一个更好的解决方案可能会更进一步,并将交叉点向内移向每个线段交叉点的凹面部分。这是一个更具挑战性的问题。

Again, this is a very simple solution, but it tends to look good for hand drawn paths. A better solution might take it a step further and move the intersection point inwards towards the concave section of each line segment intersection. This is quite a bit more challenging.

这篇关于如何平滑徒手绘制的SVG路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆