Bagaimana Anda menemukan bola terbesar yang bisa Anda gambar dalam perspektif?
Dilihat dari atas, akan seperti ini:
Ditambahkan: pada frustum di sebelah kanan, saya telah menandai empat poin saya pikir kita tahu sesuatu tentang. Kita dapat memproyeksikan kedelapan sudut frusum, dan pusat-pusat ujung dekat dan jauh. Jadi kita tahu titik 1, 3 dan 4. Kita juga tahu bahwa titik 2 adalah jarak yang sama dari 3 seperti 4 dari 3. Jadi kita dapat menghitung titik terdekat pada baris 1 ke 4 ke titik 2 untuk mendapatkan pusat? Tetapi matematika dan kode yang sebenarnya luput dari saya.
Saya ingin menggambar model (yang kira-kira berbentuk bola dan yang saya miliki untuk bola miniball yang mengikat) sebesar mungkin.
Pembaruan: Saya sudah mencoba menerapkan pendekatan incircle-on-two-pesawat seperti yang disarankan oleh bobobobo dan Nathan Reed :
function getFrustumsInsphere(viewport,invMvpMatrix) {
var midX = viewport[0]+viewport[2]/2,
midY = viewport[1]+viewport[3]/2,
centre = unproject(midX,midY,null,null,viewport,invMvpMatrix),
incircle = function(a,b) {
var c = ray_ray_closest_point_3(a,b);
a = a[1]; // far clip plane
b = b[1]; // far clip plane
c = c[1]; // camera
var A = vec3_length(vec3_sub(b,c)),
B = vec3_length(vec3_sub(a,c)),
C = vec3_length(vec3_sub(a,b)),
P = 1/(A+B+C),
x = ((A*a[0])+(B*a[1])+(C*a[2]))*P,
y = ((A*b[0])+(B*b[1])+(C*b[2]))*P,
z = ((A*c[0])+(B*c[1])+(C*c[2]))*P;
c = [x,y,z]; // now the centre of the incircle
c.push(vec3_length(vec3_sub(centre[1],c))); // add its radius
return c;
},
left = unproject(viewport[0],midY,null,null,viewport,invMvpMatrix),
right = unproject(viewport[2],midY,null,null,viewport,invMvpMatrix),
horiz = incircle(left,right),
top = unproject(midX,viewport[1],null,null,viewport,invMvpMatrix),
bottom = unproject(midX,viewport[3],null,null,viewport,invMvpMatrix),
vert = incircle(top,bottom);
return horiz[3]<vert[3]? horiz: vert;
}
Aku akui aku menikmatinya; Saya mencoba mengadaptasi kode 2D dengan memperluasnya menjadi 3 dimensi. Itu tidak menghitung insphere dengan benar; titik tengah bola tampaknya berada di garis antara kamera dan kiri atas setiap kali, dan terlalu besar (atau terlalu dekat). Apakah ada kesalahan nyata dalam kode saya? Apakah pendekatannya, jika diperbaiki, berhasil?
Jawaban:
Saya akan berasumsi bahwa frustum Anda simetris, karena gambar Anda tampaknya menyarankan demikian. Ada tiga kendala (dua jika frustum Anda adalah 2D):
A. bola tidak bisa lebih besar dari jarak antara pesawat dekat dan jauh
Jika
D
jarak dekat-jauh, kendala pertama adalah:B. bola tidak bisa tumbuh lebih luas dari bidang samping
Sekarang untuk kendala lain, katakanlah
α
adalah setengah sudut frustum danL
setengah lebar dari pesawat jauh, seperti yang ditunjukkan dalam gambar ini:Rumus pertama diberikan oleh trigonometri dalam segitiga. Yang kedua berasal dari jumlah sudut segitiga. Yang memberi kita batasan kedua:
Jika frustum Anda adalah 3D, Anda akan memiliki batasan ketiga dengan nilai
L
dan baruα
.Hasil akhir
The
R
nilai yang Anda cari adalahmin
dari tiga batas.Cara mendapatkan parameter
Jika Anda dapat memproyeksikan frustum dalam pandangan atau ruang dunia, Anda dapat menghitung L, D dan α dengan cara berikut, di mana
P
titik-titik itu dari bidang yang dekat, danQ
titik-titik itu dari bidang yang jauh:Panah berarti vektor, “.” adalah produk titik, dan || menunjukkan panjang vektor. Ganti
Q2
denganQ3
danP2
denganP3
untuk mendapatkan L dan α dalam dimensi vertikal.sumber
Dalam 2D: anggap frustum sebagai segitiga (2D)
Anda kemudian ingin menemukan incircle of the triangle.
Sebagai masalah 3D, Anda perlu menemukan insphere dari piramida berbasis persegi.
Jika saya memiliki formula saya akan mencetaknya di sini, tetapi sayangnya, saya tidak tahu formula itu.
sumber
The Biggest Sphere mungkin harus menyentuh bidang jauh (menggunakan istilah untuk pandangan-frustrasi di sini) tepat di tengah. Ini juga akan menyentuh bidang atas / bawah atau bidang kiri / kanan, tergantung pada sudut FoV mana yang lebih kecil. Saya harus mengatakan bahwa saya tidak memiliki bukti matematika aktual untuk asumsi-asumsi itu, tetapi mereka harus benar. Mungkin seseorang memiliki ide tentang cara membuktikannya.
Sphere dapat ditentukan oleh titik pusat dan jari-jarinya. Cx dan Cy sama dengan pusat farplane.
Cz dan jari-jari dapat diperoleh dengan menyelesaikan sistem persamaan berdasarkan asumsi yang tercantum di atas.
T adalah salah satu dari bidang bawah / atas atau bidang kiri / kanan (lihat di atas) dengan t1, t2 dan t3 sebagai vektor normal yang dinormalisasi dan t4 sebagai jarak dari asalnya. f adalah pusat dari pesawat jauh.
t1 * cx + t2 * cy + t3 * cz - t4 = r
-fz + cz = r
t1 * cx + t2 * cy + t3 * cz - t4 = -fz + cz
t1 * cx + t2 * cy + fz - t2 = + cz - t3 * cz
t1 * cx + t2 * cy - fz - t2 = cz * (1 - t3)
cz = (t1 * cx + t2 * cy - fz - t2) / (1 - t3)
r kemudian dihitung dengan memasukkan cz ke dalam ini: -fz + cz = r
Anda dapat memperoleh semua pesawat dari Proyeksi Matriks yang Anda gunakan. (Tidak ViewProjection dalam hal ini)
setelah itu Anda harus memindahkan bola ke ruang yang tepat: C '= terbalik (Lihat) * C
sumber
Saya mencoba melakukan sesuatu yang serupa, dan dalam kasus saya, kecepatan lebih penting daripada akurasi selama bola tidak ada di luar batas frustrasi.
Jika Anda menghitung jarak terpendek di antara garis-garis (atau wajah dalam 3d), jarak terpendek yang ditemukan dapat digunakan sebagai diameter incircle / insphere yang terletak sepenuhnya di dalam frustum. Asal-usul incircle / insphere bisa saja merupakan rata-rata dari semua simpul (jumlah & pembagian). Ini akan sangat cepat dan juga berfungsi untuk semua jenis polyhedra cembung.
Satu-satunya kelemahan adalah bahwa lingkaran atau bola tidak harus menjadi incircle atau insphere terbesar yang mungkin. Untuk frustum dengan banyak volume dan satu tepi yang sangat pendek, lingkaran / bola akan berbagi ruang frustum jauh lebih sedikit daripada yang mungkin.
Ide lain
Jika Anda ingin insphere dari view-frustum 3D dan Anda memiliki matriks perspektif yang digunakan untuk membangun frustum ini, maka Anda bisa menggunakan matriks itu pada insphere unit kubus, dan itu harus menjadi tempat yang sempurna untuk frustum. (Diameter insphere kubus adalah panjang salah satu ujung kubus, pusatnya adalah tengah kubus yang merupakan rata-rata dari simpul kubus)
sumber