Dropbox’a CokgenDeneme3’ün altına programın son halini ekledim.

En önemli yenilik iki nokta verip üçüncü noktayı açı ve uzaklıkla yaratmak. Bu bize sadece iki nokta ve kenar sayısı vererek yeni bir düzgün çokgen yaratma imkanı sağlıyor.

İki nokta verip üçüncü nasıl yaratılır ile ilgili detaylar şöyle:

Öncelikle birinci sorunumuz verilen iki noktanın arasındaki açının hesabı. Bunu yapmak için arctan kullanırız. İki noktanın y‘lerinin arasındaki farkı x‘lerinin arasındaki farka bölüp bu rakamın arctan’ını alınca açı bulunur. Fakat arctan’ın bazı sorunları var. Örneğin iki noktanın x’leri aynı olabilir ve bu da bize sonsuz bir değer verir.

Sadece bu da değil. Başka sorunlarda var. O yüzden bu sorunlardan kurtulmak için 4 + 2 durumu ayrı ayrı değerlendirdik. Öncelikle birinci durum. Aşağıdaki resimde eksenlerin çizildiği merkez birinci noktam (programın içinde this dediğim) diğer nokta ise p noktası ise ve eğer p noktası this‘e göre sağ yukarıda kalıyorsa o zaman bir sorun yok. Formülümü kullanabilirim.

Diğer konum ise p noktasının sol üstte olması hali. O zaman dx negatif oluyor. Bu halde ben arctan’ın için dx‘i pozitif yapacak şekilde koyuyorum ve çıkan sayıyı PI’den çıkartıyorum.

Üçüncü durum p noktasının sol alt tarafta olması. Yani hem dx hem de dy negatif. Durum böyle olunca yapmam gereken çıkan sayıya PI eklemek.

Son durumda ise p noktası bana göre sağ altta. Böyle olunca dx pozitif ama dy negatif oluyor. O zaman da arctan’ın içine pozitif değer versin diye bir “-” koyuyorum ve çıkanı 2PI’den çıkartıyorum.

Programın ilgili kısmını aşağıya kopyalıyorum. Unutmayın bu metod Nokta class’ının içinde.

 /**
   * Bu nokta ile verilen p noktasi arasindaki aciyi verir. Su anda
   * gereksiz bir suru adim iceriyor. Daha sonra kisaltilacak.
   * @param p bu nokta ile arasindaki acinin hesaplanacagi nokta
   */
  public float aci(Nokta p) {
    float dx = p.getX() - x;
    float dy = p.getY() - y;
    float aci = 0;
    // sag ust kisimda oldugu zaman
    if (dx > 0 && dy >= 0)
      aci = atan(dy / dx);
    // sol ust kisimda oldugu zaman PI'den cikartmak lazim
    if (dx < 0 && dy >= 0)
      aci = PI - atan(abs(dy/dx));
    // sol alt tarafta oldugu zaman PI ile toplamak lazim
    else if (dx < 0 && dy < 0)
      aci = PI + atan(dy/dx);
    // sag alt tarafta ise 2PI'den cikartmali.
    else if (dx > 0 && dy < 0)
      aci = TWO_PI - atan(abs(dy/dx));

    // eger dx = 0 ise o zaman yukaridaki (dy/dx) formulu sonsuz olur
    // o yuzden bu durumu ayrica degerlendiriyoruz.
    else if (dx == 0 && dy > 0)
      aci = PI/2;
    else if (dx == 0 && dy < 0)
      aci = 3*PI/2;

    return aci;
  }

Kodun içinde gördüğünüz gibi diğer iki durum ise dx‘in sıfır olduğu ve dy‘nin sıfırdan büyük ve sıfırdan küçük olduğu iki durum. Bu durumları da yine aynı else if komutlarıyla çözdüm.