December 12, 2021

Merhaba,

Bugün, 3 boyutlu dünyamızda kanlı ve canlı olarak bir D buluşması tertipledik. Caddebostan sahilde 3 arkadaşımla Caffè Nero'da (reklamsız olmaz 😀) hoş bir görüşme yaptık. Ayrıntıları ve ilgili duyuruyu burada bulabilirsiniz...

Ama dikkat! Şeref konuğumuz D Programlama Dili Kitabı yazarı Ali Çehreli olması konunun önemini katlıyor. Üstelik bu sefer, her ay yaptığımız (evet, bu ay 5 Aralıkta olacaktı) Zoom toplantılarından kat ve kat verimli olması önemini arttırıyor. Ayrıca D'nin Türkiye'de yaygınlaştırılmasına yönelik bazı fikirler ortaya çıktı...

Evet, hedeflerimizi 2 boyuttan 3. boyuta geçirmek elimizde. Bu toplantılarının sayısını arttırmak dileğiyle. Neden böyle uzun bir giriş yaptığıma gelince; cevabı basit:

3 boyutlu dünyaya girmek için!

Çünkü insan, yazdığı kodları, sanal da olsa gözünün önünde kanlı/canlı görmek istiyor! Şimdilik giriş niteliğinde aşağıdakiler ile yetinelim. Sonlarda ve 2. bölümde sizi çok bekletmeden harika bir olanağa (D'de Arayüzler - Interfaces in D) gireceğiz:

/** Bir ekranda, tamsayı değerinde (örn. short) 2 değişken ile **/

struct Nokta {
  short x, y;
}
/** gibi bir yapı tanımlamak, 2 boyutlu dünya için yeterlidir. **/

struct Çizgi {
  Nokta a, b;
}
/** Ancak 3 boyutlu bir dünyada, yukardaki yapıdan ikisini birden
    kullanmaya ihtiyaç var. Bu da yetmez, hesaplama yapmak için**/

struct ÜçBoyutluDünya {
  double x, y, z;  // belki float bile yeterli, ne dersiniz?
}
/** şeklinde temel veri tutan bu yapıya ihtiyaç var ama Z-ekseni
    sanki yokmuş gibi aktarmak zorundayız. Çünkü üçünü 2 boyutlu
    dünyada gösteremezsiniz. Bu nedenle Çizgi şöyle kurulur:   **/

  this(ÜçBoyutluDünya a, ÜçBoyutluDünya b) {
    this.a.x = cast(short)a.x;
    this.a.y = cast(short)a.y;
    this.b.x = cast(short)b.x;
    this.b.y = cast(short)b.y;
  }
/** Çizgi(ler) bize 3 boyutlu dünyayı verirler. Tabi sanal olarak
    çünkü zihnimiz bize derinliği olan bir cisim oradaymış gibi 2
    şekilde oyun oynar. Bu 2 hissiyata sonra değineceğiz ancak
    kod yazarken, şekilleri gerçek dünyadaki gibi döndürmek çoğu
    zaman işlerimizi kolaylaştırır. Devam edersek:             **/

class Şekil : Arayüz {
  ÜçBoyutluDünya[] noktalar;

  this(ÜçBoyutluDünya koordinat, double büyüklük) {
    // Olasılıklar uzayında noktalar (en az 8 nokta) tanımlanır
  }

  abstract void dönüştür();  // Arayüzü kullanmak için gerekli

  void döndür(int açısı, Boyut boyutu) {
    // cos() ve sin() hesaplamaları burada yapılır
  }
}
/** Yukardaki özet sınıf görüntüsü, başlangıç için yeterli ve
    öncesindeki yapıları akıllıca birleştirerek sınırsız adet
    şekil çizmek mümkün. Örneğin bunlardan 3'ü şu şekildedir:  **/

class Küp : Şekil, Arayüz  {
  Çizgi[12] kenarlar; // Bu şekil için 12 çizgi yeterli

  this(ÜçBoyutluDünya konum, double büyüklük {
    super(konum, büyüklük);
  }

  override void dönüştür() {
    // Şeklin en az çizgiyle temsil edilen hali
  }
}

class Piramit : Şekil, Arayüz  {
  Çizgi[8] kenarlar; // Bu şekil için 8 çizgi yeterli

  this(ÜçBoyutluDünya konum, double büyüklük {
    super(konum, büyüklük);
  }

  override void dönüştür() {
    // Şeklin en az noktayla temsil edilen hali
  }
}

class Dörtyüzlü : Şekil, Arayüz  {
  Çizgi[6] kenarlar; // Bu şekil için 6 çizgi yeterli

  this(ÜçBoyutluDünya konum, double büyüklük {
    super(konum, büyüklük);
  }

  override void dönüştür() {
    // Şeklin en az çizgiyle temsil edilen hali
  }
}
/** Son olarak 2 şeye daha ihtiyacımız var: Yardımcı tür Çizici
    sınıf ve bir de arayüz. Çünkü şekiller ve bunları oluşturan
    noktaların birbirlerinden haberdar olması gerekiyor. Şöyle:**/

interface Arayüz {
  void dönüştür();
}

class Çizici {
  Dörtyüzlü[] şekiller;

  void çiz() { /* ... */ }
}

Not: Sonraki bölümde derleyebileceğiniz bir örnek olacak ve bu örnek ekrana henüz hiçbir şey çizmeyecek ama çizme potansiyeline halihazırda sahip olacak. Üçüncü bölümde ise Adam D. Rupp'un arsd.simpledisplay kütüphanesini örneğimize dahil edeceğiz. Sonrasıda şov başlasın 😀

Başarılar...

December 14, 2021

On Sunday, 12 December 2021 at 20:43:06 UTC, Salih Dincer wrote:

>

/** Son olarak 2 şeye daha ihtiyacımız var: Yardımcı tür Çizici
sınıf ve bir de arayüz. Çünkü şekiller ve bunları oluşturan
noktaların birbirlerinden haberdar olması gerekiyor.

Küçük bir düzeltme:

Aslında interface Arayüz {} oluşturmaya hiç de ihtiyacımız yokmuş abstract keywordü ile ana sınıfımızı kurmanız ve alt sınıflardakini tanıtmanız yeterliymiş Ayrıca kenarlar[] dizisini kenar() işleviyle kapsüllemem gerekti:

abstract class Şekil {
  Çizgi[] kenar();
  void dönüştür();
//...

Bu sayede gereksiz kalabalıktan kurtulmuş ve farklı isimdeki sınıfıları tek bir dizide (Şekil[]) toparlamayı mümkün kıldık:

class Çizici {
  Şekil[] şekiller;
//...

Tabi bir şartla, işlev olmayan üyelere erişmek mümkün olmuyor o yüzden şöyle bir kapsüllemeye ihtiyacımız var:

//...
  override Çizgi[] kenar() {
    return kenarlar;
  }
}

Kodun çalışır devamı şurada: https://forum.dlang.org/thread/mrtmtousnglptijjvzqc@forum.dlang.org