Oyun Hazırlıyorum – 5
3 Boyutlu Uzay ve Üçgenler
3 boyutlu bir obje çizmek için önce bunu 3 boyutlu olarak tanımlamamız gerekir. 2 boyutlu işlemler için x ve y eksenlerinden oluşan basit bir şekil kullanırız.
![]() |
Eğer şekildeki gibi 3 nokta tanımlar ve bunları 3 doğruyla birleştirirseniz 2 boyutlu düzlemsel bir üçgeniniz olur. |
|
|
Şekildeki gibi x ve y eksenlerinden oluşan bir grafiğimiz var. Burada eksenlerin kesiştiği yer merkezdir ve koordinatları (0,0)’dır. X ekseni üzerinde merkezin sol tarafı negatif sağ tarafı pozitiftir. Benzer şekilde y ekseninde merkezin altında kalan kısımlar negatif üstünde yer alan kısım pozitiftir. Bir nokta tanımlarken noktanın önce x eksenindeki yeri sonra y eksenindeki yeri verilir. Koordinatlar genellikle parantez içinde ve virgülle ayrılmış olarak yazılır. Örn: (2,3) ya da (-4,8) vb. |
İki boyutta noktaların ve şekillerin nasıl temsil edildiğini öğrendik. Peki ama 3 boyutlu bir ortam için ne gerekli? Bunun için z eksenini kullanacağız. Öncelikle x ve y eksenlerinin ekran düzlemi üzerinde olduğunu düşünün. Yani x ekseni soldan sağa, y ekseni ise yukarıdan aşağıya doğru gidiyor. Merkez de ekranın tam ortası. Bu durumda z ekseni monitöre baktığınız doğrultudadır. Gözünüzden çıkıp ekranın ortasındaki diğer eksenlerin kesiştiği noktadan giren bir ışın düşünün. İşte bu z ekseni oluyor. Eksende monitörün içine doğru girmiş olan kısım pozitif, monitörden size doğru gelen kısım negatif değer alıyor.
Şimdi 3 ekseni de kullanarak 3 boyutta bir nokta tanımlayabiliriz, örn. (1,5,-6). Bu örnekte noktamız, ekranınızın ortasında olduğunu varsaydığımız merkezden x ekseninde 1 (sağ), y ekseninde 5 (yukarı) ve z ekseninde –6 (geri) birim uzakta bulunuyor.
3 eksenimizle 3 nokta tanımlayarak ve bunları hayali çizgilerle birleştirerek uzayda bir üçgen tanımlayabiliriz. Ama burada bizim için asıl önemli olan yarattığımız bu üçgeni 2 boyutlu ekranımızda nasıl göstereceğimizdir.
3 Boyuttan 2 Boyuta Projeksiyon
|
|
Yandaki küp, 12 üçgenden |
|
|
Şimdi bu küpü ekranımıza |
Daha önce de söylediğimiz gibi
biz merkez noktası olarak (0,0,0) koordinatlarını alıyoruz. 2 boyuttaki
koordinatlar için de (0,0) koordinatlarını. Ama DirectDraw, (0,0)
koordinatlarını ekranın sol üst köşesi olarak alır. Biz bunu telafi etmek
için ekran koordinatlarımıza ekran büyüklüğünün yarısını ekleriz.
Yani (0,0) noktası için 640*480’lik bir ekranda (320,240) koordinatlarını
kullanırız.
Peki 3 boyutta bu işlemi nasıl
yapacağız? C++‘ın standart kütüphanesinde Squash3DSpaceInto2Dspace()
isminde bu
işi otomatik olarak yapan bir fonksiyon mevcut.
Ama bu
fonksiyon derleyicinizde bulunmuyorsa z eksenini tamamen gözden çıkarıp
sadece x ve y değerlerini ekrana basabilirsiniz.
Bunun
dezavantajı, perspektif bir görüntü elde edemememizdir. 2 küpümüz varsa
ve birisi diğerinden daha gerideyse daha küçük gözükmesi gerekir. Ama z
eksenini devreden çıkardığımız için oluşturduğumuz görüntüde bu
derinliği sağlayamayız. Eğer 3D
Studio MAX veya Lightwave 3D gibi programlar kullandıysanız orada yarattığınız
objeleri “üst”, “sağ”, “ön”
gibi açılarla görebilirsiniz. İşte bu pencerelerde çizilen görüntülerde
de z ekseni göz ardı edilir ve arkadaki objeler herhangi bir derinlik hissi
vermeden bire bir çizilir.
3 Boyuttan 2 Boyuta Gerçek Projeksiyon
Bir obje merkezden ne kadar ilerideyse, yani z eksenindeki koordinatı ne kadar büyükse, objemiz o kadar küçük görünmelidir. Bunu yapmak için x ve y koordinatlarını z koordinatına bölüyoruz. (x, y, z) koordinatlarında bir noktamız var diyelim. Bunu (x, y) haline dönüştürmek istiyoruz.
Ekran X koord = Xkoord / Zkoord
Ekran Y koord = Ykoord / Zkoord
3 boyutun temelinde bu vardır. (8,6,2)’de bir noktanız varsa;
x = 8 / 2 = 4
y = 6 / 2 = 3
olur. 3 boyutta, her biri 3’er noktaya sahip üçgenlerden oluşan bir küp tanımlarsanız, aynı eşitliği kullanarak perspektifi de göz önüne almış olarak bu küpü ekrana çizdirebilirsiniz.
Burada karşılaşacağımız tek sorun z değerinin çok büyük olması durumunda x ve y değerlerinin çok küçük olacağıdır. Çözüm, değerleri büyütmektir. Ama büyütme işini bütün değerler için yapmalıyız ki oranlar bozulmasın. Bunun için kullandığımız değerlerin tümünü büyük bir sayıyla çarparız:
Ekran X koord = (“3 boyutta X koord” * “büyük bir sayı”) / “3 boyutta Z koord”
Ekran Y koord = (“3 boyutta Y koord” * “büyük başka bir sayı”) / “3 boyutta Z koord”
Bu “büyük bir sayılar x ve y için farklı olmalıdır. Eğer 320*200 sisteminde çalışıyorsanız sayıları x için 280 ve y için 240 seçebilirsiniz. 640*480 kullanıyorsanız x için 620 ve y için 600 seçebilirsiniz. Bunu C kodu şeklinde yazacak olursak:
screen_x = (3d_x * 620) / 3d_z
screen_y = (3d_y * 600) / 3d_z
Son Olarak
Aklımızda tutmamız gereken tek şey ekran koordinatları (0,0)’ın sol üst köşeden başladığıdır. Biz ekranın tam ortasını (0,0) merkez olarak aldık ve bilgisayarla anlaşmazlık yaşamamak için bu değerlere ekran değerlerinin yarısını ekledik (640 * 480’lik bir ekranda x değerimize 320, y değerimize 240 ekledik). Y ekseninin yukarı gittikçe arttığını aşağı gittikçe azaldığını öğrendik. Bilgisayar, ekranın sol üst köşesini (0,0) kabul ettiği için bizim baktığımız bölge y ekseninin alt kısmı durumundadır. Bu yüzden y koordinatını yazarken başına eksi işareti koymayı da unutmayalım. Böylece son eşitliğimiz:
screen_x = ( (3d_x * 620 ) / 3d_z ) + ekran_genisligininin_yarisi
screen_y = (- (3d_x * 600 ) / 3d_z ) + ekran_yuksekliginin_yarisi



