Sekarang yang tinggal hanyalah apa yang berlaku di dalam gelung bersarang
Anda mungkin pernah melihat bahawa r1sin θ dan r1cos θ
Ini digunakan untuk membuat bulatan dalam graf 2D
Dan r2 untuk menjaga jarak antara bulatan supaya tidak bertindih
Jadi, r2 > r1 kerana r2 bermula dari asal ke pusat bulatan
Sekarang, untuk melakukan penggandaan matriks yang mengagumkan itu, kami akan mencipta satuBaris
Dalam C
singleRow circle = {2 + cos(theta), sin(theta), 0};
Di Jawa
singleRow circle = new singleRow(2 + Math.cos(theta), Math.sin(theta), 0);
Sekarang buat 3 matriks Ry, Rx, Rz yang akan membantu kita dalam putaran bulatan dan donat
Di Jawa
// rotation on Y-axis Matrix Ry = new Matrix( new singleRow(Math.cos(phi), 0, Math.sin(phi)), new singleRow(0, 1, 0), new singleRow(-Math.sin(phi), 0, Math.cos(phi)) ); // rotation on X-axis Matrix Rx = new Matrix( new singleRow(1, 0, 0), new singleRow(0, Math.cos(A), Math.sin(A)), new singleRow(0, -Math.sin(A), Math.cos(A)) ); // rotation on Z-axis Matrix Rz = new Matrix( new singleRow(Math.cos(B), Math.sin(B), 0), new singleRow(-Math.sin(B), Math.cos(B), 0), new singleRow(0, 0, 1) );
Dalam C
// rotation on Y-axis Matrix Ry = {{cos(phi), 0, sin(phi)}, {0, 1, 0}, {-sin(phi), 0, cos(phi)}}; // rotation on X-axis Matrix Rx = {{1, 0, 0}, {0, cos(A), sin(A)}, {0, -sin(A), cos(A)}}; // rotation on Z-axis Matrix Rz = {{cos(B), sin(B), 0}, {-sin(B), cos(B), 0}, {0, 0, 1}};
Menggunakan fungsi multiply, kami buat sebelum ini, kami akan mendapat koordinat donat berputar
Dalam C
singleRow donut = multiply(circle, Ry); singleRow rotateX = multiply(donut, Rx); // We will consider it as [Nx, Ny, Nz] singleRow spinningDonut = multiply(rotateX, Rz);
Di Jawa
singleRow donut = Matrix.multiply(circle, Ry); singleRow rotateX = Matrix.multiply(donut, Rx); // We will consider it as [Nx, Ny, Nz] singleRow spinningDonut = Matrix.multiply(rotateX, Rz);
Kami akan membuat reciNz yang akan menjadi timbal balik Nz 5 (jarak dari kamera)
float reciNz = 1 / (spinningDonut.a3 + 5);
int x = 40 + 30 * spinningDonut.a1 * reciNz; int y = 12 + 15 * spinningDonut.a2 * reciNz; // o is index of current buffer int o = x + screen_width * y;
screen_height / 2 sepatutnya 11 tetapi kami akan menggunakan 12 untuk Sekarang
apakah 30 dan 15? IDK
dan darabkan reciNz, kenapa? IDK
Kod donat mempunyai terlalu banyak misteri yang belum dapat diselesaikan
Sekarang untuk mencari menjadikannya 3D, kita perlu beberapa bahagian bercahaya
Untuk itu, kita perlu mencari
N = Ny - Nz
- 2 sinB cosϕ cosθ
- 2 sinB cosϕ
2 cosB sinA sinϕ
2 cosA sinϕ
N ialah antara 0 hingga √2
Sekarang darabkan N dengan 8 yang akan menjadi maks 11
int L = N * 8
Untuk mencetaknya dengan kecerahan, kami akan mencipta susunan aksara daripada kecerahan terendah kepada kecerahan tertinggi
char charOpts[] = ".,-~:;=!*#$@";
atau
char[] charOpts = {'.', ',', '-', '~', ':', ';', '=', '!', '*', '#', '$', '@'};
Sekarang bahagian terakhir
semak jika:
x < lebar skrin
y < ketinggian skrin
reciNz > zBuffer[0]
Jika ya, maka
if (zBuffer[o] < reciNz && y < screen_height && x < screen_width) { buffer[o] = charOpts[L > 0 ? L : 0]; zBuffer[o] = reciNz; }
Jika L negatif, gunakan charOpts[0]/ period(.)
Atas ialah kandungan terperinci Menjelaskan donat seperti telinga Part-3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!