キャンバスでは、ARCメソッドを使用して簡単に円を描くことができます。もともと、円は幅と高さが等しい楕円と見なすこともできますが、キャンバスに楕円を描く方法はありません。他の方法を使用してシミュレートする必要があります。
まず、楕円を描くのに必要なパラメーターを明確にする必要があります。基本的な幾何学的知識は、楕円には中心座標、幅、高さ、または回転角が必要であることがわかりますが、これは当面回避できますが、回転は比較的簡単です。
1. Linetoを使用して楕円を描きますあなたはそれを正しく読みます、Linetoは、直線を描くために純粋に使用される方法であり、実際に楕円を描くために使用できます! ?しかし、彼は存在しますが、執筆スタイルは本当に信じられないほどです:関数drawellipse(canvas、o、oa、ob){
//楕円を描く、例:var b = new Array(150,150); Drawellipse(HB、B、50,30);
(キャンバス){
var x = o [0]+oa;
var y = o [1];
Moveto(x、y);
for(var i = 0; i <= 360; i ++){
var ii = i*math.pi/180;
var x = o [0]+oa*math.cos(ii);
var y = o [1] -ob*math.sin(ii);
Lineto(x、y);
}
}
}
この方法の原則は、円に360度があるため、Linetoを使用して360回ループし、各程度のラインセグメントを描き、最後にそれらを楕円に接続することです。その中で、三角関数正弦系コサインを計算に使用する必要があります。
このメソッドの2番目のパラメーターは、アレイ、つまり楕円の中心座標であることに注意してください。
アイデアは非常に奇妙で、描かれた楕円は比較的滑らかです。ただし、使用する価値はありません。この方法では、描かれた楕円ごとに360サイクルが必要です。楕円が描かれている場合にのみ、ブラウザのパフォーマンスのわずかなテストです。
私たちは彼のアイデアを理解する必要があります
2。アークを使用して円を描き、楕円にスケーリングしますこの方法の元のテキストはこちらで、コア関数は次のとおりです。var canvas = document.getElementById( 'mycanvas');
var context = canvas.getContext( '2d');
var centerx = 0;
var Centery = 0;
var radius = 50;
//状態を保存します
context.save();
//コンテキストを翻訳します
context.translate(canvas.width / 2、canvas.height / 2);
//水平方向にコンテキストをスケーリングします
Context.scale(2、1);
//楕円形に伸びる円を描く
context.beginpath();
Context.Arc(CenterX、Centery、Radius、0、2 * Math.Pi、False);
//元の状態に復元します
context.restore()
この方法では、前述したことのないキャンバス関数、つまりスケールを使用して、キャンバスのスケーリングを実現できます。スケーリングには、水平および垂直の2つの方向があります。コードはキャンバスの水平方向を拡大しますが、垂直方向は変更されません。そのため、アークによって描かれた円は楕円に変わります。
この方法は一見すると非常に素晴らしいもので、コードはほとんどなく、原則はシンプルで理解しやすいです。しかし、それを分析した後、あなたは彼の明らかな欠点を見つけるでしょう。つまり、それは - 不正確です!たとえば、幅171、高さ56の楕円が必要です。 ARCの半径を28に設定すると、その後の171/28/2の数が低下します。
ただし、常にアークの半径を100に設定する妥協方法があり、その後、十分でない場合は拡大され、それを超えた場合は減少します。ただし、まだ不正確です。
3. Bezier Curvetoを使用してください上記のスケーリング方法が不正確だと感じたので、楕円を描く正確な方法を本当に見つけたいと思っています。関数drawellipse(ctx、x、y、w、h){
var Kappa = 0.5522848;
ox =(w / 2) * kappa、//コントロールポイントオフセット水平
oy =(h / 2) * kappa、//コントロールポイントオフセット垂直
xe = x + w、// x-end
ye = y + h、// y-end
xm = x + w / 2、// x-middle
ym = y + h / 2; // y-middle
ctx.beginpath();
ctx.moveto(x、ym);
ctx.beziercurveto(x、ym -oy、xm -ox、y、xm、y);
ctx.beziercurveto(xm + ox、y、xe、ym -oy、xe、ym);
ctx.beziercurveto(xe、ym + oy、xm + ox、ye、xm、ye);
ctx.beziercurveto(xm -ox、ye、x、ym + oy、x、ym);
ctx.closepath();
ctx.stroke();
}
この方法は完璧と見なすことができます。彼は楕円を4つのベジエ曲線に分割し、それらを楕円に接続しました。最終的な幅と高さも比較的正確で、オーバーヘッドは少なくなります。
しかし、この方法にはまだ欠点があります。誰もがカッパパラメーターを見て、非常に奇妙な値があります。幾何学の専門家がこの価値を取得したい理由を教えてくれる前に、多くの人がこの価値を取得しなければならない理由を理解していないと思います - 私はまだそれを知りません。そして、私は彼を変えて、その結果が何であるかを見るという強い衝動を持っていました。
もちろん、強迫性障害患者に似た私の衝動は、この方法の不利な点とは言えません。彼の本当の欠点は、なぜ4つのbezier曲線を使用する必要があるのですか?私は個人的には、楕円は明らかに4つではなく2つの魅力的な曲線で構成されていると思います。このアイデアは、最終的に楕円を描く最も完璧な方法を見つけることになりました。
4. 2つのBESEL曲線を使用して、楕円を描きます
以前の方法を合理化できるかどうかを理解するために、質問をするためにStackoverFlowアカウントを特別に登録しました。質問には写真があるため、ポイントを送信することはできません。私はかろうじて英語の習熟度を使って外国人の質問に答えてポイントを獲得しなければなりませんでした。しかし、結局のところ、幸運が来て、質問に答えることで私のポイントの問題が解決しました。
Besel CurveとEllipseの関係の問題を提起しました。
正直に言うと、私は以下の外国人の回答のほとんどを理解していませんでしたが、幸いなことに彼はコードサンプルページを提供しました。彼の答えによると、私が楕円を描くために見つけた方法は次のとおりです。
// oval
canvasrenderingContext2d.prototype.oval = function(x、y、width、height){
var k =(width/0.75)/2、
w = width/2、
h = height/2;
this.beginPath();
this.moveto(x、yh);
this.beziercurveto(x+k、yh、x+k、y+h、x、y+h);
this.beziercurveto(xk、y+h、xk、yh、x、yh);
this.closepath();
これを返します。
}
この方法は正確であり、コードがほとんどなく、奇妙で理解するのが難しいことはありません。これを覚えておいてください。楕円の幅の幅の座標比は、楕円を描くBESEL曲線の制御点と次のとおりです。
ベッセル制御点x =(ellipse幅/0.75)/2は、コードにすでに反映されています。
上記の4つの方法をテストして、楕円を描画できます。
簡単な方法を見つけた場合は、共有して話し合ってください。