PHP ile 3 Boyutlu Görüntüler Hazırlayın
Düzey: Orta
Mike Brittain (mike@mikebrittain.com),
Teknoloji Yöneticisi, ID Society
28 Mart 2006
Başlangıçta Web geliştirme amaçlı olarak tasarlanmış bir dil olan PHP, yıllardır dinamik Web sitelerini ve veritabanı uygulamalarını yönetmek için kullanılmıştır. PEAR'ın (PHP Extension and Application Repository) aracılığıyla bu dilde yapılan genişletmeler, geliştiricilere dili yeni ve ilginç yönlere taşıma olanağı tanıdı. PEAR'ın Image_3D paketi, üç boyutlu (3-D) grafiklerin PNG ve SVG gibi modern Web tarayıcılarında giderek daha çok desteklenen iki görüntü biçimi dahil, çeşitli biçimlerde yaratılması için kullanılabilecek nesne odaklı bir arabirimdir. Image_3D paketini nasıl kullanacağınıza ilişkin bilgi edinin, dinamik 3 boyutlu görüntülerin kullanılmasındaki sınırları öğrenin ve 3 boyutlu grafiklerin pratik uygulamalarını görün.
Başlamadan önce
Bu eğitici yazı, 3 boyutlu grafiklerin dinamik olarak oluşturulmasıyla ilgilenen PHP programcıları içindir. Görüntüler sıfırdan yaratılabilir, bir alanda X, Y, ve Z koordinatlarına göre konumlandırılmış ışık kaynaklarından ve nesnelerden oluşturulabilir. 3-D Studio Max kullanmada deneyimli olan programcılar nesnelerin 3DS dosyalarından PHP oluşturmalarına nasıl aktarılacağını anlayacaklardır. Parametrik denklemlerle tanımlanan karmaşık yüzeyler Image_3D kullanılarak kolayca eşlenebilir. Sonuçta, iş uygulamaları ve veri raporları, kolayca hazırlanan pasta grafikler eklenerek zenginleştirilebilir.
Image_3D, 3 boyutlu görüntülerin oluşturulmasında kullanılan nesne odaklı bir arabirimdir. Nesneler ve ışıklar X, Y ve Z koordinatlarına göre, 3 boyutlu alanda konumlandırılır. Sonra görüntüler 2 boyutlu alana dönüştürülür ve PNG, SVG olarak depolanabilir ya da kabuğa (shell) çıkışları alınabilir (ANSI kabuklarında kullanılmak üzere). Paket, küpler, koniler, küreler, metin ve pasta grafikler gibi bir dizi basit 3 boyutlu nesneyi kolayca oluşturmak için kullanılabilir. Ayrıca, 3-D Studio Max'de oluşturulmuş nesneleri içe aktarma ve değiştirme desteği de vardır. 3 boyutlu alanlardan iyi anlayan geliştiriciler, ilginç nesneler oluşturmak için özelleştirilmiş poligram ve yüzey eşlemlerinden yararlanabilirler.
Bu eğitici yazının ilk yarısında, 3 boyutlu görüntü dosyaları oluşturmak için komut satırı PHP komut dosyalarının nasıl kullanılacağı gösterilmektedir. Renkler ve ışıklarla temel bir 3 boyutlu alan oluşturulduktan sonra, her bir eşsiz 3 boyutlu nesne tipinin yanı sıra, çıkış dosyası biçimlerinin her biri de incelenmektedir. İkinci yarıda ise bu temel örneklerin kullanışlı uygulamalara nasıl dönüştürüleceği tartışılır. 3 boyutlu görüntülerin oluşturulmasında işlemci yoğun olarak kullanılır, bu nedenle, dinamik olarak oluşturulmuş görüntüleri Web sunucularınızı çökertmeden Web'e taşımak amacıyla bu sorun için bir çözüm bulmalısınız. Image_3D paketi yalnızca statik görüntü biçimlerini destekler, bu nedenle, 3 boyutlu alanları canlandırmak için basit bir JavaScript çözümü oluşturacaksınız. Sonuçta da, veri raporlarının iş uygulamaları ile bütünleştirilebilen renkli pasta grafikler biçiminde görüntülenmesi için bir PHP sınıfı yazacaksınız.
Devam etmek için aşağıdaki yazılım ve araçlar gereklidir:
- PHP V5
- Image_3D paketi, PHP V5 nesne ve sınıf sözdizimi kullanılarak yazılır.
- Image_3D
- PEAR paketinin kurulması gerekir. Genelde,
makinenize kök (ya da yönetici) olarak erişiminiz varsa, Image_3D'yi
kurmanız kolay olur. Image_3D alfa
sürümde olduğu için, PEAR kuruluşu paketin "sabit" olmadığını
belirtebilir. Kuruluşu uygulamak için
-f
seçeneğini kullanın:
pear install -f Image_3D |
- GD
- Bu grafik kitaplığı, PNG dosyalarının çıktısının alınması için
gereklidir. Aslına bakılırsa, GD yoksa, Image_3D'den diğer
dosya tipleri de oluşturulabilir. PHP V4.3 itibariyle, GD kitaplığının bir sürümü yeni PHP
kuruluşlarıyla birlikte gönderilir. Büyük olasılıkla, PHP'yi yeniden derlemekle uğraşmanız gerekmez. Mevcut
PHP kuruluşunuzda GD'nin etkinleştirilip
etkinleştirilmediğini görmek için
phpinfo()
'yu kullanabilirsiniz.
- Web sunucusu
- Bu eğitici yazının ikinci yarısındaki örnekler Web sitesinde kullanılmak üzere oluşturulabilir. Hazırda bir Web sunucunuz yoksa, Apache'nin açık kaynak Web sunucusu ve IBM HTTP Server, kullanabileceğiniz iki uygun seçenektir.
- SVG viewer
- SVG dosyaları, yerel SVG desteği içeren Mozilla Firefox V1.5 ürününde görüntülenebilir. Internet Explorer kullanıcıları, Adobe SVG eklentisini yükleyerek tarayıcılarına SVG desteği ekleyebilirler.
Image_3D'nin arabiriminin tamamı nesne odaklı olduğu için, bu eğitici yazıda, nesnelere ve sınıflara ilişkin en azından temel bilgilere sahip olunduğu varsayılır. Bu eğitici yazının ilk yarısında gösterilen komut satırı PHP örneklerini yürütmek için Linux® kabuk hesabına ya da bir Windows® komut istemine erişim gerekir. Temel düzeyde JavaScript deneyimi de gereklidir.
Alanınızın düzenlenmesi
Çoğu PHP geliştiricisinin 2 boyutlu grafiklerden az da olsa anladığını söylemek yanlış olmaz. Büyük olasılıkla çoğu, Adobe Photoshop, Corel Paint Shop Pro, GIMP ya da başka bir program kullanarak en azından birkaç temel grafik oluşturmuştur. Önce, 3 boyutlu bir alanın ya da dünyanın alışıldık 2 boyutlu tuvalle karşılıklı olarak nasıl ilişkilendirilebileceğini tartışarak başlayalım. Ayrıca, ışıklar, renkler ve dönüşümler gibi 3 boyutlu görüntülerinizi tasarlamanıza yardımı olacak araçları da inceleyeceksiniz.
Sıradan grafik programları, bit eşlemi görüntülerken X ve Y eksenleriyle çalışır. Her bir piksel bu eksenlerde yerleştirilir. Başlangıç noktası (X=0, Y=0), üst sol köşededir. 30, 20 koordinatlarındaki bir piksel, başlangıç noktasının 30 birim (genelde pikseldir) sağında, 20 birim de altındadır.
3 boyutlu alanınızda çalışırken, başlangıç noktası alanın köşesinden çok, merkezini simgeler. Üçüncü eksen, Z, X ve Y eksenlerine karşılıklı olarak diktir. Z ekseninin pozitif yönünü bilgisayarınızın ekranının içine doğru olarak düşünün. Negatif yön, ekrandan uzağa doğru olacaktır. Şekil 1 içinde her bir eksenin yönü gösterilir.
Şekil 1. 3 boyutlu koordinat sistemi
Koordinat sisteminde 3 boyutlu nesneler oluştururken, her bir nesnenin ya da noktanın başlangıç noktasına olan uzaklığı, negatif ya da pozitif birim olarak ölçülür.
3 boyutlu alanınıza yerleştirdiğiniz her bir nesne için (koniler, küreler, vb.) PHP nesneleri oluşturacaksınız. Ayrıca, bu alan içindeki ışık kaynaklarını simgeleyen PHP nesneleri de oluşturacaksınız. Renkli nesneler her bir şekli ya da ışık kaynağını değiştirmekte kullanılır ve bir nesnenin alfa şeffaflığını ayarlamakta da kullanılabilir. Her bir nesnenin boyutunu, dönüşünü, konumunu dönüştürürken ya da hatta alanın bütününü dönüştürürken matris nesneleri oluşturulur.
İlk dünyanızın oluşturulması
İlk görüntünüz, Image_3D ile oluşturulan herhangi bir görüntü için gerekli olan tüm temel öğeleri içerir. Bu örnekten, paketteki tüm temel nesneleri hızla inceleyebilecek doğru alana ve ışığa sahip olacaksınız.
Bu ilk örneğin amacı, beyaz bir artalanda ışıklandırılmış koni şeklinde bir nesne yaratılmasıdır. Sonuçta ortaya çıkan alan, 400x400 piksellik bir görüntüye dönüştürülecektir.
Liste 1. 3 boyutlu alanda bir koni oluşturulması
<?php require_once('Image/3D.php'); // Create the blank three-dimensional space $world = new Image_3D(); $world->setColor(new Image_3D_Color(255, 255, 255)); // A blue light from the left $light1 = $world->createLight(-300, 0, -300); $light1->setColor(new Image_3D_Color(100, 100, 255)); // A green light from the upper-right $light2 = $world->createLight(300, -300, -300); $light2->setColor(new Image_3D_Color(100, 255, 100)); // Build the cone object $cone = $world->createObject('cone', array('detail' => 64)); $cone->setColor(new Image_3D_Color(255, 255, 255)); $cone->transform($world->createMatrix\ ('scale', array(70, 220, 70))); $cone->transform($world->createMatrix('rotation', array(-45, -120, -10))); $cone->transform($world->createMatrix\ ('move', array(-50, -30, 10))); // Render and save the 2-D image $world->createRenderer('perspectively'); $world->createDriver('gd'); $world->render(400, 400, 'object.png'); ?> |
Oluşturduğunuz her görüntü, $world
olarak
adlandıracağınız yeni bir Image_3D
nesnesi oluşturularak başlar. Alanın artalan rengi, Image_3D_Color
nesnesi oluşturularak ayarlanır. Bu nesnenin yapıcısının üç
parametresi, oluşturmak istediğiniz rengin RGB değerleridir.
Alanda iki adet Image_3D_Light nesnesi oluşturursunuz. Mavi bir ışık olan ilkinin, başlangıç noktasının soluna, ekranın düzleminden uzağa yerleştirildiğini düşünün. İkincisi de başlangıç noktasının üst sağ köşesine, yine ekrandan uzağa yerleştirilsin. Bu nesne, yeşil olsun.
Sonra, alana bir koni yerleştirilsin. Bu nesneye atadığınız rengin beyaz olduğuna dikkat edin. Böylece, nesne alana yerleştirdiğiniz iki ışığın rengini alır. Bu yöntem, farklı renklere sahip bir nesnenin karşıt yönlerini vurgulamak için en iyi yöntemdir.
Koniye üç dönüşüm uygulanır. Önce, nesnenin ölçeği yükseltilir. Koni nesnesi, oluşturulurken boyutu atanmayan tek nesnedir. Temelde 1x1x1 boyutlarında bir alanda oluşturulur ve boyutlarının yeniden belirlenmesi gerekir. Sonra, koniyi, ışığı iyi olarak yakalayabilmesi için döndürün. Bu, biraz deneme yanılma sürecidir. Ardından, koniyi taşıyarak görüntünün ortasına yerleştirin.
Komut dosyanızın son adımı, 3 boyutlu alanın 2 boyutluya
dönüştürülmesidir. Örneklerin tümünde "perspectively" (perspektif olarak)
dönüştürme motoru kullanacaksınız (diğer seçenek, "isometric"dir (eşit
ölçekte)). PNG görüntüsünü oluşturacak olan gd
çıkış sürücüsü seçilir. Görüntünün boyutunu 400x400 piksel olarak
seçin; görüntü, şu dosya adı ile kaydedilecektir: object.png.
Görüntüyü oluşturmak için, komut dosyası komut satırından çalıştırılmalıdır:
|
Oluşturulan görüntü dosyası aşağıda gösterildiği gibi görünmelidir:
Şekil 2. Image_3D paketi kullanılarak oluşturulmuş 3 boyutlu koni
Ayrıntıların denetlenmesi ve gerçekleme (rendering) süresi
Verdiğim örneğin yeterince açıklayıcı olduğunu umarım. Image_3D ile birlikte gönderilen diğer yerleşik nesne tiplerini göstermek için birkaç ek örnekte de aynı alanı, ışıklandırmayı ve gerçeklemeyi kullanacaksınız.
Devam etmeden önce, ilk komut dosyanızla ilgili belirtmemiz
gereken iki nokta var. Koni nesnesini örnekle desteklerken, ikinci
bağımsız değişken olarak bir dizilimi [array('detail'
=> 64)
] geçirdiniz ; bu dizilim, koniyi oluşturmak için kullanılan
çokgenlerin sayısını belirler. Bu çokgenlerin sayısının az olması, görüntünün daha açılı
olmasına neden olurken, bu sayının yüksek olması görüntünün yüzeyini
düzgünleştirir (bkz. Şekil 3).
Şekil 3. 3 boyutlu konilerde farklı ayrıntı düzeyleri. Gösterilen ayrıntı düzeyleri 8, 16, 32 ve 64'tür
Ayrıntı düzeyi yükseldikçe, Image_3D'nin görüntüyü oluşturması o kadar uzun sürer. Konilerin oluşturulması oldukça basittir, bu nedenle etkisi korkunç değildir. Kürelere ve daha karmaşık şekillere geçtiğinizde, gerçekleme hızının kolayca denetiminizden çıkabileceğini göreceksiniz.
Görüntünün nasıl oluşturulduğuna ilişkin bilgi sağlayacak olan Image_3D nesnesi için yerleşik bir istatistik yöntemi vardır. Aşağıdaki satırı bir önceki komut satırının sonuna koyun.
echo $world->stats(); |
Komut dosyası yeniden çalıştırıldığında, Liste 2 içindeki çıkış görüntülenmelidir.
Liste 2. Koni nesnesinin oluşturulması için istatistikler
|
Bu basit ayrıntılar bir yana, komutlarınız daha ayrıntılı 3 boyutlu görüntüler oluşturdukça, komut dosyalarınızın yürütülme süresini ölçmek için PEAR::Benchmark paketini kullanmayı düşünebilirsiniz (bkz Kaynaklar).
Işık kaynakları ve renk
Renk ya da ışık olmazsa, 3 boyutlu alanınızda nesneleri göremezsiniz. Şimdi de, yarattığınız nesneleri görmemize olanak sağlayan bu iki önemli öğeyi inceleyelim.
Yukarıdaki örnekteki koninin rengini kırmızıya (255, 0, 0) ayarlayacak ve iki ışık kaynağını kaldıracak olsaydınız, sonuçta ortaya çıkan görüntü, beyaz artalanda siyah bir koni gösterirdi. Üzerinde bir ışık kaynağı parlamadıkça, koninin kırmızı yüzeyi ortaya çıkmaz.
Bu sorunu, en az bir adet ışık kaynağı ekleyerek çözebilirsiniz. Işığın rengini en ortaya çıkaran beyaz ışıktır, bu nedenle ışığın beyaz olması en uygunudur.
Tek bir ışık kaynağı, alanınızdaki nesnenin ya da nesnelerin yalnızca tek bir yanını aydınlatacaktır. Karşı tarafa başka bir ışık kaynağı eklemeniz nesneleri daha da görünür kılar. İki beyaz ışık kullanırsanız, bunlar nesneye pek bir kişilik katmaz, çünkü karşıt açılar yalnızca nesnenin renginin değişik tonlarını yansıtır.
Önceden de tartışıldığı gibi, bunun yerine, bu örneklerde beyaz renkli nesneler oluşturup onları renkli ışıklarla aydınlatacaksınız. Bu, her bir nesnenin özelliklerini ortaya çıkacak olan daha çok ton ve renk özünün kullanılmasına olanak tanır.
Yukarıdaki örnekte, Image_3D_Color
sınıfı kullanarak koni
nesnesinin rengini belirlediniz. Yapıcının ilk üç parametresi, istenen rengin RGB değerleridir. Burada
gösterilmeyen dördüncü parametre ise, alpha
transparency
parametresidir. Komut dosyanıza 150 değerini
eklediğinizde, kısmen şeffaf bir koni oluşturursunuz.
$cone->setColor(new Image_3D_Color(255, 255, 255, 150)); |
Şekil 4 içinde, şeffaflığın koni üzerindeki etkisi gösterilir.
Şekil 4. Üst üste yerleştirilmiş iki adet 3 boyutlu koni nesnesi, her ikisinde de 150 değerinde alfa şeffaflık uygulanmıştır
RGB renklerine uygulanabilen bir etki daha vardır: krom görüntüsü! Koninin
rengi olarak standart Image_3D_Color nesnesini sağlamak yerine,
yeni bir Image_3D_Color_Metal
nesnesi oluşturun
(Image/3D/Color/Metal.php'yi eklemeyi unutmayın, diğer sınıflar
gibi Image/3D.php tarafından eklenmez). Bkz. Liste 3.
Liste 3. 3 boyutlu nesnelere metal görüntüsünün uygulanması
require_once('Image/3D/Color/Metal.php'); $cone = $world->createObject('cone', array('detail' => 64)); $metal = new Image_3D_Color_Metal(255,255,255); $metal->setMetal(1.25); $cone->setColor($metal); |
setMetal()
yöntemi, parametre olarak değişiklik gösterir. Biraz deneyim kazanıldığında, 0.5 ve 2.0 arasındaki değerlerin en iyi etkiyi ortaya çıkardığı görülür. 2.0 üzerindeki bir değer, görüntünün tamamen parlamasına neden olur. Koninin renk ve ışığının nasıl etkilendiğini görmek için bu değerle oynayabilirsiniz.
Nesnelerin ve şekillerin değiştirilmesi
Daha önce Adobe Photoshop programındaki dönüştürme aracını kullandıysanız,
büyük olasılıkla onun taşıma, ölçekleme, döndürme, çevirme ve çarpıtma öğelerine alışıksınızdır.
3 boyutlu nesnelerin ve alanların transform()
yöntemi, bu aracınkine benzer.
Bu terim sizi korkutmasın. Pratikte, dönüştürme matrisi,
aslında yalnızca bir nesnenin taşınmasını, ölçeklenmesini ya da
döndürülmesini sağlayan bir denetimdir. Bu, ilk olarak
Image_3D_Matrix
yaratıp sonra onu bir
transform()
yöntemine geçirerek elde edilir. Sonuçta, bu
pek de zor değildir.
Aşağıda üç örnek verilmiştir (her bir matrisin ikinci parametre olarak üç değerli bir dizilim aldığına dikkat edin):
$obj->transform($world->createMatrix\ ('move', array(-50, -30, 10))); $obj->transform($world->createMatrix\ ('scale', array(70, 220, 70))); $obj->transform($world->createMatrix\ ('rotation', array(45, 0, 0))); |
'Move'
(Taşı) matrisinin dizilim değerleri, X, Y ve Z
eksenlerindeki hareketi belirtir. 'Scale'
(Ölçeklendir)
matrisine uygulanan değerler, aynı üç eksen boyunca ölçekleme
derecesini belirtir. 'Rotation'
(Döndürme)
matrisine ilişkin değerler, her bir eksende 0 - 360 dereceler arasındaki döndürme miktarını belirtir. Şekil 5 içinde nesnenin hangi yöne döndürüldüğü gösterilir (ters yöne döndürmek için eksi değerleri uygulayabilirsiniz).
Şekil 5. X, Y ve Z eksenlerinde döndürme yönleri
Dönüştürmeler nerede ve ne zaman uygulanır?
Bu dönüştürmelerin her biri tek bir nesneye ya da 3 boyutlu alanın bütününe uygulanabilir.
Yarattığınız ilk örnek görüntünün alanında, bir koninin nasıl
döndürülebileceğini, ölçeklendirilebileceğini ve taşınabileceğini
gördünüz. Dönüştürme işlemini koni yerine $world
nesnesine uygulamış olsaydınız, 3 boyutlu alandaki herşeyi etkilerdi;
alandaki tüm nesneler ve ışıklar, büyük bir boşluk olarak, bütünüyle
etkilenirdi.
Dönüştürmeler, belirtilen sırayla her bir nesneye uygulanır. Bu size açık gibi görünebilir, ancak önce, nesnelere birer birer ve sonra da alanın bütününe olmak üzere birden çok dönüştürme uyguluyorsanız, dönüştürmelerinizi eklerken sıraya dikkat etmediğinizde beklemediğiniz sonuçlarla karşılaşabilirsiniz.
Ek nesneler
Koninizin ışıklandırılması, renklendirilmesi ve konumlandırılmasına ilişkin pek çok ayrıntıyı tamamladınız. Şimdi de Image_3D'de başka hangi tip nesnelerin yaratılabileceğine dönelim.
Koniler gibi, küplerin de yaratılması kolaydır. Küp oluşturmak
için yalnızca birkaç çokgen gereklidir, üstelik, boyutları ne olursa
olsun, tüm küpler aynı düzeyde ayrıntı içerir. Küp yaratırken,
createObject()
için ikinci parametre, kübün genişliği,
yüksekliği ve derinliğinden oluşan üç değerli bir dizilimdir.
Küp oluştururken, Liste 1 içinde $cone
yerine aşağıdaki
satırları yazabilirsiniz:
$cube = $world->createObject('cube', array(100, 100, 100)); $cube->setColor(new Image_3D_Color(255, 255, 255)); $cube->transform($world->\ createMatrix('rotation', array(-60,60,40))); |
Sonuçta ortaya çıkan görüntü şöyle olur:
Şekil 6. Image_3D paketi kullanılarak oluşturulmuş 3 boyutlu küp
Liste 1 içindeki ilk örneğinizi düzelterek devam edersek, koniyi küre ile değiştireceksiniz.
Burada, ikinci parametre, kürenin yarıçapını simgeleyen
r
için bir değer ve nesnenin görece düzgünlüğünü
tanımlayan bir tamsayı olan detail
(ayrıntı) değerini
içeren bir Hash algoritması olacaktır.
Detail değeri, 1 kadar küçük olabilir, ama bu durumda nesne, küreden
çok buruşturulmuş kağıt topağına benzeyecektir, bu değer arttıkça,
nesnenin kalitesi ve gerçekleme süresi de artar. Detail öğesinde en iyi değerler 4, 5 ya da 6'dır. 6'dan daha yüksek bir değer kullanıldığında gerçekleme süresi, saniyelerle değil, ancak dakikalarla ölçülebilecek kadar uzun olur.
$sphere = $world->createObject('sphere', array('r' => 85, 'detail' => 5)); $sphere->setColor(new Image_3D_Color(255, 255, 255)); |
Sonuçta ortaya çıkan görüntü şöyle olur:
Şekil 7. Image_3D paketi kullanılarak oluşturulmuş 3 boyutlu küre
Bu küre oluşturulurken bildirilen istatistikleri (bkz Liste 4), Liste 2 içindeki konide görülenlerle karşılaştırın.
Liste 4. 5 detail değeriyle küre nesnesi oluşturulmasının istatistikleri
|
Aslında, bu kürenin detail ayarını 6'ya yükseltirseniz, çokgenlerin ve noktaların sayısı dört katına çıkar.
Wikipedia'ya göre, simit şekli, iki daire şeklinin (S1 x S1) ürünü olarak tanımlanan bir kapalı yüzeydir. Geometri bilgilerinizi unuttuysanız, bildiğiniz bir simidi gözünüzün önüne getirin.
Simit şeklinin nasıl oluşturulduğunu görmek için aşağıdaki kodu 3 boyutlu alanınıza ekleyin.
Liste 5. Simit şekli örneği
$torus = $world->createObject('torus', array('inner_radius' => 90, 'outer_radius' => 120, 'detail_1' => 30, 'detail_2' => 30)); $torus->setColor(new Image_3D_Color(255, 255, 255)); $torus->transform($world->createMatrix('Rotation', array(-45,0,-30))); $torus->transform($world->createMatrix('Move', array(0,-20,0))); |
Bir kez daha, createObject()
'in ikinci parametresine geçirilen başka bir değer kümeniz var. Bu durumda, inner_radius
(iç yarıçap) ve outer_radius
(dış yarıçap), simidin
iç ve dış yarıçaplarının adlarıdır. Detail_1
(ayrıntı 1) ve detail_2
(ayrıntı 2) öğeleri daha belirsizdir.
Bu değerleri ayarlamayı denerseniz, detail_1
öğesinin
bantları (halkaya dik olan çizgileri) ve detail_2
öğesinin ise şeritleri (halkanın dış kenarına paralel çizgileri)
denetlediğini görürsünüz.
Sonuçta ortaya çıkan görüntü şöyle olur:
Şekil 8. Image_3D paketi kullanılarak oluşturulmuş 3 boyutlu simit şekli
Image_3D paketi kullanılarak metinler de üç boyutlu olarak gerçeklenebilir. Ancak, metnin stilinin belirlenmesinde pek az seçenek sunulur. Örneğin, yazı tipi seçemezsiniz; pakette yerleşik bulunan tek bir yazı tipinden başka seçeneğiniz yoktur. Yine de, Liste 6 içinde bir metin nesnesinin nasıl yaratılacağı gösterilir.
Liste 6. Metin nesnesi örneği
$text = $world->createObject('text', 'Databases!'); $text->setColor(new Image_3D_Color(255, 255, 255)); $text->transform($world->createMatrix('Scale', array(6, 6, 6))); $text->transform($world->createMatrix('Rotation', array(-35, 30, -15))); $text->transform($world->createMatrix('Move', array(-150, 10, 20))); |
Önceki örneklerdeki createObject()
öğesinin ikinci
parametresine geçirilen dizilimin yerine, yalnızca görüntülenecek olan
metni sağlamanız yeterlidir.
İnanması zor ama, PHP eğitici yazısının ortasına geldik ve pek çok PHP eğitici yazısının konusu olan aynı anda her yerde bulunan sistemlerden henüz söz edilmedi. Bu henüz adı geçmemiş olan sistemlere ilişkin 3 boyutlu bir gösterim aşağıda verilmiştir:
Şekil 9. Image_3D paketi kullanılarak oluşturulmuş 3 boyutlu metin
Şimdiye dek gördüğümüz 3 boyutlu görüntü oluşturmakta kullanılan araçlar temel düzeydeydi, üstelik, sıfırdan görüntü oluşturarak yapabilecekleriniz de sınırlıdır. Önceden yapılmış 3D Studio Max dosyalarını içe aktarma yeteneği (bkz. Liste 7), heyecan verici olasılıklar sunar.
Liste 7. 3D Studio Max dosyası örneği
$obj = $world->createObject('3ds', 'Image_3D.3ds'); $obj->setColor(new Image_3D_Color(255, 255, 255)); $obj->transform($world->createMatrix('Rotation', array(110, 40, 0))); $obj->transform($world->createMatrix('Scale', array(7, 7, 7))); |
Gördüğünüz gibi, nesnenin oluşturulması için, 3D Studio Max dosyasının bulunması yeterli. Image_3D kuruluşu ile biraz ilgilendiyseniz, PEAR paketindeki bazı örnekleri görmüş olabilirsiniz. Yukarıdaki listede içe aktarılan Image_3D.3ds dosyası bu örneklerden alınmıştır. Sonuçta ortaya çıkan görüntü aşağıda gösterilmiştir:
Şekil 10. Image_3D paketi ile içe aktarılmış ve gerçeklenmiş 3D Studio Max dosyası
Elbette, bu sefer işimiz kolaydı, çünkü yukarıdaki dosyada içe aktarılan 3D Studio Max dosyası 200 KB'den küçüktü ve oldukça basit bir dosyaydı. Daha büyük dosyaların açılması sunucunuzu ya da PHP'yi kolayca durma noktasına getirebilir.
Tek bir alanda birden çok nesnenin birleştirilmesi
Şimdiye dek, tek bir 3 boyutlu alandaki nesneleri teker teker gördük. Ama, burada durmamız gerekiyor. Liste 8 içinde, aynı alanda 100'den fazla nesnenin nasıl birleştirileceğinin bir örneği yer alır.
Daha önce de olduğu gibi, bu kod
Liste 1 içindeki,
$cone
nesnesini tanımlayan satırların yerine geçer.
Liste 8. Küre nesnelerinden birleştirilmiş bir kübün oluşturulması
for ($x=0; $x < 5; $x++) { for ($y=0; $y < 5; $y++) { for ($z=0; $z < 5; $z++) { $sphere = $world->createObject('sphere', array('r' => 25, 'detail' => 4)); $sphere->setColor(new Image_3D_Color(255, 255, 255)); $sphere->transform($world->createMatrix('Move', array($x * 75, $y * 75, $z * 75))); $sphere->transform($world->createMatrix('Rotation', array(45, 30, 15))); } } } $world->transform($world->createMatrix('Move', array(-225, -100, 0))); |
Liste 8, $x, $y ve $z'yi 0-4'ten artıran üç döngü tanımlar. Orta döngü içinde, tek bir küre nesnesi yaratılır.
Bir move
dönüştürmesi kullanarak, her bir yeni küre, başlangıç noktasına göre X, Y ve Z yönlerinde konumlandırılır. Taşındıktan sonra, her bir küre başlangıç noktasının çevresinde döndürülür.
Kürelerin her biri yaratıldıktan ve üç döngünün tümü de
tamamlandıktan sonra, $world
nesnesinin bütünü, görüntünün
sınırları içinde kürelerin ortalanacağı biçimde kaydırılır.
Bu örnekte 125 kürenin oluşturulduğuna dikkat edin. Detail ayarı 4 değerinde olan tek bir bir küre oluşturmakta zorlandıysanız, 124 tane daha küre oluşturmanın ne kadar güç olabileceğini tahmin edebilirsiniz. Detail değeri 4 ya da 5 olduğunda nesne gerçekten çok güzel görünür, ama herşeyin düzgün olarak çalıştığından emin oluncaya dek, bu ayarı 1 ya da 2'ye çekmeniz akıllıca olur.
Şekil 1 içinde gösterilen sonuçta ortaya çıkan görüntünün sadece küpler ve konilerden çok daha heyecan verici olduğunu kabul edersiniz.
Şekil 11. Küp şekilli bir matris yaratmak için düzenlenen 125 küre
Özel biçimler ve yüzeyler
Image_3D içinde daha özel nesnelerin oluşturulmasına olanak tanıyan iki nesne vardır: çokgenler ve eşlemler
3 boyutlu bir biçimin çok boyutlu koordinatlarda tasarlanabileceğini varsayarsak, bu koordinatları bir araya getirerek 3 boyutlu bir nesnenin kenarlarını oluşturabilirsiniz. Dikkatli bir hesaplamayla, noktalar ve çokgenler kullanarak sıfırdan küpler, koniler ya da küreler oluşturabilirsiniz. Ama bu nesneleri oluşturmanın daha kolay yolları da vardır.
Bunun yerine, üçüncü boyutu, yani derinliği olan üç noktalı bir yıldız oluşturalım. Yıldızın bir ön, bir de arka yüzü olacaktır, sonuçta bunlar, dış kenarları tanımlayan aynı koordinat noktalarına sahip olacaktır. Altı noktaya gerek vardır -- üçü yıldızın noktaları için, üçü de kenarları belirlemek için kullanılır. İşleri kolaylaştırmak için, Z=0 koordinatlarında yatan noktalar ön yüzünüz olsun. Arka yüz, ön yüze göre sabit bir uzaklıkta, 60 değer ötede olacaktır. Böylece, tüm dış noktalar aynı X ve Y koordinatlarına sahip olacaktır, ama Z koordinatı 60 olarak değiştirilecektir.
Üç kenar, yıldızın her bir dış noktasını birleştirecek biçimde eşlenir.
Liste 9'un çoğunluğu, bu nesnenin oluşturulması için birbirine bağlanması gereken noktaların yerleştirilmesiyle ilgilidir.
Aşağıdaki foreach
döngüleri, sonuçta ortaya çıkacak olan
çokgen nesnesini oluşturmakta kullanılacak olan
Image_3D_Point
nesnelerini oluşturmak için kullanılır.
Son satır $world
nesnesinin bütününü döndürür, böylece yıldızın kenarını görebilirsiniz. Alanı döndürmezseniz, yıldızın ön yüzünü yalnızca iki boyutlu olarak görürsünüz.
Liste 9. Üç noktalı yıldız oluşturulması
$polygons = array(); // Front face $polygons[] = array( array(0, -120, 0), array(-18, -12, 0), array(-86, 48, 0), array(0, 18, 0), array(86, 48, 0), array(18, -12, 0) ); // Back face $polygons[] = array( array(0, -120, 60), array(-18, -12, 60), array(-86, 48, 60), array(0, 18, 60), array(86, 48, 60), array(18, -12, 60) ); // 3 Sides $polygons[] = array( array(0, -120, 0), array(-18, -12, 0), array(-86, 48, 0), array(-86, 48, 60), array(-18, -12, 60),array(0, -120, 60) ); $polygons[] = array( array(-86, 48, 0), array(0, 18, 0), array(86, 48, 0), array(86, 48, 60), array(0, 18, 60), array(-86, 48, 60) ); $polygons[] = array( array(86, 48, 0), array(18, -12, 0), array(0, -120, 0), array(0, -120, 60), array(18, -12, 60),array(86, 48, 60) ); foreach ($polygons as $poly) { $points = array(); foreach ($poly as $set) { $points[] = new Image_3D_Point($set[0], $set[1], $set[2]); } $p = $world->createObject('polygon', $points); $p->setColor(new Image_3D_Color(255, 255, 255)); } $world->transform($world->createMatrix('Rotation', array(0, -25, -15))); |
Bu liste, Şekil 12 içinde gösterilen görüntüyü oluşturur.
Şekil 12. Image_3D paketi kullanılarak oluşturulmuş özel bir çokgen
3 boyutlu yüzeylerin eşlenmesi
Sıradaki iki örnekte ilginç bazı şekiller oluşturulur, ama biraz Calculus bilgisi de devreye girer. Hiç Calculus dersi almadıysanız ya da bu konudaki bilgilerinizi unuttuysanız, bu yazıda, körelmiş becerilerinizi bilemeye çalışmayacağız. Ancak, aşağıdaki modellerde neler olup bittiğine ilişkin temel bir fikir vermeye çalışacağız.
Mathematica yazılımıyla yüzeyleri ve kıvrımları tasarlama deneyiminiz varsa, sıradaki iki örnek size tanıdık gelecektir.
Bu iki listenin ilki yükselen bir sarmaldır. Yüzeydeki her bir noktanın, aşağıdaki parametrik fonksiyondan türeyen X, Y ve Z koordinatları vardır:
f[s,t] = {s * cos(2 ? t), s* sin(2 ? t), t} |
Bu yüzeyi yaratmak için, önce alanınızda yeni bir "eşlem" nesnesi yaratacaksınız.
$map = $world->createObject('map'); |
Eşlem, yukarıdaki özel çokgende gördüğünüz gibi 3 boyutlu bir yüzey oluşturmak için Image_3D_Point
nesnelerinin dizilimini alır. Bu noktaların her biri yukarıdaki işlevinize göre tanımlanabilir:
new Image_3D_Point( ($s * cos(2 * pi() * $t)), ($s * sin(2 * pi() * $t)), ($t) ); |
s
ve t
parametrelerini sırasıyla 0-1 ve 0-6 aralıklarında değiştireceksiniz.
Yüzeye uygun bir boyut vermek için, her bir koordinatı
$scale
ayarına atayacağınız istediğiniz bir değerle
çarpacaksınız.
Liste 10 içinde, eşlem nesnesinin nasıl oluşturulduğu gösterilir ve diğer örneklerde de olduğu gibi, nesnenin son halinin rengini, döndürmesini ve konumunu siz belirlersiniz.
Liste 10. Parametreleri belirlenmiş bir sarmal yüzey
$map = $world->createObject('map'); $scale = 120; $detail = 30; $levels = 6; $increment = 1 / $detail; for ($s = 0; $s <= 1; $s += $increment) { $row = array(); for ($t = 0; $t <= $levels; $t += $increment) { $row[] = new Image_3D_Point( $scale * ($s * cos(2 * pi() * $t)), // x $scale * ($s * sin(2 * pi() * $t)), // y $scale * ($t) // z ); } $map->addRow($row); } $map->setColor(new Image_3D_Color(255, 255, 255)); $map->transform($world->createMatrix('Rotation', array(-50, 0, 15))); $map->transform($world->createMatrix('Move', array(50, -220, 0))); |
Şekil 13 içinde sonuçta ortaya çıkan görüntü gösterilir. Helezonun
ayrıntı, ölçek ve yükseklik düzeyleri $scale
,
$detail
ve $levels
değişkenleriyle belirlenir.
Şekil 13. Image_3D paketinin eşlem nesnesi kullanılarak oluşturulmuş helezon
Stokes teoreminin bir uygulaması olan ikinci yüzey integraliniz de ilginç bir sonuç verir. Bu yüzeyi, Z ile ifade edilen yüksekliği değişken ve X ve Y düzlemlerinin başlangıç noktasından her yöne yayılan bir sinüs dalgasının ürünü olarak düşünebilirsiniz.
Calculus terimlerini bir yana bırakırsak, bu şeklin ortası delik bir kek kalıbına benzediğini söyleyebiliriz.
Bu alan, aşağıdaki parametrik işleve göre tanımlanacaktır:
f[r,t] = {r * cos(t), r * sin(t), sin(4 ? r)} |
Yine, bu yüzey için eşlem nesnesine eklenecek noktaları işaretleyeceksiniz. Her nokta Liste 11'de tanımlanır.
Liste 11. Noktaların tanımlanması
new Image_3D_Point( ($r * cos($t)), ($r * sin($t)), (sin(4 * pi() * $r)) ); |
Her bir noktayı, düzgün bir yüzey oluşturmak üzere r
ve t
parametrelerini değiştiren iki döngü içine saracaksınız. Liste 12'de gösterildiği
gibi, her X-, Y- ve Z koordinatı bir $scale
değeriyle çarpılacaktır.
Liste 12. 3 boyutlu ortası delik bir kek kalıbı şekli
$map = $world->createObject('map'); $scale = 130; $detail = 35; $increment = 1 / $detail; for ($r = 0; $r <= 1; $r += $increment) { $row = array(); for ($t = 0; $t <= (2 * pi()); $t += $increment) { $row[] = new Image_3D_Point( $scale * ($r * cos($t)), $scale * ($r * sin($t)), $scale * (sin(4 * pi() * $r)) ); } $map->addRow($row); } $map->setColor(new Image_3D_Color(255, 255, 255)); $map->transform($world->createMatrix('Rotation', array(-45, 0, -15))); |
Sonuçta ortaya çıkan görüntü şöyle olur:
Şekil 14. Image_3D paketindeki eşlem nesnesi kullanılarak geliştirilen parametrik işlevden oluşan 3 boyutlu yüzey
Ek çıktı sürücüleri
Şimdiye kadar yarattığınız tüm görüntüler GD sürücüsünü kullanıyordu. Bu sürücünün PNG görüntüleri oluşturduğunu gördünüz. Ancak kullanabileceğiniz dört ek sürücü daha vardır: SVG, SVGRotate, ZBuffer ve ASCII.
SVG (Scalable Vector Graphics; Ölçeklenebilir Vektör Grafiği) dosya biçimi, 2 boyutlu görüntüler oluşturan vektörlerin bir XML tanımıdır. W3C, bu biçimi 2001 yılında standartlaştırmıştır, ancak bu biçimin Web üzerindeki kullanımı, SVG dosyalarını görüntüleyebilen tarayıcıların kullanılabilir hale gelmesiyle engellenmiştir. Şu anda en uygun seçenekler SVG için yerleşik destek içeren Firefox V1.5 ve Adobe SVG eklentisine sahip Internet Explorer ürünleridir.
Image_3D'den SVG görüntüleri oluşturmak oldukça basittir. Yapılması gereken yalnızca Liste 1'deki son iki kod satırını aşağıdaki gibi değiştirmektir:
$world->createDriver('svg'); $world->render(400, 400, 'object.svg'); |
Sonuçta ortaya çıkan görüntü dosyası ilk yarattığınız koniye çok benzer olmalıdır.
SVG dosyalarının heyecan verici bir yönü, görüntüyü tanımlayan XML ağacının, JavaScript ve DOM ayrıştırma yordamları kullanılarak işlenebilmesidir. Görüntülerin, Web sayfalarını işlemek üzere dHTML kullanır gibi işlendiğini düşünün. SVGRotate sürücüsü, yalnızca bu amaçla gerekli olan komut dosyasını içeren bir SVG dosyası oluşturur.
Çıktı sürücüsünün değiştirilmesi yine son iki kod satırının değiştirilmesiyle kolay bir şekilde gerçekleştirilebilir:
$world->createDriver('svgrotate'); $world->render(400, 400, 'object.svg'); |
Sonuçta ortaya çıkan dosya, SVG biçimini tanıyan bir tarayıcıda görüntülendiğinde, koniyi gerçek zamanlı olarak döndürmek ve ölçeklemek için kullanılabilecek yerleşik denetimleri içerir. Görüntünün bir ekran görüntüsü aşağıda gösterilmiştir.
Şekil 15. SVGRotate sürücüsü görüntüyü gerçek zamanlı olarak işlemek için kullanılabilecek denetimleri ve komutları içerir.
Komut dosyası içeren SVG dosyaları sağlanan desteğin sınırlı olduğunu göz önünde bulundurun. Sonuçta ortaya çıkan dosya Adobe SVG eklentisi olan bir Internet Explorer'da çalışmasına karşın Firefox'ta düzgün görüntülenmemiştir.
3 boyutlu alanların 2 boyutlu bir görüntüye dönüştürülmesi için hangi nesnelerin üst üste gelip diğerlerini gizlediğini belirleyebilen özel bir algoritma gerekir. 3 boyutlu modellemede, nesnelerin 2 boyutlu bir alanda görünebilirliğinin yönetilmesine Z-buffering (Z-arabelleği) adı verilir.
Şimdiye kadar size verilen örneklerin hiçbirinde diğer nesnelerin üzerine gelen nesnelerle ilgili sorunlar yoktu. Böyle bir sorunla karşılaşırsanız, en uygun seçenek çıktı sürücünüzü GD'den ZBuffer'a değiştirmektir. ZBuffer sürücüsü bir PNG görüntüsü oluşturmak üzere hala GD'yi kullanır, ancak 2 boyutlu bir bit eşlem üzerinde çizili olduklarından 3 boyutlu nesneleri daha iyi yönetebilir.
Liste 13'teki kodu kullanarak, nesnelerin Z-buffering işleminde özellikle bir çakışmaya neden olacak, aynı alanı kaplayan iki nesne yaratacaksınız. Kürenin alfa şeffaflık değeri 150 olarak verilmiştir; böylece küreyi ortasından ikiye kesen düzlemi görebilirsiniz.
Liste 13. Küreyi kesen dört kenarlı bir düzlem
$sphere = $world->createObject('sphere', array('r' => 85, 'detail' => 4)); $sphere->setColor(new Image_3D_Color(255, 255, 255, 150)); $plane = $world->createObject('polygon', array( new Image_3D_Point(-120, 0, -120), new Image_3D_Point(-120, 0, 120), new Image_3D_Point( 120, 0, 120), new Image_3D_Point( 120, 0, -120) ) ); $plane->setColor(new Image_3D_Color(255, 255, 255)); $plane->transform($world->createMatrix('Rotation', array(15,15,-10))); |
Bu nesneyi GD sürücüsünü kullanarak oluşturursanız, aşağıda gösterildiği gibi, küre düzlemin önünde duruyormuş gibi görünür.
Şekil 16. GD sürücüsü kullanılarak ayrı ayrı oluşturulmuş üst üste gelen iki adet 3 boyutlu nesne
Ancak, yarattığınız düzlemin koordinatlarından, bunun kürenin içinden geçip küreyi kesmesi gerektiğini bilirsiniz. Sürücünün ZBuffer olarak değiştirilmesi bu sorunu çözer ve aşağıda gösterilen PNG dosyası ortaya çıkar.
Şekil 17. ZBuffer sürücüsü uygulanarak çözülen, üst üste gelmiş iki adet 3 boyutlu nesne arasındaki ZBuffer çakışmaları
Örneklerinizde ASCII sürücüsü bulunmamaktadır, ancak bu sürücünün amacı renkli bir ANSI uçbiriminde görüntülenecek görüntüler yaratılmasına olanak vermektir. Windows® kurulu bir PC'de çalışıyorsanız, bu sürücüden elde edilen çıktı büyük olasılıkla sizin için pek yararlı olamayacaktır.
Pratik örneklere geçiş
Şimdiye kadar gördüğünüz örnekler bu paketin PHP'de 3 boyutlu görüntüler oluşturma yeteneklerini göstermiştir. Web sayfalarını yönetmek için icat edilen bu dilin bu kadar ayrıntılı görüntü dosyaları oluşturmak üzere kullanılabileceğini kim tahmin edebilirdi? Bu oldukça iyi bir olanak, ancak 3 boyutlu sihirbaz ya da hesap meraklısı değilseniz bu size sıkıcı gelmiş olabilir. Basit nesneleri ve komut satırı komut dosyalarını alıp nasıl biraz daha ilginç örnekler oluşturabileceğinize bakalım.
3 boyutlu görüntülerin canlandırılması
GD grafik kitaplığı, GIF görüntülerini destekleme konusunda parçalı bir geçmişe sahiptir. Lisanslama sorunları nedeniyle, V1.6 yayın düzeyinden sonra GIF desteği GD'den kaldırıldı, ancak V2.0.28 yayın düzeyiyle yeniden kondu. Her durumda, Image_3D, canlandırmalı GIF'lerin dışa aktarılmasına izin vermez ve PNG dosyaları canlandırmayı desteklemez.
Döngülü bir canlandırma yürütecek tek bir dosya yaratmak yerine, bir "flip-book" etkisi yaratmak için birden çok dosyayı nasıl kullanabileceğinize bakalım. Örneği, 30 ayrı dosya oluşturarak kürelerden oluşan bir küp ile genişleteceksiniz. Arka arkaya görüntülendiğinde, ortaya çıkan canlandırma, kübü iki eksen üzerinde döner bir şekilde gösterecek.
Görüntülerin her birini oluşturmak için tek bir komut dosyası kullanacaksınız:
$cycles
.
Döngü için en dışta, her dosya için değişecek ancak ayrı ayrı dosyalar içindeki
her küreye uygulanacak üç dönüş değeri belirleyeceksiniz. Amacınız
canlandırmanın düzgün bir döngü içinde yürümesi olacağı için dönüşün 360
derecelik hareketlerle yürümesi gerekecek.
Y ekseni dönüşü için sabit bir dönüş değeri (30) ile başlayın. Buradan, sırada oluşturmakta olduğunuz dosyaya göre 360 derecelik bir döngü ile artış ekleyebilirsiniz. 360 derecelik bütün halindeki artışları gerçekleştirmek için modulus işleci kullanılır; bu durumda 375 derecelik bir dönüş 15 derece azaltılarak dönüşün ilk çevrimi içinde kalır.
$rot_y = (30 + (int) (360 / $cycles * $i)) % 360; |
Bu görüntüleri oluşturmanın en zor kısmı anlatıldı.
Kodun geri kalanı size tanıdık gelmeli. Bir $world
nesnesi yaratırsınız
ve buna iki ışık kaynağı verirsiniz. Üç döngü kullanarak, kürelerden oluşan kübü
yaratırsınız.
Oluşturduğunuz ilk küre kübü, boyut başına beş küp içeriyordu ve bunun için 125 adet 3 boyutlu nesne yaratılması gerekiyordu. Ayrıca bu görüntülerden 30 adet yaratıyorsunuz ve bu, 3.000'den fazla küre anlamına geliyor. Aşağıdaki kodda, kenar başına dört küre gelecek şekilde bir ölçek küçültmesi gerçekleştirdiniz ve her kürenin ayrıntı düzeyini üçe indirdiniz (bkz. Liste 14).
Liste 14. 30 adet "flip-book" sayfası oluşturulması
<?php require_once('Image/3D.php'); $cycles = 30; for ($i=0; $i < $cycles; $i++) { $rot_x = 45; $rot_y = (30 + (int) (360 / $cycles * $i)) % 360; $rot_z = (15 + (int) (360 / $cycles * $i)) % 360; $world = new Image_3D(); $world->setColor(new Image_3D_Color(255, 255, 255)); $light1 = $world->createLight(-500, 0, -500); $light1->setColor(new Image_3D_Color(255, 255, 0)); $light2 = $world->createLight(300, -300, -1000); $light2->setColor(new Image_3D_Color(255, 162, 0)); for ($x=0; $x < 4; $x++) { for ($y=0; $y < 4; $y++) { for ($z=0; $z < 4; $z++) { $sphere = $world->createObject('sphere', array('r' => 25, 'detail' => 3)); $sphere->setColor(new Image_3D_Color(255, 255, 255)); $sphere->transform($world->createMatrix('Move', array(($x * 75) + 50, $y * 75, $z * 75))); $sphere->transform($world->createMatrix('Rotation', array($rot_x, $rot_y, $rot_z))); } } } $world->transform($world->createMatrix('Move', array(-225, -100, 0))); $world->createRenderer('perspectively'); $world->createDriver('gd'); $world->render(800, 800, 'animated_png/anim' . ($i+1) . '.png'); } ?> |
Komut satırından kodu çalıştırın, sonra gidip kendinize bir bardak kahve yapın. Bu işlem biraz zaman alacaktır.
Bir sonraki adım tüm bu görüntülerin bir birine tutturulmasıdır. Bunu ilk
görüntüyü bir HTML sayfasında görüntüleyerek ve görüntü kümesi içinde bir görüntüden
diğerine geçmek için JavaScript'i kullanarak yapacaksınız. Sayfa üzerindeki
görüntüler arasında geçiş yapılması, Image nesnesinin src
özelliği değiştirilerek gerçekleştirilen standart bir tekniktir. Aşağıdaki
JavaScript örneğiniz, "flip-book" için gerekli görüntü dizilimini hazırlar, görüntüyü
değiştirmek için bir işlev tanımlar ve setInterval()
zamanlayıcısını
kullanarak animate()
işlevini yürütür.
Liste 15. "Flip-book" yaratmak üzere kullanılan HTML ve JavaScript
<html> <head> <title>Animated PNG</title> </head> <body> <script type="text/javascript"> var imageset = new Object(); imageset.seconds = 0.1; imageset.imgTag = "animation"; imageset.images = new Array(); for ($i=1; $i <= 30; $i++) { imageset.images.push('animation_01/anim' + $i + '.png'); } function animate(animObj) { if (!animObj.index) { animObj.index = 0; } animObj.index++; if (animObj.index >= animObj.images.length) { animObj.index = 0; } document.images[ animObj.imgTag ].src = animObj.images[ animObj.index ]; } document.write('<img src="' + imageset.images[0] + '" name="animation" />'); setInterval("animate(imageset);", imageset.seconds * 1000); </script> </body> </html> |
Ortaya çıkan canlandırma statik 3 boyutlu görüntülerinizi canlandırır.
Dinamik görüntülerin Web üzerinde görüntülenmesi
3 boyutlu görüntüler oluşturmanın zorluklarından biri, bunların yaratılması için çok fazla zaman, bellek ve işlemci çevrimi gerekmesi ve bu nedenle de bunların Web sitelerinde kullanım için uygun olmamasıdır. Bu sorunları çözmek için neler yapabilirsiniz?
Öncelikle, bu komut dosyalarını bir Web tarayıcısı üzerinden çalıştırmaya karar verirseniz, Image_3D paketinin görüntü dosyasını oluşturmayı bitirmesini beklerken sunucu bağlantısının zamanaşımına uğradığını görebilirsiniz. Komut dosyanızın en üstüne yakın bir yere aşağıdaki satırı ekleyerek PHP'nin maksimum yürütme süresini devre dışı bırakabilirsiniz.
set_time_limit(0); |
complex3-D görüntülerinin oluşturulması PHP'de çok fazla bellek harcayabilir.
Komut satırından çalıştırma sorun olmayabilir ancak bu komut dosyalarını bir kez Web
üzerinden çalıştırdığınızda yine sunucunuzun bağlantıyı kapattığını görebilirsiniz.
PHP komut dosyalarınıza yeterince bellek ayırdığınızdan emin olun. Genellikle,
php.ini dosyasında ya da yerel bir .htaccess dosyasında memory_limit
değerini değiştirebilirsiniz.
Tüm örneklerde, Image_3D, görüntüler yaratır ve bunları bir dosyaya kaydeder. Ancak dosyanın adı aşağıdaki iki PHP çıktı akışından biriyle değiştirilebilir:
- php://stdout
- php://output
Bir Windows sunucusunda test ettiğinizde bu yöntem başarısız olur, ancak GD sürümü de çıktı akışlarını düzgün desteklemiyor olabilir. Bu nedenle, bu yöntemle ilgili bir sorununuz varsa, görüntüyü dosyaya kaydetmeyi, dosyayı açıp içeriği çıktı arabelleğine aktarmayı deneyin. Bu en etkili çözüm gibi görünmese de, 3 boyutlu görüntüler oluşturduğunuzu unutmayın. Dosya giriş/çıkışı büyük olasılıkla bu komut dosyası için bir engel oluşturmayacaktır.
PHP'den bir görüntü dosyası oluştururken sunucunun yanıt üstbilgileri için
her zaman uygun içerik tipini eklemeyi unutmayın.
PNG görüntülerinde, aşağıda gösterildiği için image/png
değerini
kullanın:
header("Content-type: image/png"); |
Dinamik dosyaların önbelleğe alınması
Anında 3 boyutlu görüntüler oluşturma fikiri iyi olsa da, bir saat içinde komut dosyasında birkaç isabetten daha fazlasını yakalarsanız Web sunucunuzda büyük bir performans gerilemesi yaşayabilirsiniz. Bunu nasıl önleyebileceğinize ilişkin bir örneğin üzerinden geçelim.
3 boyutlu küre görüntüleri yaratan bir komut dosyanız olduğunu düşünün.
Bu komut dosyasının adı spheres.php olsun. Bu dosya yalnızca tek boyutlu ve tek renkli bir
küre yaratırsa bu pek yararlı olmayabilir.
Komut dosyasını her çağırdığınızda komut dosyasına iki parametre geçirdiğinizi
düşünün: Bu parametrelerden biri küre nesnesini yaratmak için
kullanılacak ve r
ile gösterilecek olan radius
(yarıçap)
parametresi olacak. İkinci parametre olan color
(renk) parametresi ise,
kürenin rengini vermek için dokuz basamaklı bir RGB değeri olacak. Aşağıdaki örnekte
bu komut dosyasını bir Web sayfasından nasıl çağırabileceğiniz gösterilmektedir:
<img src="sphere.php?radius=20&color=255000000" alt="Red ball" /> |
Küreyi oluşturmak için 5 ya da üzeri bir ayrıntı düzeyi kullandığınızı varsayarsak, büyük olasılıkla, Web sayfanıza gelen her ziyaretçi için görüntünün yeniden yaratılmasını engellemek isteyeceksiniz.
Kullanacağınız yaklaşım, yarattığınız her görüntü için, dinamik görüntüyü yaratmak üzere kullanılan iki parametreyi içeren biçimlendirilmiş bir dosya adı yaratmak olacaktır: örneğin sphere_20_255000000.png.
spheres.php komut dosyası her çağrıldığında, ilk önce isteği karşılayacak eşleşen bir görüntü dosyası olup olmadığına bakacaksınız. Böyle bir dosya varsa, dosyayı açın ve içeriği çıktı akışına aktarın. Böyle bir dosya yoksa, Image_3D nesnesini oluşturun, yeni görüntü dosyasını kaydedin, daha sonra dosyayı açıp içeriği çıktı akışına aktarın. İlk ziyaretçinin görüntüyü görmek için kısa bir süre beklemesi gerekebilir ancak sonraki ziyaretçiler önbelleğe alınmış olan versiyonu alacaklardır.
Ve sistem yöneticiniz sizi sevecektir!
Sonunda, doğrudan işinizde ve veritabanı uygulamalarınızda kullanılabilecek gerçekten düzgün bir Image_3D örneği göreceğiniz bir noktadasınız.
Image_3D, henüz anlatılmamış olan bir nesne tipini daha destekler: pasta grafik. Hemen konuya girelim ve üç boyutlu bir pasta diliminin nasıl görüneceğine bakalım. Her bir pasta dilimi farklı bir renkte olacak, bu nedenle beyaz nesneler ve renkli ışıklar yerine beyaz ışık ve renkli nesneler kullanacaksınız.
Liste 1'deki standart ortamınızda başlayın, ancak iki ışık kaynağını tek bir beyaz ışıkla değiştirin (bkz. Liste 16).
Liste 16. 45 derecelik mavi bir pasta grafik dilimi
$light = $world->createLight(0, 1000, 1000); $light->setColor(new Image_3D_Color(255, 255, 255)); $pie = $world->createObject('pie', array('start' => 0, 'end' => 45, 'detail' => 20, 'outside' => 150)); $pie->setColor(new Image_3D_Color(0, 0, 255)); $world->transform($world->createMatrix('Scale', array(1, 1, 10))); $world->transform($world->createMatrix('Rotation', array(-60, 0, 0))); |
Pasta nesnesinin yaratılması için, createObject()
yöntemine
geçirilen array
parametrenizde dört giriş gerekir. Start
ve end
,
dilimin başlangıç ve bitiş derecesi ölçülerini gösterir.
Bunlar 0 dereceden başlayarak ölçülür. Pastayı bir saat gibi düşünürsek, 0 derece
saat 3 konumunda yer alır ve açı ölçümü saat yönünde yapılır. Detail
değeri, nesne için bir düzgünlük düzeyi sağlar, outside
ise
dairesel pastanın göreli boyutunu gösterir.
Bu nesne üzerinde iki dönüşüm kullanırsınız. Ölçek dönüşümü, 10 değerine sahip bir Z-ekseni boyutu kullanarak, her bir dilime bir derinlik hissi vermek için kullanılır. X-eksenine uygulanan dönüş, pastayı iş grafiklerinde görülen tanıdık yönlendirmeye doğru eğer (Şekil 18).
Şekil 18. Tek bir pasta nesnesi
Pastaya dilim eklendikçe, bunların beklenmedik bir şekilde üst üste geldiklerini görebilirsiniz. GD sürücüsünü ZBuffer ile değiştirerek bu sorunu kolayca çözebilirsiniz.
Bir e-ticaret Web sitesi için müşteri kayıtlarını saklamak üzere Apache Derby veritabanını kullandığınızı varsayalım. Her bir müşteri kaydı, her bir posta adresinin ilini içerecektir. Hızlı bir SQL sorgusu, Liste 17'de gösterildiği gibi her bir ilde kaç müşterinin yaşadığını ortaya çıkaracaktır.
Liste 17. Farklı illerdeki müşteri kayıtlarının sayısının seçilmesi
SELECT COUNT( * ) AS customers, state FROM customers GROUP BY state ORDER BY customers DESC |
SQL sonuç kümesini bir HTML tablosuna dönüştürecek biçimlemeyi kolayca
oluşturabilirsiniz. Bu tabloya eşlik edecek güzel bir pasta grafik ekleyelim. Bu
örnekte, programınızın 3 boyutlu grafiği nasıl oluşturmasını istediğinize
ilişkin bir sınıf arabirimi tasarlayarak başlayalım. Her bir dilim bir bütünün
yüzdesi olarak tanımlanacak. Dilimleri HTML tablosundaki verilerle doğrudan
ilişkilendirmek istemeniz durumunda, her bir dilimin rengini belirleyebilirsiniz.
Son olarak, isteğe bağlı üçüncü bir parametre ana pastadan belirli dilimleri çekerek
çağırmanıza olanak verir ($slice->explode
); bkz. Liste 18.
Liste 18. 3 boyutlu bir görüntü oluşturmak için bir pasta grafik sınıfı kullanılması
<?php require_once 'pie_chart_class.php'; $chart = new PieChart(400, 400, array(255,255,255)); $chart->addSlice(15, array(255,0,0), true); $chart->addSlice(5, array(255,255,0), true); $chart->addSlice(35, array(0,255,0)); $chart->addSlice(30, array(0,255,255)); $chart->addSlice(15, array(0,0,255)); $chart->render('pie.png'); ?> |
Verilen yüzdeler yalnızca örnek verilerdir. Derby'den sonuç kümesini nasıl oluşturacağınız ve her bir müşteri sayısını tüm müşterilerin bir yüzdesine nasıl dönüştüreceğiniz konusuna değinmedik. Ancak bu, standart bir veritabanı işlemidir ve biraz da elinizdeki işle ilgili bir konudur.
Artık bir sınıf arabirimi örneğine sahip olduğunuza göre, sınıfı yaratarak
boşlukları doldurabilirsiniz. Bu sınıfla ilgili özel olarak ileri düzey bir
bilgi gerekmez. Dikkat edilmesi gereken tek ayrıntı, pastaya eklenen her dilimin
saat yönünde eklendiğidir. explode
özelliğinin true (doğru) olarak
ayarlandığı her dilim için, dilimi pastadan ayırmak üzere kullanacağınız X ve Y
ekseni yönlerini hesaplamanız gerekecektir (bkz. Liste 19).
Liste 19. 3 boyutlu pasta grafikler oluşturmak üzere kullanılacak PHP sınıfı
<?php require_once 'Image/3D.php'; class PieChart { private $slices; private $width; private $height; private $bg; private $world; public function __construct($width, $height, $bg_list) { $this->width = $width; $this->height = $height; $this->bg = $bg_list; } public function addSlice ($percent, $color_list, $explode=false) { $this->slices[] = new PieChart_Slice($percent, $color_list, $explode); } public function render ($filename) { $radius = round((min($this->width,$this->height) * 0.85) / 2); $world = new Image_3D(); $world->setColor(new Image_3D_Color($this->bg[0], $this->bg[1], $this->bg[2])); $light = $world->createLight(0, 1000, 1000); $light->setColor(new Image_3D_Color(255, 255, 255)); $start = 0; foreach ($this->slices as $slice) { $end = $start + $slice->degrees; $options = array('start' => $start, 'end' => $end, 'detail' => 20, 'outside' => $radius); $pie = $world->createObject('pie', $options); $color = new Image_3D_Color($slice->rgb[0], $slice->rgb[1], $slice->rgb[2]); if ($slice->explode) { $mid = $end - (($end - $start) / 2); $dx = cos(deg2rad($mid)) * ($radius * 0.15); $dy = sin(deg2rad($mid)) * ($radius * 0.15); $pie->transform($world->createMatrix('Move', array($dx, $dy, 0))); $color->addLight($color, 0.4); } $pie->setColor($color); $start = $end; } $world->transform($world->createMatrix('Scale', array(1, 1, 10))); $world->transform($world->createMatrix('Rotation', array(-60, 0, 0))); $world->createRenderer('perspectively'); $world->createDriver('zbuffer'); $world->render($this->width, $this->height, $filename); } } class PieChart_Slice { public $percent; public $rgb; public $degrees; public $explode; public function __construct($percent, $color_list, $explode=false) { $this->percent = $percent; $this->rgb = $color_list; $this->explode = $explode; $this->degrees = 360 * ($percent / 100); } } ?> |
Sonuçta ortaya çıkan grafik aşağıda gösterilmiştir:
Şekil 19. Kırmızı ve sarı renkli dilimleri ayrılmış bir pasta grafik
Özet
Image_3D, dinamik olarak görüntüler oluşturmak üzere PHP'de kolayca kurulup kullanılabilecek bir PEAR paketidir. Sınıf arabirimi, PHP V5 sürümüyle ilgilenmiş olan herkes için anlaşılması kolay bir öğedir. Pakete dahil olan tüm nesne tiplerini, ışıkları, renkleri ve dönüştürmeleri incelediniz. Ayrıca basit komut satırı komut dosyalarıyla nasıl daha karmaşık uygulamalar oluşturabileceğinizi ve bunları Web üzerinde kullanılabilir yapmak üzere yararlanabileceğiniz bir stratejiyi de gördünüz. Son olarak, müdürünüzün çok beğeneceği pasta grafiklerin yaratılmasına yardımcı olacak basit bir sınıf tasarladınız.
Örneklerin tümünü hemen kullanacak olmayabilirsiniz. Ancak bu paketin hala alfa sürümünde olduğunu unutmayın. Herhangi bir işlevin eksik ya da hatalı olduğunu görürseniz PEAR istek listesine bir istek gönderebilirsiniz.
Açıklama | Ad | Boyut | Karşıdan yükleme yöntemi |
---|---|---|---|
PHP 3 boyutlu kod örneği | os-php-3d.source.zip | 779KB | HTTP |
Bilgi Edinme
- PEAR:: Image_3D ürünü
hakkındaki bilgileri okuyabilir ve bu ürünü kurabilirsiniz.
- "Connecting
PHP Applications to Apache Derby" (PHP Uygulamalarının Apache Derby'ye
Bağlanması) başlıklı konuyu okuyarak pasta grafiği nasıl geliştireceğinizi
öğrenebilirsiniz.
- "Add
interactivity to your SVG" (SVG'nize etkileşim eklenmesi) başlıklı konuyu
okuyarak SVG görüntüleri ve komut dosyaları hakkında ek bilgi edinebilirsiniz.
- "Getting
started with objects with PHP V5" (PHP V5 ile nesnelere başlangıç) başlıklı konuyu
okuyarak PHP V5 nesne/sınıf sözdizimi konusundaki bilgilerinizi tazeleyebilirsiniz.
- Kartezyen koordinat sistemi hakkında ek bilgi edinmek için
Cartesian
coordinate system başlıklı sayfaya bakabilirsiniz.
- PHP ve gd kitaplığını kullanarak dinamik bit eşlem görüntüleri oluşturma
konusunda bilgi için Generate
dynamic bitmap graphics with PHP and gd" (PHP ve gd ile dinamik bit eşlem
grafikleri oluşturma) başlıklı konuyu okuyabilirsiniz.
- PHP'de nesne odaklı bir grafik katmanı oluşturma hakkında bilgi almak için
"Create
graphics the smart way with PHP" (PHP ile akıllı grafikler yaratma) başlıklı konuyu
okuyabilirsiniz.
- developerWorks
teknik
etkinlikler ve Web yayınları sayesinde güncel bilgiler edinebilirsiniz.
- developerWorks PHP
proje kaynaklarını ziyaret ederek PHP becerilerini artırabilirsiniz.
- developerWorks üzerine tüm
PHP
içeriğine göz atabilirsiniz.
- Açık kaynak teknolojileri konusunda kendinizi geliştirmenize ve bunları
IBM ürünleriyle kullanmanıza yardımcı olacak kapsamlı
nasıl yapılır bilgileri, araçlar ve proje güncellemeleri için developerWorks
Open
source zone (Açık kaynak bölgesi) sayfasını ziyaret edebilirsiniz.
Ürün ve teknoloji edinme
- Adobe's
SVG Viewer eklentisini bilgisayarınıza yükleyebilirsiniz.
- PHP komut dosyalarının yürütme süresini ölçmek için
PEAR::Benchmark karşılaştırmalı
değerlendirmesini kullanabilirsiniz.
- Bilgisayarınıza yükleyebileceğiniz ya da DVD'sini edinebileceğiniz
IBM
deneme yazılımı ile yeni açık kaynak geliştirme projenizde değişiklik
yapabilirsiniz.
Tartışma
- developerWorks web günlüklerine katılarak developerWorks topluluğuna erişebilirsiniz.
Mike Brittain, New York City'de Internet üzerinden tam kapsamlı pazarlama hizmetleri veren bir kuruluş olan ID Society'de teknoloji müdürüdür. 10 yılı aşkın bir süredir Web siteleri ve uygulamaları geliştirmekte olan Mike Brittain açık kaynak dilleri ve uygulamaları üzerine odaklanmıştır. Bilgisayarının başında olmadığında onu genellikle kayak ya da snowboard yaparken görebilirsiniz. Mike Brittain'a mike@mikebrittain.com adresinden ulaşabilirsiniz. |
Öhüm, şimdi de istek parçamız: Continuations and advanced flow control