Pendekatan lukisan-piksel (seperti yang disarankan oleh @Loadmaster) lebih unggul daripada solusi matematika dalam berbagai cara:
- Implementasinya jauh lebih sederhana. Masalah di atas dapat diselesaikan dalam waktu kurang dari 100 baris kode, seperti yang ditunjukkan oleh solusi JSFiddle ini (sebagian besar karena secara konseptual jauh lebih sederhana, dan tidak memiliki kasus tepi atau pengecualian untuk ditangani).
- Itu mudah beradaptasi dengan masalah yang lebih umum. Ia bekerja dengan bentuk apa pun, apa pun morfologinya, selama dapat dirender dengan pustaka gambar 2D (yaitu, "semuanya!") - lingkaran, elips, splines, poligon, apa saja. Heck, bahkan gambar bitmap.
- Kompleksitas solusi lukisan-piksel adalah ~ O [n], dibandingkan dengan ~ O [n * n] untuk solusi matematika. Ini berarti ini akan bekerja lebih baik dengan bertambahnya jumlah bentuk.
- Dan berbicara tentang kinerja, Anda akan sering mendapatkan akselerasi perangkat keras secara gratis, karena sebagian besar perpustakaan 2D modern (seperti kanvas HTML5, saya percaya) akan memindahkan pekerjaan rendering ke akselerator grafis.
Satu-satunya kelemahan lukisan piksel adalah akurasi solusi yang terbatas. Tapi itu bisa disesuaikan dengan hanya menampilkan kanvas yang lebih besar atau lebih kecil sesuai tuntutan situasi. Perhatikan juga, bahwa anti-aliasing dalam kode rendering 2D (sering diaktifkan secara default) akan menghasilkan akurasi yang lebih baik dari tingkat piksel. Jadi, misalnya, merender gambar 100x100 ke dalam kanvas dengan dimensi yang sama seharusnya, menurut saya, menghasilkan akurasi pada urutan 1 / (100 x 100 x 255) = 0,000039% ... yang mungkin "cukup baik" untuk semua kecuali masalah yang paling menuntut.
<p>Area computation of arbitrary figures as done thru pixel-painting, in which a complex shape is drawn into an HTML5 canvas and the area determined by comparing the number of white pixels found in the resulting bitmap. See javascript source for details.</p>
<canvas id="canvas" width="80" height="100"></canvas>
<p>Area = <span id="result"></span></p>
// Get HTML canvas element (and context) to draw into
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Lil' circle drawing utility
function circle(x,y,r) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2);
ctx.fill();
}
// Clear canvas (to black)
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Fill shape (in white)
ctx.fillStyle = 'white';
circle(40, 50, 40);
circle(40, 10, 10);
circle(25, 15, 12);
circle(35, 90, 10);
// Get bitmap data
var id = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = id.data; // Flat array of RGBA bytes
// Determine area by counting the white pixels
for (var i = 0, area = 0; i < pixels.length; i += 4) {
area += pixels[i]; // Red channel (same as green and blue channels)
}
// Normalize by the max white value of 255
area /= 255;
// Output result
document.getElementById('result').innerHTML = area.toFixed(2);