Rumah  >  Artikel  >  hujung hadapan web  >  4 cara untuk melukis elips dalam petua tutorial HTML5 Canvas_html5

4 cara untuk melukis elips dalam petua tutorial HTML5 Canvas_html5

WBOY
WBOYasal
2016-05-16 15:47:041851semak imbas

Ikhtisar

Kanvas dalam HTML5 tidak secara langsung menyediakan kaedah untuk melukis elips Berikut ialah ringkasan beberapa kaedah lukisan. Setiap kaedah mempunyai kelebihan dan kekurangannya sendiri, yang harus dipilih mengikut situasi. Parameter setiap kaedah adalah sama:

1.konteks ialah objek persekitaran lukisan 2D Kanvas,
2.x ialah absis pusat elips,
3.y ialah ordinat pusat elips,
4.a ialah panjang separuh paksi melintang elips ,
5.b ialah panjang separuh paksi membujur elips.

Kaedah persamaan parametrik

Kaedah ini menggunakan persamaan parametrik elips untuk melukis elips

Salin kod
Kod adalah sebagai berikut:

//----------Gunakan persamaan parametrik untuk melukis elips----------------------
//Parameter Fungsi x dan y ialah pusat elips a dan b ialah separuh paksi mendatar dan menegak
//Panjang separuh paksi menegak tidak boleh 0 pada masa yang sama
//Kelemahan kaedah ini ialah apabila Lebar garisan lebih lebar, elips akan menjadi lebih kecil Apabila rata
//Hujung paksi panjang di dalam elips lebih tajam, tidak licin dan kurang cekap.
fungsi ParamEllipse(konteks, x, y, a, b)
{
//maks bersamaan dengan 1 Bahagi dengan nilai paksi utama a dan b yang lebih besar
//i meningkat sebanyak 1/maks setiap kitaran, menunjukkan peningkatan dalam darjah
//Ini boleh menjadikan laluan (arka) yang dilukis dalam setiap kitaran Hampir kepada 1 piksel
var step = (a > b) ? : 1 / b;
context.beginPath();
context.moveTo(x a, y); //Dari elips Mula melukis dari titik akhir kiri
untuk (var i = 0; i < 2 * Math.PI; i = step)
{
//Persamaan parametrik ialah x = a * cos(i), y = b * sin(i),
//Parameter ialah i , menunjukkan darjah (radian)
context.lineTo(x a * Math.cos(i), y b * Math.sin(i));
}
context.closePath();
context .stroke();
};

Kaedah mampatan seragam

Kaedah ini menggunakan prinsip mampatan seragam dalam matematik untuk memampatkan bulatan secara seragam menjadi elips Secara teorinya, elips piawai boleh diperolehi Kod berikut akan menyebabkan lebar garisan tidak konsisten lantai.

Salin kod
Kod tersebut adalah seperti berikut:

//------------Kaedah mampatan seragam untuk melukis elips-------
//The kaedah Kaedah lengkok digunakan untuk melukis bulatan, digabungkan dengan skala untuk
//Skala dalam arah paksi mendatar atau menegak (mampatan seragam)
//Tepi elips yang dilukis dengan kaedah ini lebih tebal kerana ia lebih dekat dengan hujung paksi panjang, dan paksi lebih panjang Lebar garisan titik akhir ialah nilai normal
//Semakin dekat tepi dengan paksi kecil, elips akan lebih rata dan nipis, dan sekata ketakselanjaran akan berlaku. Ini adalah hasil skala
//Kekurangan ini kadangkala menjadi kelebihan, seperti Apabila menyatakan kesan tiga dimensi cincin (halo planet)
//Untuk kes di mana parameter a atau b ialah 0, kaedah ini tidak berkenaan
fungsi EvenCompEllipse(konteks, x, y, a, b)
{
context.save();
//Pilih yang lebih besar daripada a dan b sebagai parameter jejari kaedah lengkok
var r = (a > b) ? r; //Nisbah penskalaan paksi menegak
context.scale(nisbahX, nisbahY); //Skala (mampatan seragam)
context.beginPath();
//Lukis lawan jam dari titik akhir kiri elips
context.moveTo((x a) / ratioX, y / ratioY);
context.arc(x / ratioX , y / ratioY, r, 0, 2 * Math.PI);
context.closePath ();
context.stroke();
context.restore();
};


Kaedah Lengkung Bezier Kubik 1

Melukis elips dengan lengkung Bezier padu ialah anggaran dalam lukisan sebenar, dan ia juga merupakan anggaran dalam teori. Tetapi kerana kecekapannya yang tinggi, ia sering digunakan untuk melukis elips dalam grafik vektor komputer, tetapi saya tidak begitu jelas tentang teori tertentu. Tahap penghampiran terletak pada pemilihan kedudukan dua titik kawalan. Kedudukan titik kawalan kaedah ini diperolehi oleh percubaan saya sendiri, dan ketepatannya adalah okey. Kodnya adalah seperti berikut:


//---------Gunakan lengkung Bezier padu untuk mensimulasikan elips 1-----------------------
//Kaedah ini juga akan menghasilkan fenomena apabila garis Lebar lebih lebar dan elips lebih rata,
//hujung paksi panjang lebih tajam dan tidak licin
fungsi BezierEllipse1(konteks, x, y, a , b)
{
//Kunci ialah penetapan dua titik kawalan dalam bezierCurveTo
//0.5 dan 0.6 ialah dua pekali kunci (diperolehi daripada eksperimen dalam fungsi ini)
var ox = 0.5 * a,
oy = 0.6 * b;

context.save();
context.translate(x, y);
context.beginPath();
//Lukis lawan jam bermula dari hujung bawah paksi menegak elips
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();

};

Kaedah Lengkung Bezier Kubik 2

Kaedah ini telah ditukar daripada balasan kepada siaran dalam StackOverFlow Ia mempunyai ketepatan yang lebih tinggi dan juga merupakan kaedah yang biasa digunakan untuk melukis elips. kod

Kodnya adalah seperti berikut:
//---------Gunakan lengkung Bezier padu untuk mensimulasikan elips 2----- -- ----------------//Kaedah ini juga akan menghasilkan fenomena iaitu apabila LineWidth lebih lebar dan elips lebih rata//, paksi panjang hujungnya lebih tajam dan tidak licin
//Kaedah ini lebih tepat daripada kaedah Bezier sebelumnya, tetapi kurang cekap
fungsi BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848 ,
lembu = a * k, // mengimbangi titik kawalan mendatar
oy = b * k // mengimbangi titik kawalan menegak

ctx.beginPath();
//Lukis empat lengkung Bezier kubik mengikut arah jam bermula dari titik akhir kiri elips
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();
};




Kaedah raster

Kaedah ini boleh menggunakan algoritma asas dalam grafik untuk melukis elips berdasarkan ciri-ciri Kanvas yang boleh mengendalikan piksel. Contohnya, algoritma lukisan elips titik tengah, dsb.

Salah satu contoh ialah catatan blog oleh rakan taman "Doudou Gou" "Kelas Penambahbaikan Kanvas HTML5 (1) - Grafik Raster (1) Algoritma Lukisan Bulatan Titik Tengah". Kaedah ini agak "asal", mempunyai fleksibiliti yang hebat, kecekapan tinggi, dan ketepatan yang tinggi, tetapi agak rumit untuk melaksanakan fungsi yang berharga untuk melukis elips. Sebagai contoh, apabila lebar garis berubah, algoritma menjadi lebih rumit. Walaupun ia adalah algoritma untuk melukis bulatan, algoritma untuk melukis elips adalah serupa dengannya. Anda boleh merujuknya di bawah.

Ringkasan

Pada asasnya semua kaedah tidak boleh mencapai ketepatan 100% kerana ia dihadkan oleh resolusi paparan.

Malah, kaedah terbaik adalah arc() scale(). Pustaka lukisan kanvas KineticJS menggunakan kaedah ini. Dalam perisian lukisan lain, tiada kaedah arc() scale() seperti kanvas HTML5 biasanya digunakan untuk mensimulasikan elips anggaran Tidak kira berapa banyak lengkung Bezier, ia hanyalah anggaran. Berkenaan menggunakan lengkung Bezier untuk mensimulasikan elips, anda boleh merujuk kepada maklumat ini:
Melukis lengkok elips menggunakan garis poli, lengkung Bezier kuadratik atau kubik
.

Memandangkan arc() scale() ialah kaedah yang telah dilaksanakan oleh penyemak imbas, ia mempunyai ketepatan teori yang paling tinggi, jadi ia adalah yang terbaik dari segi kecekapan, ketepatan dan kemudahan penggunaan.

Selepas melukis elips dengan skala arc()(), kedua-dua kaedah context.stroke() dan context.restore() dipanggil dalam susunan yang berbeza, dan hasilnya akan menjadi sangat menarik. Biasanya anda harus restore() dahulu dan kemudian stroke().

Demo

Berikut ialah beberapa demonstrasi melukis fungsi elips sebagai tambahan kepada kaedah raster Kod tunjuk cara adalah seperti berikut:

Salin kod
<.>
Kodnya adalah seperti berikut:




执行




注意,要成功运行代码,需要支持要5支持。

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn