多くの auf LineTo セグメントで構成されるフリーハンドのユーザー描画 SVG パスをより滑らかなものに変換するソリューションを探しています。
優先言語は JavaScript ですが、アドバイスは大歓迎です。
多くの auf LineTo セグメントで構成されるフリーハンドのユーザー描画 SVG パスをより滑らかなものに変換するソリューションを探しています。
優先言語は JavaScript ですが、アドバイスは大歓迎です。
まず第一に、raphael などの優れたグラフィック ライブラリを使用することをお勧めします。実際に JavaScript を使用して描画を実行するプロセスを簡素化します。
スムージングの非常に簡単な方法は、すべての lineto コマンドを同等の curveto コマンドに変換し、各線分の角度に基づいていくつかの制御点を計算することです。例えば、
<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>
これらは両方とも正三角形を描く必要があります
次のステップは、コントロール ポイントの位置を計算することです。一般に、滑らかな角の両側にある制御点は、頂点を通る架空の線上に配置する必要があります。正三角形の頂点の場合、これは水平線になります。いくつかの操作の後、次のようなものを取得できます。
<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>
トリッキーな部分はコントロール ポイントの計算ですが、それは単純な三角関数の問題に過ぎません。前述したように、ここでの目標は、2 つの制御点を角の頂点を二等分する線上に配置することです。たとえば、2 つの線分があるとします。
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
接線角度がわかれば、制御点の位置を計算できます
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 コマンドで各コントロール ポイントを配置する場所です。
CX1 Y1 X2 Y2 X3 Y3
X3 と Y3 は頂点の位置を定義します。X1 Y1 と X2 Y2 は制御点を定義します。X1 Y1 は頂点への入り方のベクトルを定義し、X2 Y2 は頂点への入り方のベクトルを定義すると考えることができます。決定しなければならない 2 つのコントロール ポイントが得られたので、
CXcp1 Ycp1 Xcp2 Ycp2 0 0
また
CXcp2 Ycp2 Xcp1 Ycp1 0 0
これは重要な決定です。裏返すとループ状になります。この時点で、この決定をどのように行うべきかを判断できるはずです...
繰り返しますが、これは非常に単純な解決策ですが、手描きのパスに適している傾向があります。より良い解決策は、さらに一歩進んで、交点を各線分の交点のくぼんだ部分に向かって内側に移動することです。これはかなり難しいです。
私は同じ問題を抱えています。paperjsの例を見ると、パスの単純化の例が1つあり、その背後にアルゴリズムが潜んでいることがわかりました。ここで見ることができます: https://github.com/paperjs/paper.js/blob/ master/src/path/PathFitter.js
パスウィッチを単純化するアルゴリズムは、「デジタル化された曲線を自動的に適合させるためのアルゴリズム」という名前の学術研究の js バージョン (最適化あり) です。
私はこのアルゴリズムのみを抽出する作業を行っており、おそらく svg.js へのプラグインとして公開する予定です。