Gönderen Konu: 3D Cube  (Okunma sayısı 21308 defa)

3D Cube

« : 15.12.2003 18:58:22 »
Hızlı düğmeleri aç

skate

İleti: 5.245

A Sinner Scener
Çevrimdışı
  • Administrator
  • *****
  • Hero Member
    • Profili Görüntüle
    • http://www.akaydin.com/
Bu çok klasik bir uğraşıdır. Her 3D ile ilgilenmeye başlayan ilk olarak küp çevirmek ister. Ancak programlama dili ve formülleri anlayamamaktan kaynaklanan ya da uygun örnekler bulunamadığı için yeni başlayanlara zor anlar yaşatabilir bu basit örnek. Burada herkesin çalıştırabilmesi için eskiden HTML+JavaScript ile yazdığım bir örneği koyuyorum. PHP bloğunda yer alan kısmı copy&paste ederek bir text dosyasına yazın ve uzantısını htm ya da html olarak rename edin. Sonra double-click ile çalıştırın. Hepsi bu.

Kod: [Seç]
<html>
<head>
<title>Cube3D Demo</title>
<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=windows-1254&quot;>
<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-9&quot;>
</head>
<body bgcolor=&quot;#000000&quot; text=&quot;#FF0000&quot; onResize=&quot;return false&quot; onContextMenu=&quot;return false&quot; onSelectStart=&quot;return false&quot; onScroll=&quot;return false&quot;>
<script>
// prepare layers
for(i = 0; i < 8; i++)
document.write(&quot;<div id='v&quot; + i + &quot;' style='position:absolute; left:0px; top:0px; width:30px; height:30px; z-index:1'><b style='font-size: 30px'>•</b></div>&quot;);

// define global variables
var firstCoorX = new Array(100, 100, 100, 100, -100, -100, -100, -100);
var firstCoorY = new Array(100, 100, -100, -100, 100, 100, -100, -100);
var firstCoorZ = new Array(100, -100, 100, -100, 100, -100, 100, -100);
var coorX = new Array();
var coorY = new Array();
var coorZ = new Array();
var zoom = 300, dist = 350;
var midX = 200, midY = 200;
var PI = 3.1415926535;
var angleXaxis = 0, angleYaxis = 0, angleZaxis = 0;

// rotate cube function
function rotateCube()
{
for(i = 0; i < 8; i++)
{
 // rotate on x axis
 coorY[i] = firstCoorY[i] * Math.cos(angleXaxis / 180.0 * PI) + firstCoorZ[i] * Math.sin(angleXaxis / 180.0 * PI);
 coorZ[i] = firstCoorY[i] * Math.sin(angleXaxis / 180.0 * PI) - firstCoorZ[i] * Math.cos(angleXaxis / 180.0 * PI);
 // rotate on y axis
 coorX[i] = coorZ[i] * Math.cos(angleYaxis / 180.0 * PI) + firstCoorX[i] * Math.sin(angleYaxis / 180.0 * PI);
 coorZ[i] = coorZ[i] * Math.sin(angleYaxis / 180.0 * PI) - firstCoorX[i] * Math.cos(angleYaxis / 180.0 * PI);
 // rotate on z axis
 temp = coorX[i];
 coorX[i] = coorX[i] * Math.cos(angleZaxis / 180.0 * PI) + coorY[i] * Math.sin(angleZaxis / 180.0 * PI);
 coorY[i] = temp * Math.sin(angleZaxis / 180.0 * PI) - coorY[i] * Math.cos(angleZaxis / 180.0 * PI);
}
// increase angles
angleXaxis = (angleXaxis + 1) % 360;
angleYaxis = (angleYaxis + 2) % 360;
angleZaxis = (angleZaxis + 3) % 360;
}

// projection and plot function
function setCube()
{
for(i = 0; i < 8; i++) // for every 8 vertex
{
 if(coorZ[i] + dist > 0) // if it is visible
 {
  px = coorX[i] / (coorZ[i] + dist) * zoom; // FORMULA: projection_x = x / (z + distance) * zoom
  py = coorY[i] / (coorZ[i] + dist) * zoom; // FORMULA: projection_y = y / (z + distance) * zoom
  document.all(&quot;v&quot; + i).style.left = midX + px; // FORMULA: vertex_position_x = center_of_the_area + projection_x
  document.all(&quot;v&quot; + i).style.top = midY + py; // FORMULA: vertex_position_y = middle_of_the_area + projection_y
 }
}
}

function cubeAnim()
{
rotateCube(); // rotate the cube
setCube(); // project and draw
setTimeout(&quot;cubeAnim()&quot;, 20); // call next frame after 20 miliseconds
}
cubeAnim(); // call the first frame
</script>
</body>
</html>

Umarım bu size yardımcı olur.

3D Cube

« Yanıtla #1 : 15.12.2003 23:40:15 »
Hızlı düğmeleri aç

vigo


  • Ziyaretçi
çok hoş eline saalık... ya ps2 demo cd sinde, YAM (yet another basic) diye bişi var, ps2 hardware i kullanarak basicde code yazıyosun... örnekte bi filled light-source cube var...
inceledim acaip bişi... çok akıllıca yapılmış..
yani hidden line olduu için, aslında ekranda sanki 3 face çizip fill ediyor, sanki sadece görünen noktalrı çizdiriyor gibi bişi... kağıta yazıp javascript yapcam belki bi işe yarar... ama sanırım sadece cube türü objeler için geçerli...

3D Cube

« Yanıtla #2 : 16.12.2003 10:12:22 »
Hızlı düğmeleri aç

skate

İleti: 5.245

A Sinner Scener
Çevrimdışı
  • Administrator
  • *****
  • Hero Member
    • Profili Görüntüle
    • http://www.akaydin.com/
Evet Vigo yalnızca görünen faceler çizdirilir genellikle. Kamera ile yüzeyin normalinin yaptığı açı hesaplanır. 90 dereceyi geçiyorsa yüzey çizdirilmez. şimdi çok vaktim yok. Bir ara örnek bir C codeum var, yollarım buralara. Cube harici tüm objeler için de işe yarıyor.

Cube için daha basit bir trick var gerçi benim c64'de yaptığım vektör partında kullandığım. Doğrudan facein rotasyonundan perspektifi yakalayacak kadar bir sayı değeri çıkarıyorsun. Çünkü 90 derceye gelmeden facein önüne perspektiften kaynaklanan başka bir face geçiyor. Örneğin 81 dereceyi geçtimi diye kontrol ediyorsun, geçtiyse çizdirmiyorsun. Sonuç bende kusursuzdu. Ancak bu sadece cube'de işe yarar. Piramit'e de benzer bir trick bulmuştum ancak bugları bir türlü temizleyemeyince adam akıllı hesaplattım yüzeyin normaliyle cameranın açısını. (Skate en doğru ve klasik yolu en son çare olarak kullanır. Optimizasyon manyaklığından mı? Hayır... Gerizekâlılığından.)

P.S: Javascript'te filled cube? VML? bence PHP'nin image fonksiyonlarını kullanarak refresh ede ede göstersen daha hızlı olur :) Hadi şaşırt beni.

Aklıma geldi de VML'de yaratılan polygonların vertexlerini çekiştirebiliyorduk istediğimiz gibi yanlış hatırlamıyorsam. Bu şekilde yapılması mümkün gibi evet...

3D Cube

« Yanıtla #3 : 16.12.2003 12:22:31 »
Hızlı düğmeleri aç

skate

İleti: 5.245

A Sinner Scener
Çevrimdışı
  • Administrator
  • *****
  • Hero Member
    • Profili Görüntüle
    • http://www.akaydin.com/
Cube'e bir iki yeni özellik ekledim...

Kod: [Seç]
<html>
<head>
<title>Cube3D Demo</title>
<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=windows-1254&quot;>
<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-9&quot;>
</head>
<body bgcolor=&quot;#000000&quot; onResize=&quot;return false&quot; onContextMenu=&quot;return false&quot; onSelectStart=&quot;return false&quot; onScroll=&quot;return false&quot;>
<script>
// prepare layers
for(i = 0; i < 8; i++)
document.write(&quot;<div id='v&quot; + i + &quot;' style='position:absolute; left:0px; top:0px; width:30px; height:30px; z-index:1'><b id='s&quot; + i + &quot;'>•</b></div>&quot;);

// define global variables
var firstCoorX = new Array(100, 100, 100, 100, -100, -100, -100, -100);
var firstCoorY = new Array(100, 100, -100, -100, 100, 100, -100, -100);
var firstCoorZ = new Array(100, -100, 100, -100, 100, -100, 100, -100);
var coorX = new Array();
var coorY = new Array();
var coorZ = new Array();
var zoom = 300, dist = 350;
var midX = 200, midY = 200;
var PI = 3.1415926535;
var angleXaxis = 0, angleYaxis = 0, angleZaxis = 0;
var hexN = new Array();
hexN[0] = &quot;0&quot;;hexN[1] = &quot;1&quot;;hexN[2] = &quot;2&quot;;hexN[3] = &quot;3&quot;;hexN[4] = &quot;4&quot;;hexN[5] = &quot;5&quot;;hexN[6] = &quot;6&quot;;hexN[7] = &quot;7&quot;;
hexN[8] = &quot;8&quot;;hexN[9] = &quot;9&quot;;hexN[10] = &quot;A&quot;;hexN[11] = &quot;B&quot;;hexN[12] = &quot;C&quot;;hexN[13] = &quot;D&quot;;hexN[14] = &quot;E&quot;;hexN[15] = &quot;F&quot;;

// rotate cube function
function rotateCube()
{
for(i = 0; i < 8; i++)
{
 // rotate on x axis
 coorY[i] = firstCoorY[i] * Math.cos(angleXaxis / 180.0 * PI) + firstCoorZ[i] * Math.sin(angleXaxis / 180.0 * PI);
 coorZ[i] = firstCoorY[i] * Math.sin(angleXaxis / 180.0 * PI) - firstCoorZ[i] * Math.cos(angleXaxis / 180.0 * PI);
 // rotate on y axis
 coorX[i] = coorZ[i] * Math.cos(angleYaxis / 180.0 * PI) + firstCoorX[i] * Math.sin(angleYaxis / 180.0 * PI);
 coorZ[i] = coorZ[i] * Math.sin(angleYaxis / 180.0 * PI) - firstCoorX[i] * Math.cos(angleYaxis / 180.0 * PI);
 // rotate on z axis
 temp = coorX[i];
 coorX[i] = coorX[i] * Math.cos(angleZaxis / 180.0 * PI) + coorY[i] * Math.sin(angleZaxis / 180.0 * PI);
 coorY[i] = temp * Math.sin(angleZaxis / 180.0 * PI) - coorY[i] * Math.cos(angleZaxis / 180.0 * PI);
}
// increase angles
angleXaxis = (angleXaxis + 1) % 360;
angleYaxis = (angleYaxis + 2) % 360;
angleZaxis = (angleZaxis + 3) % 360;
}

// projection and plot function
function setCube()
{
for(i = 0; i < 8; i++) // for every 8 vertex
{
 if(coorZ[i] + dist > 0) // if it is visible
 {
  px = coorX[i] / (coorZ[i] + dist) * zoom; // FORMULA: projection_x = x / (z + distance) * zoom
  py = coorY[i] / (coorZ[i] + dist) * zoom; // FORMULA: projection_y = y / (z + distance) * zoom
  document.all(&quot;v&quot; + i).style.left = midX + px; // FORMULA: vertex_position_x = center_of_the_area + projection_x
  document.all(&quot;v&quot; + i).style.top = midY + py; // FORMULA: vertex_position_y = middle_of_the_area + projection_y
  document.all(&quot;s&quot; + i).style.fontSize = (300 - coorZ[i]) / 5;
  document.all(&quot;s&quot; + i).style.color = &quot;#&quot; + conv2Hex(parseInt((550 - coorZ[i]) / 3, 10)) + &quot;0000&quot;;
 }
}
}

// convert decimal to hex
function conv2Hex(decval)
{
leftval = parseInt(decval / 16, 10);
rightval = decval % 16;
hexval = hexN[leftval] + hexN[rightval];
return hexval;
}

// main routine
function cubeAnim()
{
rotateCube(); // rotate the cube
setCube(); // project and draw
setTimeout(&quot;cubeAnim()&quot;, 20); // call next frame after 20 miliseconds
}
cubeAnim(); // call the first frame
</script>
</body>
</html>

3D Cube

« Yanıtla #4 : 16.12.2003 23:24:16 »
Hızlı düğmeleri aç

vigo


  • Ziyaretçi
hehe süper ya...
zaten sen bu konuda bikeresinde bizim evde çok güzel örnekler yapmıştın... bu şekilde javascript based örnekler, en azından kendi adıma, çok işime yarıyor... saolasın skate kardeşim...
bende araya VML line çızdıriimmi? :))

3D Cube

« Yanıtla #5 : 17.12.2003 00:04:05 »
Hızlı düğmeleri aç

skate

İleti: 5.245

A Sinner Scener
Çevrimdışı
  • Administrator
  • *****
  • Hero Member
    • Profili Görüntüle
    • http://www.akaydin.com/
Elbette ki.. Geliştirip geliştirip yeni version atabilir herkes buraya. Ancak benim yöntemim öküzlük biraz. Attachment olarak yolliicam bundan sonra :)