Jump to page: 1 2 3
Thread overview
İşleç yükleme
Jun 03, 2011
erdem
Jun 03, 2011
erdem
Jun 03, 2011
erdem
Jun 04, 2011
erdem
Jun 04, 2011
erdem
Jun 04, 2011
erdem
Jun 04, 2011
erdem
Jun 04, 2011
erdem
Jun 04, 2011
erdem
Mar 04, 2012
Salih Dinçer
Mar 04, 2012
Salih Dinçer
Mar 05, 2012
Salih Dinçer
June 03, 2011
struct Vector2
{
   float x, y;

   this (float x, float y)
   {
       this.x = x;
       this.y = y;
   }

   /*
     operatörlere farklı görev yükleme
   */
   Vector2 opMul(ref const Vector2 soldaki, float sağdaki)
   {
       // ?? Vector2 sonuç(soldaki)
       Vector2 sonuç = soldaki;
       sonuç *= sağdaki;
       return sonuç;
   }

   Vector2 opMul(float soldaki, ref const Vector2 sağdaki)
   {
       Vector2 sonuç = sağdakih;
       sonuç *= soldaki;
       return sonuç;
   }

   Vector2 opMulAssign(ref const float sağdaki)
   {
       x *= sağdaki;
       y *= sağdaki;
       return this;
   }


   Vector2 opAddAssign(ref const Vector2 sağdaki)
   {
       x += sağdaki.x;
       y += sağdaki.y;

       return this;
   }

   /*
     bu vektöre dik bir vektör döndürür
    */
   Vector2 dik() const
   {
       return Vector2(y, -x);
   }

   /*
     skaler çarpımı (dot product) hesaplar
    */
   float skalerÇarpım(ref const Vector2 v2) const
   {
       return x * v2.x + y * v2.y;
   }

   /*
     bu vektörün tersi olan vektörü bulur
   */
   Vector2 tersiniBul() const
   {
       return Vector2(-this.x, -this.y);
   }

   /*

   void yansıt(ref const Vector2 normal)
   {
       this += 2.0 * this.skalerÇarpım(normal) * normal.tersiniBul();
   }
   */
}

unittest
{
	/*
		bu şekilde atama yapamıyoruz sanırım
		Vector2 ikinci(Vector2(1, 1);
	*/
	auto ilk = Vector2(2, 2);
	auto ikinci = Vector2(-3, -3);
	ilk = ilk.tersiniBul();
	assert(ilk == Vector2(-2, -2));
	float sayı = -1.0;
	ilk *= sayı;
	assert(ilk == Vector2(2, 2));
	ilk = 2.0f * ikinci;

}

void main()
{
}

Yukarıdaki birim testinde en alttaki ifade 'no property 'opMul_r' for type 'float'' diye bir hata veriyor. Ayrıca C++'de olduğu gibi () arasında atama yapamıyoruz galiba. Gene yansıt işlevi de yorum kaldırılınca hata veriyor.

Digitalmars'ın dökümanlarına baktım ama gene çoğu zaman olduğu gibi pek bir şey anlamadım <_<

Biraz da tembellik ederek daha TDLP'ye bakmadan yazdım :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 03, 2011

Tamam şimdi TDPL'ye bakınca buldum. Baya ilginçmiş.

Andrei örneklerde de şablon kullanmış :) Aslında işe yarayan bir özellik.

Ama şimdilik basitçe şunun gibi olması gerekiyor sanırım. Örneğin += operatörünü yüklediğimiz zaman:

import std.stdio;

struct Vector2
{
   float x, y;

   this (float x, float y)
   {
       this.x = x;
       this.y = y;
   }

   ref Vector2 opOpAssign(string op)(Vector2 sağdaki)

   if (op == "+") {
       x += sağdaki.x;
       y += sağdaki.y;
       return this;
   }
}

void main()
{
   auto ilk = Vector2(2, 2);
   ilk += Vector2(3, 3);
   assert(ilk == Vector2(5, 5));

}

Yukarda yazdığım örneklerin tamamı geçersiz hale gelmiş deprecated anladığım kadarıyla.. Bu yukarda 'opOpAssign' şeklinde yazdığım gruba atama operatörleri giriyor. 'a = b a += b' ve 'a *= b' gibi..

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 03, 2011

Çok teşekkürler! :)

Artık birim testlerini uzun uzun yazarım. Bu arada birim testleri aslında tek tek her modül için ayrı yapmak daha mantıklı galiba. Öbür türlü benim yaptığım gibi çorba gibi oluyordu :-D Bir taraftan program çalışıyor bir taraftan birim testleri kendi aralarında takılıyorlar.

Bu gün rastgele gezerken Andrei'nin nasıl birim testleri yazdığını gördüm. Bu bana iyi bir fikir verdi:

http://bit.ly/mBUDn8

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 03, 2011

Ben sabah yazacak zaman bulamadım ve işe gelirken uğraştım.

Alıntı (erdem):

>
>     Vector2 opMul(ref const Vector2 soldaki, float sağdaki)
>     {
>         // ?? Vector2 sonuç(soldaki)
>         Vector2 sonuç = soldaki;
>         sonuç *= sağdaki;
>         return sonuç;
>     }
> ```


O işlevlerin yalnızca float alması gerekiyor. Çünkü 'soldaki' nesne aslında 'this' nesne:


ref Vector2 opMulAssign(const float sağdaki)
{
x *= sağdaki;
y *= sağdaki;
return this;
}

Vector2 opMul(float sağdaki) const
{
Vector2 sonuç = this;
sonuç *= sağdaki;
return sonuç;
}



yansıt'la fazla uğraşmadım ama sağ tarafı ayırınca çalışıyor:


void yansıt(ref const Vector2 normal)
{
auto eklenen = 2.0 * this.skalerÇarpım(normal) * normal.tersiniBul();
this += eklenen;
}



İşleç yüklemenin yeni yazımının kolaylığı, olabilen durumlarda birden fazla işlecin tek işlevle tanımlanabilmesi:


struct Vector2
{
double x;
double y;

ref Vector2 opOpAssign(string işleç)(double sağdaki)
{
mixin("x " ~ işleç ~ "= sağdaki;");
mixin("y " ~ işleç ~ "= sağdaki;");
return this;
}

Vector2 opBinary(string işleç)(double sağdaki)
{
Vector2 sonuç = this;
sonuç.opOpAssign!işleç(sağdaki);
return sonuç;
}

Vector2 opBinaryRight(string işleç)(double soldaki)
{
return this.opBinary!işleç(soldaki);
}
}



mixin garip oluyor ama yukarıdaki 3 tanım çoğu ikili işleç için galiba doğru. (Ama "double / Vector2" gibi durumlar tabii ki yanlış olur.)

Ali

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
June 04, 2011
import std.stdio;

struct Vector2
{
   float x, y;

   this (float x, float y)
   {
       this.x = x;
       this.y = y;
   }

   // vector2 * sayı
   Vector2 opBinary(string işleç)(const float sağdaki)
   if (işleç == "*")
   {
       auto sonuç = this;
       this *= sağdaki;
       return this;
   }

   // sayı * vector2
   Vector2 opBinaryRight(string işleç)(const float soldaki)
   if (işleç == "*")
   {
       return this.opBinary!(işleç)(soldaki);
   }

   /*
     atama işleçleri
   */

   // vector2 = vector2
   ref Vector2 opAssign(const ref Vector2 sağdaki)
   {
       x = sağdaki.x;
       y = sağdaki.y;
       return this;
   }

   // vector2 *= sayı
   ref Vector2 opOpAssign(string işleç)(const float sağdaki)
   if (işleç == "*") {
       x *= sağdaki;
       y *= sağdaki;
       return this;
   }
}

unittest
{
   auto birinci = Vector2(1, 2);
   auto ikinci = Vector2(3, 3);
   auto sayı = 4.0f;

   Vector2 sonuç = birinci *= 3;
   assert(sonuç == Vector2(3, 6));
   // BUG *
    assert(birinci == Vector2(1, 2));
}

Burada bir hata var. Ama kafam karıştı galiba. Bir türlü nerede ilk değeri de değiştirdiğini göremedim :huh:

Çok güzel çalışan programımız BUG kısmına gelince patlıyor! :-D

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 04, 2011

Alıntı (erdem):

>
>
>     // vector2 * sayı
>     Vector2 opBinary(string işleç)(const float sağdaki)
>     if (işleç == "*")
>     {
>         auto sonuç = this;
>         this *= sağdaki;
>         return this;
>     }
> ```

>

Sabahtan beri bunla uğraşıyordum. Bazen kafa basmıyor  :-D Burada kod this'i değiştiriyormuş. Doğrusu şu şekilde olacak:

   auto sonuç = this;
   sonuç *= sağdaki;
   return sonuç;
Alıntı (erdem):
>
>
>
Vector2 sonuç = birinci *= 3;
>

Burada da doğal olarak 'birinci *= 3' birinciyi değiştirecek. Bunun doğrusu da sadece 'birinci *= 3;' oluyor.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 04, 2011

Alıntı (acehreli):

>
  • Ben özel bir nedeni yoksa float yerine double kullanıyorum.

Aslında XNA da doğal sayı türü olarak float kullanılmış. Ben de konunun tam ayrıntılarını bilmiyorum ama sanki bir yerlerde GPU(Grafik İşlemci Birimi) 'float' sayılar için optimize edilmiştir türünden bir şeyler okumuştum. O yüzden 'float 'kullanayım diye düşündüm.

Alıntı (acehreli):

>

Tabii belki de en iyisi gerçekleştirme türünü ve hatta boyutu bile parametre olarak almaktır:

> struct Vector(T, int boyut)
> {
>     T[boyut] elemanlar;
> }
> ```

>


struct Vector2(T, int boyut)
{
T[boyut] elemanlar;
}

void main()
{
auto birVektör = Vector2!(float, 3)(4, 4);
}



Burda boyutun nasıl kullanılacağını anlamadım. Amacımız iki noktanın koordinatını tutmak olduğuna göre şöyle yazmazmıydık:


struct Vector2(T)
{
T x, y;
}

void main()
{
auto başkaVektör = Vector2!(float) (2, 3);
}



Aslında bunu düşündüm. Örneğin hem bir 'ushort' hem de 'float' türünde Vector2 gerekebiliyor. Ama bu şekilde her seferinde yazım biraz uzun olur ve kullanıcının kafasını karıştırır mı diye çekincede kaldım. Artık ilerde belki tamamen bu hale getirebilirim :)

Alıntı (acehreli):
>
> - Yapılar değer türleri olduklarından dil bize çok yardımcı oluyor; bizim bazı durumlarda özel işlemler yapmamıza gerek kalmıyor. Örneğin bu tür için opAssign(Vector2)'yi yazmaya aslında gerek yok
>

Çok teşekkürler. Bunu öğrendiğim iyi oldu :)

Alıntı (acehreli):
>
> Onun için şablon kısıtlamalarıyla küçük bir deney yaptım. std.algorithm.canFind, bir elemanın bir aralıkta bulunup bulunmadığını bildiriyor.
>

Bu kısmı pek anlamadım  :huh:  Biraz açabilirmisiniz.

Yorumlar için teşekkürler! :)

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
June 04, 2011

Alıntı (erdem):

>

Ama bu şekilde her seferinde yazım biraz uzun olur ve kullanıcının kafasını karıştırır mı diye çekincede kaldım.

Ama 'alias' kullanarak böyle kısaca yazılabiliyor :) En çok kullanılan değer Vector2 olduğu için böyle basit bir 'alias 'kullanarak yazılabiliyor. Ama alias şablonlarla problem çıkarır mı bilmiyorum.

struct Vector(T)
{
   T x, y;
}

alias Vector!(float) Vector2;


void main()
{
   auto konum = Vector2 (2, 3);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 04, 2011

Teşekkürler! :)

Şimdilik son hali şunun gibi olmuş oldu:

http://bit.ly/mcEaFu

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 04, 2011

Alıntı (acehreli):

>

(Şuradaki "Atama işleci ile kullanılan nitelik işlevleri" başlığında bir örnek var: http://ddili.org/ders/d/nitelikler.html)

O yüzden bence uzaklık() @property olmasa daha uygun.

  1. tersiniBul() yerine tersi() daha iyi bir isme benziyor. Hatta işte bu bir @property olabilir galiba.

Zaten o dersi okuduktan '@property' yapmıştım. Ama haklısınız bu değişiklikleri yaptım bile :)

Alıntı (acehreli):

>
  1. Aslında önceden olduğu gibi türün ismi Vector2 olmalı, çünkü iki noktası var. Yani "2'liğini" şu alias vermiyor:
> alias Vector!(float) Vector2;
> ```

>

Haklısınız ama hem mantıklı bir isim bulamadım. Hem de kodun her yerindeki Vector2'leri değiştirmem gerekecek. O yüzden şimdilik böyle yazdım.

Bu arada isterseniz *github*'da da *mentor* olarak yorum yazabilirsiniz :)

Ama tabi bu şekilde forumu takip eden herkes izlemiş oluyor.

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
« First   ‹ Prev
1 2 3