概要
HTML5 の Canvas では、楕円を描画するためのメソッドが直接提供されていません。以下にいくつかの描画メソッドをまとめます。それぞれの方法には利点と欠点があるため、状況に応じて選択する必要があります。各メソッドのパラメータは同じです:
1.context は Canvas の 2D 描画環境オブジェクト、
2.x は楕円の中心の横座標、
3.y は楕円の中心の縦座標、
4.a は楕円の横半軸の長さ、
5.b は楕円の縦半軸の長さです。
パラメトリック方程式法
このメソッドは、楕円のパラメトリック方程式を使用して楕円を描画します
均一圧縮方式
この方法は、数学における均一圧縮の原理を使用して、円を楕円に均一に圧縮します。理論的には、次のコードにより線幅が不均一になります。解決策については、5 番目の Simonleung のコメントを参照してください。床。 。
//---------------楕円を描画するための均一圧縮方法----------------------
//メソッド 円弧メソッドは、スケールと組み合わせて円を描画するために使用されます。
//水平軸または垂直軸方向にスケールします (均一圧縮)
//このメソッドで描画される楕円のエッジは太くなるので、長軸の端に近いほど、長軸が長くなります。端点の線幅は通常の値です
//エッジが短軸に近づくほど、楕円は平らで細くなり、均一になりますこれはスケールの影響です
//リング(惑星のハロー)の立体感を表現する場合など、この欠点が利点となる場合もあります
//パラメータaの場合または b が 0 の場合、このメソッドは適用できません
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
// a と a の大きい方を選択しますb を円弧メソッドの半径パラメータとして使用
var r = (a > b) ? a : b;
var rateX = a / r; //水平軸スケーリング比
var rateY = b / r; //縦軸のスケーリング率
context.scale(ratioX, rateY); // スケール(均一圧縮)
context.beginPath();
// 楕円の左端から反時計回りに描画
context.moveTo((x a) / rateX, y / rateY);
context.arc(x / rateX , y / rateY, r, 0, 2 * Math.PI);
context.closePath ();
context.ストローク();
context.restore();
};
3 次ベジェ曲線の手法 1
3次ベジェ曲線で楕円を描くことは、実際の描画における近似であり、理論上の近似でもあります。 ただし、効率が高いため、コンピュータのベクター グラフィックスで楕円を描画するのによく使用されますが、具体的な理論についてはよくわかりません。 近似の程度は、2 つの制御点の位置の選択によって決まります。この方法の制御点の位置は私自身の実験によって取得されたものであり、精度は問題ありません。
context.save();
context.translate(x, y);
context.beginPath();
//楕円の縦軸の下端から反時計回りに描画します
context .moveTo(0, b);
context.bezierCurveTo(ox, b, a, oy, a, 0);
context.bezierCurveTo(a, -oy, ox, -b, 0 , -b) ;
context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0);
context.bezierCurveTo(-a, oy, -ox, b, 0, b );
context.closePath();
context.ストローク();
context.restore();
};
3 次ベジェ曲線の方法 2
このメソッドは StackOverFlow の投稿への返信から変更され、より精度が高く、
ctx.beginPath();
//楕円の左端から時計回りに 4 つの 3 次ベジェ曲線を描画します
ctx.moveTo(x - a, y);
ctx.bezierCurveTo ( x - a, y - oy, x - ox, y - b, x, y - b);
ctx.bezierCurveTo(x ox, y - b, x a, y - oy, x a, y);
ctx.bezierCurveTo(x a, y oy, x ox, y b, x, y b);
ctx.bezierCurveTo(x - ox, y b, x - a, y oy, x - a, y);
ctx.closePath();
ctx.ストローク();
};
ラスター方式
このメソッドは、ピクセルを操作できる Canvas の特性に基づいて、グラフィックスの基本的なアルゴリズムを使用して楕円を描画できます。 例えば、中点楕円描画アルゴリズムなど。
一例としては、庭友達の「どうどうごう」さんのブログ投稿「HTML5 キャンバス改善講座 (1) - ラスターグラフィックス (1) 中点円描画アルゴリズム」があります。この方法は比較的「独創的」で、優れた柔軟性、高効率、高精度を備えていますが、楕円を描画するための有益な関数を実装するのは比較的複雑です。たとえば、線幅が変化すると、アルゴリズムはより複雑になります。円を描画するアルゴリズムですが、楕円を描画するアルゴリズムも同様ですので、以下を参照してください。
概要
ディスプレイの解像度によって制限されるため、基本的にすべての方法で 100% の精度を達成することはできません。
実際、最良のメソッドは arc()scale() です。キャンバス描画ライブラリKineticJSはこのメソッドを使用します。
他の描画ソフトウェアには、HTML5 キャンバスのような固有の arc()scale() メソッドはありません。ベジェ曲線の数がいくつであっても、それらは単なる近似にすぎません。ベジェ曲線を使用した楕円のシミュレーションについては、ポリライン、2 次または 3 次ベジェ曲線を使用した楕円弧の描画 を参照してください。
arc()scale()はブラウザに実装されているメソッドなので理論上の精度が最も高く、効率、精度、使いやすさの点で最高です。
arc()scale() で楕円を描画した後、context.stroking() と context.restore() の 2 つのメソッドが異なる順序で呼び出され、非常に興味深い結果が得られます。通常は、最初にrestore()を実行してから、stroking()を実行する必要があります。
デモ
以下は、ラスター法に加えて楕円関数を描画するいくつかのデモです。デモ コードは次のとおりです。
<ボタン onclick="execDraw();" type="button">実行