4

Postscript/SVGパスから元のグラフィックプリミティブを再構築しようとしています。したがって、元の円は(SVGマークアップで)次のようにレンダリングされます。

   <path stroke-width="0.5" d="M159.679 141.309 
        C159.679 141.793 159.286 142.186 158.801 142.186 
        C158.318 142.186 157.925 141.793 157.925 141.309 
        C157.925 140.825 158.318 140.432 158.801 140.432 
        C159.286 140.432 159.679 140.825 159.679 141.309" />

これは、4つのベジェ曲線を使用して円を作成する近似です。他の場所では、円弧はリンクされたベジェ曲線で近似されます。

私の質問は、この構成を認識して「最良の」円を再構成するために使用できるアルゴリズムがあるかどうかです。私は小さなエラーを気にしません-それらは最悪の場合二次になります。

更新:これが円または円弧であるかどうかをアプリオリに知らないことに注意してください-それは何でもかまいません。また、曲線上に2、3、4、またはそれ以上のポイントが存在する可能性があります。だから私は本当にこの種の関数が欲しいです:

error = getCircleFromPath(path)

ここで、errorこれが円である可能性が高いかどうかを早期に示します。

[私はそれが円であることがわかっている場合、それはより簡単な問題であることに同意します。]

更新:@georgeは私の問題に答えるのにいくらか役立ちますが、それがすべてではないと思います。

原点に変換して正規化した後、曲線上に次の4つのポイントがあるように見えます。

point [0, 1] with control point at [+-d,1] // horizontal tangent
point [1, 0] with control point at [1,+-d] // vertical tangent
point [0, -1] with control point at [+-d,-1] // horizontal tangent
point [-1, 0] with control point at [-1,+-d] // vertical tangent

これにより、各ポイントの接線がそのポイントのパス方向に「平行」になることが保証されます。また、対称性も保証されます(反射を伴う4倍軸。ただし、円は保証されません。たとえば、の値が大きいdとボックスが丸くなり、値が小さいとひし形が丸くなります。

私の値はd約0.57のようです。これは1/sqrt(3。)かもしれませんし、他の何かかもしれません。それは私が求めているこの種の関係です。

@georgeは、円弧の中点を次のように指定します。

{p1,(p1 + 3 (p2 + p3) + p4)/8,p4}

したがって、私の例(1,0から0.1の場合)では、これは次のようになります [[1,0]+3[1,d]+3[d,1]+[0,1]] / 8

[0.5+3d/8, 3d/8+0.5]

d = 0.57の場合、これは0.71になるので、おそらくdは

(sqrt(0.5)-0.5)*8./3.

これは正方形のダイアモンドにも当てはまりますが、円弧の場合、式はより一般的である必要があり、誰かがそれを持っていればありがたいです。たとえば、私はベジェ数学に精通していないので、@georgeの式は私にとって新しいものでした

enter code here
4

4 に答える 4

5

あなたのためにすべての数学をすることなく..これは役立つかもしれません:

ベジェには常に4つのコントロールポイントがあります。カーブは、各パーツのコントロールポイント1〜4、4〜7、7〜10、および10〜13でリンクされた4つのベジエです。ポイント1、4、7、および10(&13 == 1)は、正確に曲線上にあります。あなたが素敵な円を持っているかどうかを確認するには、次のように計算します。

center =   ( p1+p7 )/2  =(  {159.679, 141.309} +  {157.925, 141.309} ) / 2
       = {158.802, 141.309}

ポイント4+10-> {158.801、141.309}を使用して同じ結果が得られることを確認します

中心がわかれば、曲線に沿ってポイントをサンプリングし、一定の距離があるかどうかを確認できます。

4点のベジェアークが1つしかない場合、中点が(p1 + 3(p2 + p3)+ p4)/8にあると便利な式が得られます。したがって、3つのポイントを通過する円を見つけることができます。

{p1,(p1 + 3 (p2 + p3) + p4)/8,p4}

カーブ上の他のポイントを再度サンプリングして、実際にほぼ円弧があるかどうかを判断します。

ベジェ式の編集は次のとおりです。

x=(1-t)^3 p1 + 3 (1-t)^2 t p2 + 3 (1-t) t^2 p3 + t^3 p4    with  parameter 0 < t < 1

たとえば、t=1/4では次のようになります。

x=( 27 p1 + 27 p2 + 9 p3 + 1 p4 ) / 64

したがって、中心を見つけたら、いくつかのポイントを簡単に確認して、それらの距離を計算できます。

ほぼ正確な円弧のみを検出したい場合は、厳密な許容誤差で2つの余分なポイントをチェックすることでうまくいくと思います。ほぼ円形のものを検出したい場合は、一連のポイントを計算し、平均誤差を基準として使用します。

于 2012-10-16T18:16:17.647 に答える
3

すべての要素が円のようなものである場合は、寸法を取得してpath.getBBox()そこから円を生成できます。この場合、楕円を検討していますが、実際のcircle要素に簡単に変換できます。

var path = document.getElementById("circle_path");
var bbox = path.getBBox();

var rx = bbox.width/2;
var ry = bbox.height/2;
var cx = bbox.x + rx;
var cy = bbox.y + ry;

var ellipse = document.createElementNS(xmlns, "ellipse");
ellipse.setAttribute("fill", "none");
ellipse.setAttribute("stroke", "red");
ellipse.setAttribute("stroke-width", 0.1);
ellipse.setAttribute("cx", cx);
ellipse.setAttribute("cy", cy);
ellipse.setAttribute("rx", rx);
ellipse.setAttribute("ry", ry);

svg.appendChild(ellipse);

ここでデモを見ることができます:

http://jsfiddle.net/nwHm6/

于 2012-10-16T01:40:03.300 に答える
1

ベジェ曲線の端点はおそらく円上にあります。もしそうなら、元の円を再構築するのは簡単です。

もう1つの可能性は、制御点が中心の周りに対称的に配置されている可能性があるため、制御点の重心を円の中心とすることです。中心から、中心に最も近い4つのコントロールポイントの平均距離として半径を取得します。

于 2012-10-16T01:18:04.770 に答える
0

楕円は、(0,0)を中心とし、平行移動(2 params)、スケーリング(2 params)、回転(1 param)の単位円として定義できます。したがって、各アークで5つのポイント(t =0¼½¾1)を取り、これらの5つのパラメーターを解きます。次に、4つのポイント(t =⅛⅜⅝⅞)の中間を取り、これらが同じ変換された円上にあるかどうかをテストします。はいの場合、whoopee !、これは変換された円(の一部)です。

直前と直後は別のまたはである可能性がありarcますarcn。これらは同じ楕円ですか?はいの場合、なす角が接触している場合は、ピースの説明を結合します。

于 2013-04-01T13:43:29.120 に答える