• Tidak ada hasil yang ditemukan

Rasterisasi

Dalam dokumen JILID 1 (Halaman 143-154)

BAB 8 SALURAN GRAFIS

8.1 Rasterisasi

Rasterisasi adalah operasi sentral dalam grafis urutan objek, dan rasterizer adalah pusat untuk setiap saluran grafis. Untuk setiap primitif yang datang, rasterizer memiliki dua tugas: menghitung piksel yang dicakup oleh primitif dan menginterpolasi nilai, yang disebut atribut, di seluruh primitif—tujuan atribut ini akan dijelaskan dengan contoh selanjutnya.

Output dari rasterizer adalah satu set fragmen, satu untuk setiap piksel yang dicakup oleh primitif. Setiap fragmen "hidup" pada piksel tertentu dan membawa kumpulan nilai atributnya sendiri.

Dalam bab ini, kami akan menyajikan rasterisasi dengan tujuan menggunakannya untuk membuat scene tiga dimensi. Metode esterisasi yang sama juga digunakan untuk menggambar garis dan bentuk dalam 2D—walaupun semakin umum menggunakan sistem grafis 3D "di bawah penutup" untuk melakukan semua gambar 2D.

Menggambar garis

Sebagian besar paket grafis berisi perintah menggambar garis yang mengambil dua titik akhir dalam koordinat layar (lihat Gambar 3.10) dan menarik garis di antara keduanya.

Misalnya, panggilan untuk titik akhir(1,1)dan (3,2) akan mengaktifkan piksel (1,1) dan (3,2) dan

mengisi satu piksel di antara keduanya. Untuk titik akhir koordinat layar umum (x0,y0) dan(x1,y1), rutin harus menggambar beberapa kumpulan piksel yang "masuk akal" yang mendekati garis di antara mereka. Menggambar garis tersebut didasarkan pada persamaan garis, dan kami memiliki dua jenis persamaan untuk dipilih: implisit dan parametrik. Bagian ini menjelaskan pendekatan menggunakan garis implisit. Meskipun kami sering menggunakan titik akhir bernilai integer sebagai contoh, penting untuk mendukung titik akhir arbitrer dengan benar

Menggambar Garis Menggunakan Persamaan Garis Implisit Cara yang paling umum untuk menggambar garis menggunakan persamaan implisit adalah algoritma titik tengah (Pitteway (1967);van Aken dan Novak(1985)). Algoritma titik tengah akhirnya menggambar garis yang sama dengan algoritma Bresenham (Bresenham, 1965) tetapi agak lebih mudah.

Hal pertama yang harus dilakukan adalah menemukan persamaan implisit:

Persamaan 8.1

f(x, y) ≡ (y0 − y1)x + (x1 − x0)y + x0y1 − x1y0 = 0.

Kita asumsikan bahwa x0 ≥ x1. Jika itu tidak benar, kami menukar poin sehingga itu benar. Kemiringan garis m diberikan oleh

𝒎 =𝒚𝟏− 𝒚𝟎 𝒙𝟏− 𝒙𝟎

Diskusi berikut mengasumsikan m ∈ (0, 1]. Diskusi analog dapat diturunkan untuk m ∈ (−∞, −1], m ∈ (−1,0], dan m ∈ (1, ∞).Keempat kasus mencakup semua kemungkinan.

Untuk kasus m ∈ (0, 1], ada lebih banyak "lari" daripada "naik", yaitu, garis bergerak lebih cepat di x daripada di y. Jika kita memiliki API di mana sumbunya mengarah ke bawah, kita mungkin memiliki kekhawatiran tentang apakah ini membuat proses lebih sulit, tetapi, pada kenyataannya, kita dapat mengabaikan detail itu. Kita dapat mengabaikan gagasan geometris "atas" dan "bawah", karena aljabarnya persis sama untuk dua kasus. Pembaca yang cermat dapat memastikan bahwa ada algoritma yang bekerja untuk sumbu y ke bawah.

Asumsi kunci dari algoritma titik tengah adalah bahwa kita menggambar yang paling tipis garis mungkin yang tidak memiliki celah.Hubungan diagonal antara dua piksel tidak dianggap sebagai celah.

Gambar 8.2 Tiga garis "masuk akal" yang menghasilkan tujuh piksel secara horizontal dan tiga piksel secara vertikal.

Gambar 8.3 Atas: garis berada di atas titik tengah sehingga piksel teratas digambar. Bawah:

garis berada di bawah titik tengah sehingga piksel bawah digambar.

Saat garis bergerak dari titik akhir kiri ke kanan, hanya ada dua kemungkinan:

menggambar piksel dengan ketinggian yang sama dengan piksel yang ditarik ke kiri, atau menggambar piksel satu lebih tinggi. Akan selalu ada tepat satu piksel di setiap kolom piksel di antara titik akhir. Nol akan menyiratkan celah, dan dua akan menjadi alkali gigi. Mungkin ada dua piksel dalam baris yang sama untuk kasus yang sedang kita pertimbangkan; garisnya lebih horizontal daripada vertikal sehingga kadang-kadang akan lurus, dan kadang-kadang naik. Konsep ini ditunjukkan pada Gambar 8.2, di mana tiga garis "masuk akal" ditampilkan, masing-masing lebih maju ke arah horizontal daripada ke arah vertikal.

Algoritme titik tengah untuk m (0,1] pertama-tama menetapkan piksel paling kiri dan nomor kolom (nilai-x) dari piksel paling kanan dan kemudian mengulang secara horizontal membentuk baris (nilai-y) dari setiap piksel. algoritma adalah:

y = y0

for x = x0 ke x1 do draw(x, y)

if (beberapa kondisi) then y = y + 1

Perhatikan bahwa x dan y adalah bilangan bulat. Dengan kata-kata ini mengatakan,

"terus menggambar piksel dari kiri ke kanan dan kadang-kadang bergerak ke atas dalam arah y saat melakukannya." Kuncinya adalah untuk menetapkan cara yang efisien untuk membuat keputusan dalam pernyataan if.

Cara efektif untuk menentukan pilihan adalah dengan melihat titik tengah garis antara dua pusat piksel potensial. Lebih khusus lagi, piksel yang baru saja digambar adalah piksel (x, y) yang pusatnya dalam koordinat layar sebenarnya adalah di (x,y). Kandidat piksel yang akan digambar ke kanan adalah piksel (x + 1, y) dan (x + 1, y + 1). Titik tengah antara pusat dari dua kandidat piksel adalah (x + 1, y + 0.5). Jika garis melewati di bawah titik tengah ini kita menggambar piksel bawah, dan sebaliknya kita menggambar piksel atas (Gambar 8.3).

Untuk memutuskan apakah garis melewati di atas atau di bawah (x + 1, y + 0.5), kita mengevaluasi f(x, y + 0.5) pada Persamaan (8.1). Ingat kembali dari bab 2 bahwa f(x, y)=0 untuk titik (x, y) pada garis, f(x, y) > 0 untuk titik pada salah satu sisi garis, dan f(x, y) < 0 untuk titik-titik di sisi lain garis. Karena f(x, y)=0 dan f(x, y) = 0 keduanya merupakan persamaan yang sangat baik untuk garis, persamaan tersebut tidak langsung jelas apakah f(x, y) menjadi positif menunjukkan bahwa (x, y) berada di atas garis, atau apakah itu di bawah. Namun, kita bisa mengetahuinya; istilah kunci dalam Persamaan (8.1) adalah suku y (x1 x0)y. Perhatikan bahwa

(x1 x0) pasti positif karena x1 > x0. Ini berarti bahwa dengan bertambahnya y, suku (x1 − x0)y semakin besar (yaitu, lebih banyak positif atau kurang negatif). Jadi, kasus f(x, +∞) pasti positif, dan pasti di atas garis, menyiratkan poin di atas garis semuanya positif. Cara lain untuk melihatnya adalah bahwa komponen y dari vektor gradien adalah positif. Jadi di atas garis, di mana y dapat meningkat secara sembarang, f(x, y) harus positif. Ini berarti kita dapat membuat kode kita lebih spesifik dengan mengisi pernyataan if:

if f(x + 1, y + 0.5) < 0 then y = y + 1

Kode di atas akan bekerja dengan baik untuk garis kemiringan yang sesuai (yaitu, antara nol dan satu). Pembaca dapat mengerjakan tiga kasus lain yang hanya berbeda dalam detail-detail kecil.

Gambar 8.4 Saat menggunakan titik keputusan yang ditunjukkan di antara dua piksel oranye, kami hanya menggambar piksel biru, jadi kami mengevaluasi f di salah satu dari dua titik kiri

yang ditampilkan

Jika efisiensi yang lebih besar diinginkan, menggunakan metode tambahan dapat membantu. Metode inkremental mencoba membuat loop lebih efisien dengan menggunakan kembali komputasi dari langkah sebelumnya. Dalam algoritma titik tengah seperti yang disajikan, perhitungan utama adalah evaluasi f(x + 1, y + 0.5). Perhatikan bahwa di dalam loop, setelah iterasi pertama, kita telah mengevaluasi f(x − 1, y + 0.5) atau f(x − 1, y − 0.5) (Gambar 8.4). Perhatikan juga hubungan ini:

f(x + 1, y) = f(x, y)+(y0 -− y1)

f(x + 1, y + 1) = f(x, y)+(y0 - − y1)+(x1− x0).

Ini memungkinkan kita untuk menulis versi inkremental dari kode:

y = y0

d = f(x0 + 1, y0 + 0.5) for x = x0 to x1 do

draw(x, y) if d < 0 then y = y + 1

d = d + (x1 − x0)+(y0 − y1) else

d = d + (y0 − y1)

Kode ini harus berjalan lebih cepat karena memiliki sedikit biaya penyiapan tambahan dibandingkan dengan versi non-incremental (yang tidak selalu benar untuk algoritma inkremental), tetapi mungkin mengakumulasi lebih banyak kesalahan numerik karena evaluasi f(x, y + 0.5) dapat terdiri dari banyak tambahan untuk antrean panjang. Namun, mengingat bahwa garis jarang lebih panjang dari beberapa ribu piksel, kesalahan seperti itu tidak mungkin menjadi kritis. Biaya setup yang sedikit lebih lama, tetapi eksekusi loop yang lebih cepat, dapat dicapai dengan menyimpan (x1 − x0) + (y0 − y1) dan (y0 − y1) sebagai variabel. Kami

mungkin berharap goodcompiler akan melakukannya untuk kami, tetapi jika kodenya penting, sebaiknya periksa hasil kompilasi untuk memastikannya.

Rasterisasi Segitiga

Kita sering ingin menggambar segitiga 2D dengan pon 2D p0 = (x0, y0), p1 = (x1, y1), dan p2 = (x2, y2) dalam koordinat layar. Ini mirip dengan masalah menggambar garis, tetapi memiliki beberapa kehalusan tersendiri. Seperti menggambar garis, kita mungkin ingin menginterpolasi warna atau properti lain dari nilai pada simpul. Ini mudah jika kita memiliki koordinat barycentric (Bagian 2.7). Misalnya, jika titik-titik memiliki warna c0, c1, dan c2, warna pada suatu titik dalam segitiga dengan koordinat barycentric (α, β, γ) adalah

c = αc0 + βc1 + γc2.

Jenis interpolasi warna ini dikenal dalam grafis sebagai interpolasi Gouraud setelah penemunya (Gouraud, 1971).

Kehalusan lain dari rasterisasi segitiga adalah bahwa kita biasanya rasterisasi segitiga yang berbagi simpul dan tepi. Ini berarti kita ingin melakukan rasterisasi pada segitiga yang berdekatan sehingga tidak ada lubang. Kita bisa melakukan ini dengan menggunakan algoritma titik tengah untuk menggambar garis luar setiap segitiga dan kemudian mengisi piksel interior. Ini berarti segitiga yang berdekatan menggambar piksel yang sama di sepanjang setiap tepi. Jika segitiga yang berdekatan memiliki warna yang berbeda, gambar akan tergantung pada urutan di mana dua segitiga digambar. Cara paling umum untuk meraster segitiga yang menghindari masalah urutan dan menghilangkan lubang adalah dengan menggunakan konvensi bahwa piksel digambar jika dan hanya jika pusatnya berada di dalam segitiga, yaitu, koordinat barysentris daripusat piksel berada di dalam interval (0,1). Ini menimbulkan masalah tentang apa yang harus dilakukan jika pusatnya tepat di tepi segitiga.

Ada beberapa cara untuk menangani ini seperti yang akan dibahas nanti di bagian ini.

Pengamatan utama adalah bahwa koordinat barycentric memungkinkan kita untuk memutuskan apakah akan menggambar piksel dan warna apa yang seharusnya menjadi piksel jika kita menginterpolasi warna dari simpul. Jadi masalah rasterisasi segitiga kita bermuara pada pencarian koordinat barycentric dari pusat piksel secara efisien (Pineda, 1988).

Algoritma rasterisasi brute force adalah:

for all x do

for all y do

compute (α, β, γ) for (x, y)

if (α [∈ 0, 1] dan β ∈ [0, 1] dan γ ∈ [0, 1]) then c = αc0 + βc1 + γc2

drawpixel (x, y) dengan warna c

Algoritma lainnya membatasi loop luar menjadi kumpulan piksel kandidat yang lebih kecil dan membuat komputasi barycentric menjadi efisien.

Kita dapat menambahkan efisiensi sederhana dengan menemukan persegi panjang pembatas dari tiga simpul dan hanya mengulang persegi panjang ini untuk menggambar kandidat piksel. Kita dapat menghitung koordinat barycentric menggunakan Persamaan (2.32).

Ini menghasilkan algoritma:

xmin = flfloor(xi) xmax = ceiling(xi) ymin = flfloor(yi) ymax = ceiling(yi) for y = ymin to ymax do

for x = xmin to xmax do α = f12(x, y)/f12(x0, y0) β = f20(x, y)/f20(x1, y1)

γ = f01(x, y)/f01(x2, y2)

if (α > 0 dan β > 0 dan γ > 0) then c = αc0 + βc1 + γc2

drawpixel (x, y) dengan warna c

Di sini fij adalah garis yang diberikan oleh Persamaan (8.1) dengan simpul yang sesuai:

f01(x, y)=(y0 − y1)x + (x1 − x0)y + x0y1− x1y0, f12(x, y)=(y1 − y2)x + (x2 − x1)y + x1y2 − x2y1, f20(x, y)=(y2 − y0)x + (x0 − x2)y + x2y0− x0y2.

Perhatikan bahwa kita telah menukar uji α ∈ (0, 1) dengan α > 0 dst., karena jika semua α, β, γ positif, maka kita tahu semuanya kurang dari satu karena α+β+γ = 1. Kita juga dapat menghitung hanya dua dari tiga variabel barycentric dan mendapatkan yang ketiga dari hubungan itu, tetapi tidak jelas bahwa ini menghemat perhitungan setelah algoritma dibuat inkremental, yang mungkin seperti pada algoritma menggambar garis; masing-masing perhitungan α, β, dan γ melakukan evaluasi bentuk f(x, y) = Ax + By + C. Dalam loop dalam, hanya x yang berubah, dan itu berubah satu. Perhatikan bahwa f(x + 1, y) = f(x, y) + A. Ini adalah dasar dari algoritma inkremental. Pada loop luar, evaluasi berubah untuk f(x, y) menjadi f(x, y + 1) , sehingga efisiensi yang sama dapat dicapai. Karena α, β dan γ berubah dengan kenaikan konstan dalam loop, begitu juga warna c. Jadi ini bisa dibuat inkremental juga. Misalnya, nilai merah untuk piksel (x + 1, y) berbeda dari nilai merah untuk piksel (x, y) dengan jumlah konstan yang dapat dihitung sebelumnya. Contoh segitiga dengan interpolasi warna ditunjukkan pada Gambar 8.5.

Gambar 8.5 Segitiga berwarna dengan interpolasi barycentric. Perhatikan bahwa perubahan komponen warna adalah linier di setiap baris dan kolom serta di sepanjang setiap tepi.

Bahkan konstan sepanjang setiap garis, seperti diagonal, juga.

Menangani Piksel pada Tepi Segitiga Kita masih belum membahas apa yang harus dilakukan untuk piksel yang pusatnya tepat berada di tepi segitiga. Jika sebuah piksel tepat berada di tepi segitiga, maka piksel tersebut juga berada di tepi segitiga yang berdekatan jika ada. Tidak ada cara yang jelas untuk memberikan piksel ke satu segitiga atau yang lain.

Keputusan terburuk adalah tidak menggambar piksel karena lubang akan terjadi di antara dua segitiga. Lebih baik, tapi tetap tidak bagus, adalah membuat kedua segitiga menggambar piksel. Jika segitiga transparan, ini akan menghasilkan pewarnaan ganda. Kami benar-benar ingin memberikan piksel ke salah satu segitiga, dan kami ingin proses ini sederhana; segitiga mana yang dipilih tidak masalah selama pilihan itu didefinisikan dengan baik.

Gambar 8.6 Titik di luar layar akan berada di satu sisi tepi segitiga atau sisi lainnya. Tepat satu dari simpul tak-berbagi a dan b akan berada pada sisi yang sama.

Salah satu pendekatan adalah untuk mencatat bahwa setiap titik di luar layar pasti berada tepat di satu sisi tepi bersama dan itulah tepi yang akan kita gambar. Untuk dua segitiga yang tidak tumpang tindih, simpul-simpul yang tidak berada di tepi berada pada sisi yang berlawanan dari tepi satu sama lain. Tepat satu dari simpul ini akan berada di sisi tepi yang sama dengan titik di luar layar (Gambar 8.6). Ini adalah dasar dari tes. Pengujian jika angka p dan q memiliki tanda yang sama dapat diimplementasikan sebagai pengujian pq > 0, yang sangat efisien di sebagian besar lingkungan.

Perhatikan bahwa pengujian ini tidak sempurna karena garis yang melalui tepi mungkin juga melewati titik di luar layar, tetapi setidaknya kami telah sangat mengurangi jumlah kasus yang bermasalah. Titik di luar layar mana yang digunakan adalah sembarang, dan (x, y) = (−1, −1) merupakan pilihan yang baik. Kita perlu menambahkan tanda centang untuk kasus titik yang tepat di tepi. Kami ingin pemeriksaan ini tidak dilakukan untuk kasus-kasus umum, yang merupakan pengujian sepenuhnya di dalam atau di luar. Ini menyarankan:

xmin = flfloor(xi) xmax = ceiling(xi) ymin = flfloor(yi) ymax = ceiling(yi) fα = f12(x0, y0) fβ = f20(x1, y1) fγ = f01(x2, y2)

for y = ymin to ymax do

for x = xmin to xmax do α = f12(x, y)/fα β = f20(x, y)/fβ γ = f01(x, y)/fγ

if (α ≥ 0 and β ≥ 0 and γ ≥ 0) then

if (α > 0 or fαf12(−1, −1) > 0) and (β > 0 or fβf20(−1, −1) > 0) and (γ > 0 or fγf01(−1, −1) > 0) then c = αc0 + βc1 + γc2

drawpixel (x, y) dengan warna c

Kita mungkin berharap bahwa kode di atas akan bekerja untuk menghilangkan lubang dan penarikan ganda hanya jika kita menggunakan persamaan garis yang persis sama untuk kedua segitiga. Faktanya, persamaan garis adalah sama hanya jika dua simpul bersama memiliki orde yang sama dalam panggilan undian untuk setiap segitiga. Jika tidak, persamaan mungkin terbalik. Ini bisa menjadi masalah tergantung pada apakah kompiler mengubah

urutan operasi. Jadi jika implementasi yang kuat diperlukan, detail kompiler dan unit aritmatika mungkin perlu diperiksa. Empat baris pertama dalam pseudocode di atas harus dikodekan dengan hati-hati untuk menangani kasus di mana tepi tepat mengenai pusat piksel.

Selain dapat menerima implementasi inkremental, ada beberapa titik keluar awal yang potensial. Misalnya, jika negatif, tidak perlu menghitung β atau γ. Meskipun ini mungkin menghasilkan peningkatan kecepatan, pembuatan profil selalu merupakan ide yang baik;

cabang tambahan dapat mengurangi saluran pipa atau konkurensi dan mungkin memperlambat kode. Jadi selalu, ujilah optimalisasi yang tampak menarik jika kode adalah bagian yang kritis.

Detail lain dari kode di atas adalah bahwa pembagian dapat berupa pembagian dengan nol untuk segitiga yang mengalami degenerasi, yaitu jika fγ = 0. Entah kondisi kesalahan titik mengambang harus diperhitungkan dengan benar, atau tes lain akan diperlukan

Guntingan

Cukup mengubah primitif menjadi ruang layar dan rasterisasi mereka tidak cukup bekerja dengan sendirinya. Ini karena primitif yang berada di luar volume tampilan—

khususnya, primitif yang ada di belakang mata—dapat menjadi raster, yang mengarah ke hasil yang salah. Misalnya, perhatikan segitiga yang ditunjukkan pada Gambar 8.7.

Gambar8.7 Kedalaman z ditransformasikan ke kedalaman z’ dengan transformasi perspektif.

Perhatikan bahwa ketika z bergerak dari positif ke negatif, z’ beralih dari negatif ke positif.

Dengan demikian simpul di belakang mata dipindahkan di depan mata melampaui z = n + f.

Ini akan menyebabkan hasil yang salah, itulah sebabnya segitiga terlebih dahulu dipotong untuk memastikan semua simpul berada di depan mata.

Dua simpul berada dalam volume tampilan, tetapi yang ketiga berada di belakang mata.

Transformasi proyeksi memetakan teks vertikal ini pada lokasi yang tidak masuk akal di belakang bidang jauh, dan jika ini dibiarkan terjadi, segitiga akan diraster dengan tidak benar.

Untuk itu, rasterisasi harus didahului dengan operasi pemotongan yang menghilangkan bagian-bagian primitif yang dapat memanjang ke belakang mata.

Kliping adalah operasi umum dalam grafis, diperlukan setiap kali satu entitas geometris

"memotong" yang lain. Misalnya, jika Anda menjepit segitiga pada bidang x =0 , bidang tersebut memotong segitiga menjadi dua bagian jika tanda-tanda koordinat x dari simpul-simpulnya tidak sama semua. Dalam sebagian besar aplikasi kliping, bagian segitiga di sisi yang

"salah" dari bidang dibuang. Operasi ini untuk satu bidang ditunjukkan pada Gambar 8.8.

Gambar 8.8 Sebuah poligon terpotong pada bidang kliping. Bagian "di dalam" pesawat dipertahankan.

Dalam kliping untuk mempersiapkan rasterisasi, sisi yang "salah" adalah sisi di luar volume tampilan. Selalu aman untuk memotong semua geometri di luar volume tampilan—

yaitu, memotong keenam sisi volume—tetapi banyak sistem berhasil lolos hanya dengan memotong pada bidang dekat.

Bagian ini membahas implementasi dasar modul kliping. Mereka yang tertarik untuk menerapkan clipper kecepatan industri harus melihat buku oleh Blinn yang disebutkan dalam

catatan di akhir bab ini. Dua pendekatan yang paling umum untuk mengimplementasikan kliping adalah

1. di koordinat dunia menggunakan enam bidang yang mengikat piramida penglihatan terpotong,

2. di ruang transformasi 4D sebelum pembagian homogen

Kemungkinan dapat diterapkan secara efektif (J. Blinn, 1996) dengan menggunakan pendekatan berikut untuk setiap segitiga:

for setiap six plane do

if (segitiga seluruhnya di luar bidang) then break (segitiga tidak terlihat)

else if bidang bentang segitiga then clip segitiga

if (segi empat kiri) then break ke kedua segitiga Kliping Sebelum Transform (Opsi 1)

Opsi 1 memiliki implementasi langsung. Satu-satunya pertanyaan adalah, "Apa persamaan enam bidang?" Karena persamaan ini sama untuk semua segitiga yang dirender dalam gambar tunggal, kita tidak perlu menghitungnya dengan sangat efisien. Untuk alasan ini, kita bisa membalikkan transformasi yang ditunjukkan pada Gambar 5.11 dan menerapkannya ke delapan simpul dari volume tampilan yang diubah:

(x, y, z) =(l, b, n) (r, b, n)

(l, t, n) (r, t, n) (l, b, f) (r, b, f) (l, t, f) (r, t, f).

Persamaan bidang dapat disimpulkan dari sini. Atau, kita dapat menggunakan geometri vektor untuk mendapatkan bidang langsung dari parameter tampilan.

Memotong dalam Koordinat Homogen (Opsi 2)

Anehnya, opsi yang biasanya diterapkan adalah kliping dalam koordinat homogen sebelum membagi. Di sini volume tampilan adalah 4D, dan dibatasi oleh volume 3D (hyperplanes). Ini adalah

−x + lw = 0, x − rw = 0,

−y + bw = 0, y − tw = 0,

−z + nw = 0, z − fw = 0.

Bidang-bidang ini cukup sederhana, sehingga efisiensinya lebih baik daripada Opsi 1.

Bidang ini masih dapat ditingkatkan dengan mengubah volume tampilan [l, r] × [b, t] × [f, n]

menjadi [0, 1]3 . Ternyata kliping segitiga tidak lebih rumit daripada di 3D.

Kliping melawan Pesawat

Tidak peduli pilihan mana yang kita pilih, kita harus memotong pesawat. Persamaan implisit untuk bidang yang melalui titik q dengan n normal adalah

f(p) = n · (p − q)=0.

Ini sering ditulis : (Persamaan 8.2)

f(p) = n · p + D = 0.

Menariknya, persamaan ini tidak hanya menggambarkan bidang 3D, tetapi juga menggambarkan garis pada 2 Dan dan volume analog bidang 4D. Semua entitas ini biasanya disebut bidang dalam dimensi yang sesuai.

Jika kita memiliki segmen garis antara titik a dan b, kita dapat "memotongnya" pada bidang menggunakan teknik untuk memotong tepi segitiga 3D dalam program pohon BSP. Di sini, titik a dan b diuji untuk menentukan apakah mereka berada pada sisi yang berlawanan dari bidang f(p) = 0dengan memeriksa apakah f(a) dan f(b) memiliki tanda yang berbeda.

Biasanya f(p) < 0 didefinisikan sebagai “di dalam” bidang, dan f(p) > 0 adalah “di luar” bidang.

Jika bidang membelah garis, maka kita dapat menyelesaikan titik potong dengan mensubstitusi persamaan garis parametrik,

P = a + t(b – a) ke dalam f(p) = 0 bidang Persamaan(8.2). Ini menghasilkan

n . (a + t(b – a)) + D = 0 Memecahkan untuk t memberi

𝒕 =𝒏 . 𝒂 + 𝑫 𝒏 . (𝒂 − 𝒃)

Kami kemudian dapat menemukan titik persimpangan dan "memperpendek" garis.

Untuk memotong segitiga.

Dalam dokumen JILID 1 (Halaman 143-154)