概要 HTML5 の Canvas は、楕円を描画するためのメソッドを直接提供しません。以下にいくつかの描画メソッドをまとめます。それぞれの方法には利点と欠点があるため、状況に応じて選択する必要があります。各メソッドのパラメータは同じです:
context は Canvas の 2D 描画環境オブジェクト、
x は楕円の中心の横座標、
y は楕円の中心の縦座標、
aは楕円の横半軸の長さ、
b は楕円の縦半軸の長さです。
パラメトリック方程式メソッド このメソッドは、楕円のパラメトリック方程式を使用して楕円を描画します
//----------パラメトリック方程式を使用して楕円を描画します---------- ------ -----
//関数のパラメータ x と y は楕円の中心であり、a、b は楕円の横半軸と縦半軸の長さです。
//この方法の欠点は、linWidth が広くなり、楕円が平らになることです。
//楕円の内側の長軸の端は鋭くなりますが、そうではありません。滑らかで効率は低い
function ParamEllipse(context, x, y, a, b)
{
//max は、主軸の値 a と大きい方で割った 1 に等しいb
//i はループごとに 1/max ずつ増加し、度の増加を示します
//これは機能します 各サイクルで描画されるパス (円弧) を 1 ピクセルに近づけます
var step = (a > ; b) ? 1 / a : 1 / b;
context.beginPath();
for (var) の左端から描画を開始します。 i = 0; i {
//パラメトリック方程式は x = a * cos(i), y = b * sin(i),
//パラメータは i で、次数 (ラジアン) を示します。
context.lineTo(x a * Math.cos(i), y b * Math.sin(i));
}
context.closePath( );
context.ストローク();
};
均一圧縮方法
この方法は、数学における均一圧縮の原理を使用します。理論的には、次のコードにより線幅が不一致になる問題が発生します。解決策については、5 を参照してください。 //---- -- -----楕円を描くための均一圧縮法---------
//この方法は、円弧法を使用して楕円を描くことです。円を描いてスケールと結合します
//水平軸または垂直軸方向にスケールします (均一圧縮)
//この方法で描画される楕円の端は、長軸の端に近づくほど太くなります、長軸の端の線の幅は通常の値です
//側面短軸に近づくほど、楕円は平らで薄くなり、スケールの結果である不連続性も生じます
//リング(惑星ハロー)の立体感を表現する場合など、この欠点が利点となる場合もあります
//パラメータaまたはbが0の場合、この方法は適用できません
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
// 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) / 比率 X, y / 比率 Y);
context.arc(x / 比率 X, y / 比率 Y, r, 0, 2 * Math.PI);
context.closePath(); );
context.restore();
};
3 次ベジェ曲線描画楕円は実際には近似ですこれは理論上の近似値でもあります。 ただし、効率が高いため、コンピュータのベクター グラフィックスで楕円を描画するのによく使用されますが、具体的な理論についてはよくわかりません。 近似の程度は、2 つの制御点の位置の選択によって決まります。この方法の制御点の位置は私自身の実験によって得られたものであり、精度は問題ありません。
コードをコピー
{
//重要なのは bezierCurveTo
の 2 つの制御点の設定です//0.5 と 0.6 は 2 つの重要な係数です (この関数の実験から得られます) )
var ox = 0.5 * a,
oy = 0.6 * b;
context.translate(x, y);
//楕円の垂直方向から、軸の下端が反時計回りに描画されます。
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, -a, 0); >context.bezierCurveTo(-a, oy, - ox, b, 0, b);
context.stop();
context.restore();
3 次ベジェ曲線メソッド 2 このメソッドは、StackOverFlow での返信から投稿に変更されました。精度が高く、楕円を描画するためによく使用されるメソッドでもあります。 >
//-------- 3 次ベジェ曲線を使用して楕円 2 をシミュレートします---------------------
//このメソッドは、lineWidth が広く、楕円がより平らな場合にも生成されます
//、長軸の端は鋭く、滑らかではありません
//この方法は前のベジェ法よりも正確ですが、効率がわずかに劣ります
関数 BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848,
ox = a * k, // 水平制御点オフセット
oy = b * k; // 垂直制御点オフセット Quantity
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); oy, x ox, y b, x, y b);
ctx.bezierCurveTo(x - ox, y b, x - a, y oy, x - a, y); >ctx.ストローク();
};
ラスターメソッド
このメソッドは、グラフィックスの基本的なアルゴリズムを使用してピクセルを操作します。楕円。 例えば、中点楕円描画アルゴリズムなど。
一例としては、庭友達の「どうどうごう」さんのブログ投稿「HTML5 キャンバス改善講座 (1) - ラスターグラフィックス (1) 中点円描画アルゴリズム」があります。この方法は比較的「独創的」で、優れた柔軟性、高効率、高精度を備えていますが、楕円を描画するための有益な関数を実装するのは比較的複雑です。たとえば、線幅が変化すると、アルゴリズムはより複雑になります。円を描画するアルゴリズムですが、楕円を描画するアルゴリズムも同様ですので、以下を参照してください。
デモ
ラスター手法に加えて楕円関数を描画するいくつかのデモを以下に示します。デモ コードは次のとおりです。 コードをコピーします。