HTML5のキャンバスは、楕円を描く方法を直接提供しません。以下は、いくつかの描画方法の要約です。さまざまな方法には独自の利点と短所があり、状況に応じて選択されています。各メソッドのパラメーターは同じです。
コンテキストは、Canvasの2D描画環境オブジェクトです。
Xは、楕円の中心の水平座標です。
yは、楕円の中心の垂直座標です。
Aは、楕円の水平半軸の長さです。
Bは、楕円の垂直半軸の長さです。
パラメーター方程式方法この方法は、楕円のパラメトリック方程式を使用して楕円を描画します
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//関数のパラメーターxとyは、楕円の中心です。 AとBは、それぞれ楕円の水平半軸です。
//垂直の半軸の長さは同時に0にすることはできません
//この方法の欠点は、linwidthがより広く、楕円がお世辞になったときです
//内側の楕円の主要軸の端は鋭く、滑らかではなく、効率が低い
関数paramellipse(コンテキスト、x、y、a、b)
{
//最大値は主軸の値aとbの大きい方です
//各サイクルで1/maxを増やし、程度の増加を示します
//これにより、各ループに1ピクセルに近いパス(アーク)が描画されます
var step =(a> b)? 1 / a:1 / b;
context.beginpath();
Context.moveto(x + a、y); //楕円の左のエンドポイントから描画します
for(var i = 0; i <2 * math.pi; i += step)
{
//パラメーター方程式はx = a * cos(i)、y = b * sin(i)です。
//パラメーターはiで、程度を示します(radian)
context.lineto(x + a * math.cos(i)、y + b * math.sin(i));
}
Context.ClosePath();
context.stroke();
};
均一な圧縮法この方法は、数学の均一な圧縮の原理を使用して、サークルを均一に楕円に圧縮し、理論的には標準的な楕円を取得できます。次のコードには、一貫性のない線幅に問題があります。解決策は、5階でSimonleungのコメントを見ることです。
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//メソッドは、ARCメソッドを使用して円を描画し、スケールを組み合わせることです
//水平または垂直軸方向のスケーリング(圧縮さえ)
//この方法で描かれた楕円の端は、端が主軸の端に近づくと厚くなり、主軸の端の線幅は正常です
//エッジがマイナー軸に近いほど、楕円が平らで薄くなり、中断さえも引き起こされます。これはスケールの結果です。
//この欠点は、リングの3次元効果を表現する場合など、時には利点があります(惑星ハロー)
//パラメーターaまたはbが0の場合、この方法は適用されません
関数evencompellipse(context、x、y、a、b)
{
context.save();
// ARCメソッドの半径パラメーターとして、AとBの大きいものを選択します
var r =(a> b)? A:B;
var比率= a / r; //水平軸スケーリング比
var ratioy = b / r; //寸法軸スケーリング比
context.scale(ratiox、ratioy); //スケーリング(圧縮さえ)
context.beginpath();
//楕円の左端から反時計回りに描画します
context.moveto((x + a) / ratiox、y / ratioy);
context.arc(x / ratiox、y / ratioy、r、0、2 * math.pi);
Context.ClosePath();
context.stroke();
context.restore();
};
立方体のベジエ曲線法1楕円の立方皮の曲線図は、実際に描画するときの近似であり、理論的には近似でもあります。ただし、その効率が高いため、コンピューターベクトルグラフィックスに楕円を描くためによく使用されますが、特定の理論についてはあまり明確ではありません。近似は、2つの制御ポイントの位置の選択にあります。この方法のコントロールポイント位置は自分で取得され、精度は問題ありません。
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//この方法は、ライン幅が広く、楕円が平らな場合にも生成されます。
//長軸の端はシャープで滑らかではありません
関数bezierellipse1(コンテキスト、x、y、a、b)
{
//キーは、Beziercurvetoの2つの制御ポイントの設定です
//0.5と0.6は2つの重要な係数です(この機能の実験のために得られます)
var ox = 0.5 * a、
oy = 0.6 * b;
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.stroke();
context.restore();
};
立方皮の曲線法2この方法は、高い精度でStackoverflowの投稿への返信から変更され、楕円を描くために一般的に使用される方法でもあります。
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//この方法は、ライン幅が広く、楕円がお世辞になったときにも生成されます
//、長軸の端はシャープで滑らかではありません
//この方法は以前のベッセル法よりも正確ですが、効率がわずかに低い方法があります
関数bezierellipse2(ctx、x、y、a、b)
{
var k = .5522848、
ox = a * k、//水平制御ポイントオフセット
oy = b * k; //垂直制御ポイントオフセット
ctx.beginpath();
//楕円の左端から時計回りに4つの立方体ベジエ曲線を描く
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.stroke();
};
グレーティング方法この方法は、ピクセルを動作させ、グラフィックスで基本的なアルゴリズムを使用できるキャンバスの特性に基づいて楕円を描画できます。たとえば、ミッドポイント描画楕円アルゴリズムなど。
1つの例は、Garden Friend、HTML5 Canvas Improvement Class(I)-Rasterグラフィックス(1)のミッドポイントとサークルアルゴリズムのDoudouによるブログ投稿です。この方法は比較的原始的で、柔軟性があり、効率的で正確ですが、楕円を描くための有用な機能を実現する方が複雑です。たとえば、行の幅が変化すると、アルゴリズムがより複雑になります。これは円を描くためのアルゴリズムですが、楕円を描くためのアルゴリズムはそれに似ているため、以下を参照できます。
デモ
以下は、ラスターメソッドに加えて、楕円機能を描画するいくつかのデモンストレーションです。デモコードは次のとおりです。
<div id = "canvaswrap" style = "background:#ffff; width:600px; height:600px; border:1px solid black;"> </div>
<script type = "text/javascript"> // <![cdata [
var Canvas、
コンテクスト;
var div = document.getElementById( "CanvasWrap");
div.innerhtml = "";
canvas = document.createelement( "canvas");
canvas.style.width = "600px"
canvas.style.height = "600px"
canvas.width = 600;
canvas.height = 600;
Context = canvas.getContext( "2d");
Div.AppendChild(Canvas);
関数execdraw()
{
//クロムでは、ライン幅の問題を1以下に解決する
Context.LineWidth = 1.1;
Context.Strokestyle = "Black"
paramellipse(コンテキスト、130、80、50、50); //丸
paramellipse(Context、130、80、100、20); // Ellipes
evencompellipse(コンテキスト、130、200、50、50); //丸
Evencompellipse(Context、130、200、100、20); // Ellipe
Bezierellipse1(コンテキスト、470、80、50、50); //丸
Bezierellipse1(コンテキスト、470、80、100、20); //エリペ
Bezierellipse2(コンテキスト、470、200、50、50); //丸
Bezierellipse2(コンテキスト、470、200、100、20); //エリペ
//類似性の検出(オーバーラップの程度)
paramellipse(コンテキスト、300、450、250、50);
Context.Strokestyle = "Yellow";
Bezierellipse1(コンテキスト、300、450、250、50);
Context.Strokestyle = "Blue";
Bezierellipse2(コンテキスト、300、450、250、50);
};
関数ClearCavnas()
{
Context.ClearRect(0、0、600、600);
};
//]]> </script>
<p>
<ボタンonclick = "execdraw();" type = "button"> execute </button>
<button onclick = "clearcanvas();" type = "button"> clean </button>
</p>
コードを正常に実行するには、HTML5対応キャンバスをサポートするブラウザが必要であることに注意してください。
ブログを書いたのは初めてでしたが、一日中それをするのは簡単ではありませんでした!ブログパークの暗い肌のテンプレートには、挿入されたコードがよく表示されません。コード形式を取得するために大きな痛みを感じました!