web-dev-qa-db-ja.com

ベジェ曲線で円を作成する方法は?

開始点(x、y)と円の半径があります。ベジエ曲線ポイントからパスを作成できるエンジンもあります。

ベジエ曲線を使用して円を作成するにはどうすればよいですか?

81
Rella

すでに述べたように、ベジェ曲線を使用した円の正確な表現はありません。

他の回答を完了するには:nセグメントのベジェ曲線の場合、最適制御点までの距離は、曲線の中央が円自体の上にあるという意味で、(4/3)*tan(pi/(2n))

formula for n segments

したがって、4ポイントでは(4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831

4 point case

118
Kpym

Comp.graphics.faqでカバー

抜粋:

件名4.04:ベジェ曲線を円に合わせるにはどうすればよいですか?

興味深いことに、ベジェ曲線は円に近似できますが、円に完全には適合しません。一般的な近似は、4つのベジェを使用して円をモデル化することです。各ベジェは、制御点が端点(rは円の半径)から距離d = r * 4 *(sqrt(2)-1)/ 3で、終点の円に接する方向。これにより、ベジェの中間点が円上になり、1次導関数が連続するようになります。
この近似の半径誤差は、円の半径の約0.0273%になります。

Michael Goldapp、「3次多項式による円弧の近似」コンピューター支援幾何設計(#8 1991 pp.227-238)

Tor DokkenとMorten Daehlen、「曲率連続ベジェ曲線による円の良好な近似」コンピューター支援幾何設計(#7 1990 pp。33-41)。 http://www.sciencedirect.com/science/article/pii/016783969090019N (非無料記事)

http://spencermortensen.com/articles/bezier-circle/ の非有料の記事も参照してください。

ブラウザーとCanvas要素。

一部のブラウザはベジエ曲線を使用してキャンバスを描画し、Chromeは(現時点では)4セクターアプローチを使用し、Safariは8セクターアプローチを使用します。違いは高解像度でのみ顕著です。 、その0.0273%のため、また、円弧が平行に描画され、位相がずれている場合にのみ真に見えるため、円弧は真の円から振動していることがわかります。 、600pxの半径は通常、違いが生じるサイズです。

特定の描画APIには真のアークレンダリングがないため、ベジェ曲線も使用します。たとえば、Flashプラットフォームにはアーク描画APIがないため、アークを提供するフレームワークは通常同じベジェ曲線アプローチを使用します。

ブラウザ内のSVGエンジンは異なる描画方法を使用する場合があることに注意してください。

その他のプラットフォーム

どのプラットフォームを使用しようとしても、アーク描画がどのように行われるかを確認する価値があります。そのため、このような視覚的なエラーを予測し、適応させることができます。

30
ocodo

質問に対する答えは非常に良いので、追加することはほとんどありません。それに触発されて、4つのベジエ曲線から始めて、曲線の数を1つに減らして、ソリューションを視覚的に視覚的に確認する実験を始めました。驚いたことに、3つのベジエ曲線で円が十分に見えたことがわかりましたが、構造は少し複雑です。実際に、Inkscapeを使用して、黒の1ピクセル幅のベジエ近似を、赤の3ピクセル幅の円の上に配置しました(Inkscapeで作成)。明確にするために、ベジエ曲線の境界ボックスを示す青い線と表面を追加しました。

あなた自身を見るために、私は私の結果を提示しています:

1曲線グラフ(完全を期すために、隅に絞り込まれたドロップのように見えます): enter image description here

2曲線グラフ: enter image description here

3曲線グラフ: enter image description here

4曲線グラフ: enter image description here

(SVGまたはPDFここに配置したかったが、サポートされていない)

24
U. Windl

すでに多くの回答がありますが、非常に優れた3次ベジエ円近似の小さなオンライン記事を見つけました。単位円に関してc = 0.55191502449ここで、cは、制御点への接線に沿った軸切片点からの距離です。

中央の2つの座標が制御点である単位円の単一象限として。 (0,1),(c,1),(1,c),(1,0)

放射状の誤差は0.019608%であるため、この回答リストに追加する必要がありました。

記事はここにあります 次ベジエ曲線で近似円

7
Blindman67

他の答えは、真の円が可能でないという事実をカバーしています。このSVGファイルは、二次ベジェ曲線を使用した近似であり、取得できる最も近いものです。 http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg

キュービックベジェ曲線を使用したものを次に示します。 http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg

7
Jaffer

それは不可能。ベジエは立方体です(少なくとも...最も一般的に使用されています)。円の方程式には平方根が含まれるため、円を立方体で正確に表現することはできません。結果として、近似する必要があります。

これを行うには、円をn-tant(たとえば、四分円、八分円)に分割する必要があります。各n-tantについて、最初と最後の点をベジェ曲線の最初と最後として使用します。ベジェポリゴンには、2つの追加ポイントが必要です。高速にするために、n-tantの各極点の円の接線を取り、2つの接線の交差点として2つの点を選択します(したがって、基本的にベジェポリゴンは三角形になります)。精度に合わせてn-tantの数を増やします。

7
Stefano Borini

これは近似に関するものなので、新しい質問を開くべきかどうかはわかりませんが、ベジエの制御点を取得する一般的な式に興味があり、この質問に収まると思います。 Webで見つけたすべてのソリューションは、3次曲線専用であるか、有料であるか、理解すらできません(数学が苦手です)。だから私は自分でこれを解決しようとすることにしました。私は与えられた角度に依存する円の中心から制御点の距離を研究していましたが、これまでのところ、

enter image description here

ここで、Nは単一曲線の制御点の数であり、_α_は円弧の角度です。

二次曲線の場合、それはl ≈ r + r * PI*0.1 * pow(α/90, 2)に簡略化できます。_PI*0.1_はかなり推測です-完全な値を計算しませんでしたが、かなり近いです。これは、1〜2個の制御点を持つ曲線に対してはかなり適切に機能し、3次曲線の半径誤差は約0.2%です。高次曲線の場合、精度の低下が顕著です。 3つのコントロールポイントの曲線は2次曲線に似ているため、明らかに何か見逃していますが、それを理解することはできません。 デモ です。

1

コードを探しているだけの人へ:

https://jsfiddle.net/nooorz24/2u9forep/12/

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY) {
    ctx.beginPath();
    ctx.moveTo(
        centerX - (sizeX),
        centerY - (0)
    );
    ctx.bezierCurveTo(
        centerX - (sizeX),
        centerY - (0.552 * sizeY),
        centerX - (0.552 * sizeX),
        centerY - (sizeY),
        centerX - (0),
        centerY - (sizeY)
    );
        ctx.stroke();
}

function drawBezierOval(centerX, centerY, sizeX, sizeY) {
    drawBezierOvalQuarter(centerX, centerY, -sizeX, sizeY);
    drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY);
    drawBezierOvalQuarter(centerX, centerY, sizeX, -sizeY);
    drawBezierOvalQuarter(centerX, centerY, -sizeX, -sizeY);
}

function drawBezierCircle(centerX, centerY, size) {
    drawBezierOval(centerX, centerY, size, size)
}

drawBezierCircle(200, 200, 64)
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

これにより、4つのベジェ曲線で構成される円を描くことができます。 JSで書かれていますが、他の言語に簡単に翻訳できます

1
NoOorZ24

これを死者から取り戻してすみませんが、この投稿は this pageと一緒に非常に役立ち、展開可能な式を考え出しました。

基本的に、4つ以上の任意の数のベジェ曲線を使用できる非常に単純な数式を使用して、ニアサークルを作成できます。_Distance = radius * stepAngle / 3_

ここで、Distanceはベジェ制御点と円弧の最も近い端との間の距離、半径は円のradius、およびstepAngleは2つの端の間の角度です。 2π/(曲線の数)で表される円弧の。

ワンショットでヒットするには:Distance = radius * 2π / (the number of curves) / 3

0
bubbinator