25 Şubat 2007

İki doğru arasındaki açıyı bulan program

Delphi'de hazırladığımız bir projenin küçük bir parçasının algoritmasını test etmek için hazırladığım bir program

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, Math;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject;
      Button: TMouseButton; Shift:
      TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  noktasay: byte;
  x1,y1,x2,y2: integer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  noktasay :=0;
end;

procedure TForm1.FormMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  ab,bc,ac,x3,y3 : integer;
  aci : real;
begin
  noktasay:=succ(noktasay);
  if (noktasay>3) then noktasay:=1;
  if (noktasay=1) then
  begin
    //Birinci nokta yani A noktası
    //Ekranı temizle
    Canvas.Brush.Color := clBtnFace;
    Canvas.FillRect(Canvas.ClipRect);
    x1:=x;
    y1:=y;
    form1.Canvas.MoveTo(x1,y1);
    label2.Caption:='A'+#13+inttostr(x1)+' '+inttostr(y1);
  end;
  if (noktasay=2) then
  begin
    //İkinci nokta yani B noktası
    x2:=x;
    y2:=y;
    form1.Canvas.LineTo(x2,y2);
    label3.Caption:='B'+#13+inttostr(x2)+' '+inttostr(y2);
  end;
  if (noktasay=3) then
  begin
    //Üçüncü nokta yani C noktası
    x3:=x;
    y3:=y;
    form1.Canvas.LineTo(x3,y3);
    label4.Caption:='C'+#13+inttostr(x3)+' '+inttostr(y3);
    //AB doğrusu ile BC doğrusu arasındaki açıyı bulmak için
    //kullandığımız formül
    ab:=sqr(x1-x2)+sqr(y1-y2);
    bc:=sqr(x2-x3)+sqr(y2-y3);
    ac:=sqr(x1-x3)+sqr(y1-y3);
    aci:=radtodeg(arccos((ab+bc-ac)/(2*sqrt(ab)*sqrt(bc))));
    label1.Caption:='Açı= '+ floattostr(aci);
  end;
end;

end.

21 Ekim 2006

OpenGL denemeleri

OpenGL öğrenmeye çalışıyorum. İlk şaşkınlığımı koordinat sistemi yüzünden yaşadım. Çoğu programlama dili dikey ekseni tersten alıp aşağıya indikçe y değerini artan biçimde kabul ediyor. Ancak OpenGL matematiksel koordinarlara uygun biçimde yukarıya çıktıkça dikey eksen değerinin arttığını kabul etmiş, yani koordinat merkezi sol alt köşe olarak alınıyor. İlk denememde içi dolu bir E harfi oluşturmaya çalıştım. Bunun içinde GL_POLYGON özelliğini kullandım.
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //Çizim alanımızın
//sınırları, sırasıyla sol sağ alt üst yakın uzak, örneğin
//yatay eksende minimum -1 maksimum +1 değerlerini
//verebiliyorum
glColor3f(0.0, 0.0, 1.0); // RGB modunda renk değerleri,
                          //şu aşamada beyaz
glBegin(GL_POLYGON);
  glVertex2f(-0.5, 0.5);
  glVertex2f(-0.3, 0.5);
  glVertex2f(-0.3, 0.45);
  glVertex2f(-0.45, 0.45);
  glVertex2f(-0.45, 0.025);
  glVertex2f(-0.3, 0.025);
  glVertex2f(-0.3, -0.025);
  glVertex2f(-0.45, -0.025);
  glVertex2f(-0.45, -0.45);
  glVertex2f(-0.3, -0.45);
  glVertex2f(-0.3, -0.5);
  glVertex2f(-0.5, -0.5);
glEnd();
İlk yazdığım kod bu şekildeydi, tabii hiç beklemediğim bir şekilde şu sonucu aldım. Daha sonra acaba verdiğim noktalarda mı hata var diyerek GL_POLYGON özelliğini GL_LINE_LOOP a çevirdim.
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glColor3f(0.0, 0.0, 1.0); // Beyaz
glBegin(GL_LINE_LOOP);
  glVertex2f(-0.5, 0.5);
  glVertex2f(-0.3, 0.5);
  glVertex2f(-0.3, 0.45);
  glVertex2f(-0.45, 0.45);
  glVertex2f(-0.45, 0.025);
  glVertex2f(-0.3, 0.025);
  glVertex2f(-0.3, -0.025);
  glVertex2f(-0.45, -0.025);
  glVertex2f(-0.45, -0.45);
  glVertex2f(-0.3, -0.45);
  glVertex2f(-0.3, -0.5);
  glVertex2f(-0.5, -0.5);
glEnd();
ve şu sonucu aldım. Anladım ki verdiğim noktalar doğru. Biraz araştırma yaptıktan sonra GL_POLYGON özelliğinin maalesef iç bükey olarak çalışamadığı sadece dış bükey durumlarda doğru sonuçlar verdiğini öğrendim. Sonrasında şeklimi parçalara ayırarak bir daha denedim.
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glColor3f(0.0, 0.0, 1.0); // Beyaz
glBegin(GL_POLYGON);  //Bu bölüm
                      //üstteki yatay parçayı çiziyor.
  glVertex2f(-0.5, 0.45);
  glVertex2f(-0.5, 0.5);
  glVertex2f(-0.3, 0.5);
  glVertex2f(-0.3, 0.45);
glEnd();
glColor3f(1.0, 0.0, 0.0); // Kırmızı
glBegin(GL_POLYGON);  //Bu bölüm 
                      //soldaki dikey parçayı çiziyor.
  glVertex2f(-0.45, 0.45);
  glVertex2f(-0.45, -0.45);
  glVertex2f(-0.5, -0.45);
  glVertex2f(-0.5, 0.45);
glEnd();
glColor3f(0.0, 0.0, 1.0);  //Mavi
glBegin(GL_POLYGON);  //Bu bölüm
                      //ortadaki yatay parçayı çiziyor.
  glVertex2f(-0.45, 0.025);
  glVertex2f(-0.3, 0.025);
  glVertex2f(-0.3, -0.025);
  glVertex2f(-0.45, -0.025);
glEnd();
glColor3f(1.0, 1.0, 1.0);  //Beyaz
glBegin(GL_POLYGON); //Bu bölüm
                     //alttaki yatay parçayı çiziyor.
  glVertex2f(-0.5, -0.45);
  glVertex2f(-0.5, -0.5);
  glVertex2f(-0.3, -0.5);
  glVertex2f(-0.3, -0.45);
glEnd();
ve sonuç; Bingo! Sonunda doğru sonucu elde ettim ama bu aşamada GL_POLYGON özelliğini kullanmanın bir esprisi kalmadı. Bunun yerine dört noktanın içerisini dolduran GL_QUADS özelliği de kullanılabilir.
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 
glColor3f(0.0, 0.0, 1.0); // Beyaz
glBegin(GL_QUADS);  //Bu bölüm
                    //üstteki yatay parçayı çiziyor.
  glVertex2f(-0.5, 0.45);
  glVertex2f(-0.5, 0.5);
  glVertex2f(-0.3, 0.5);
  glVertex2f(-0.3, 0.45);
glEnd();
glColor3f(1.0, 0.0, 0.0); // Kırmızı
glBegin(GL_QUADS);  //Bu bölüm
                    //soldaki dikey parçayı çiziyor.
  glVertex2f(-0.45, 0.45);
  glVertex2f(-0.45, -0.45);
  glVertex2f(-0.5, -0.45);
  glVertex2f(-0.5, 0.45);
glEnd();
glColor3f(0.0, 0.0, 1.0);  //Mavi
glBegin(GL_QUADS);  //Bu bölüm
                    //ortadaki yatay parçayı çiziyor.
  glVertex2f(-0.45, 0.025);
  glVertex2f(-0.3, 0.025);
  glVertex2f(-0.3, -0.025);
  glVertex2f(-0.45, -0.025);
glEnd();
glColor3f(1.0, 1.0, 1.0);  //Beyaz
glBegin(GL_QUADS); //Bu bölüm
                   //alttaki yatay parçayı çiziyor.
  glVertex2f(-0.5, -0.45);
  glVertex2f(-0.5, -0.5);
  glVertex2f(-0.3, -0.5);
  glVertex2f(-0.3, -0.45);
glEnd();
veya daha da basitleştirip
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glColor3f(0.0, 0.0, 1.0); // Beyaz

//Bu bölüm üstteki yatay parçayı çiziyor.
//glRectf(x1, y1, x2, y2);    
glRectf(-0.5, 0.5, -0.3, 0.45);


glColor3f(1.0, 0.0, 0.0); // Kırmızı
//Bu bölüm soldaki dikey parçayı çiziyor.
glRectf(-0.5, 0.45, -0.45, -0.45); 

glColor3f(0.0, 0.0, 1.0);  //Mavi
//Bu bölüm ortadaki yatay parçayı çiziyor.
glRectf(-0.45, 0.025, -0.3, -0.025);
glColor3f(1.0, 1.0, 1.0);  //Beyaz
//Bu bölüm alttaki yatay parçayı çiziyor.
glRectf(-0.5, -0.45, -0.3, -0.5);
dikdörtgen çizmekte kullanılan glRectf komutu kullanılanıbilir.

30 Haziran 2006

Dünyanın en çılgın kenti: Dubai

Dubai dünyanın en büyük inşaat alanı konumunda. Mohammed bin Rashid Al Maktoum'u, büyük düşündüğü için tebrik etmek gerek.

Önce Burj al-Arab isimli dünyanın en yüksek otelini inşa ettiler. Otelde 180 metre yükseklikte bir lobby sizi karşılıyor. 200 metre yükseklikte veya suyun altında bir restoranda yemek yiyebiliyorsunuz. En küçük oda 169 metre kare ve geceliği 1000 dolar. En büyüğü ise 780 metre kare ve geceliği 28000 dolar. Bu otel yetmez deyip 6500 yataklı Asia Asia isimli devasa bir otel için de düğmeye basmış durumdalar. Bir de 550 milyon dolara mal olması beklenen, dünyanın ilk su altı oteli olan Hydropolis ile uğraşıyorlar

Ancak bu oteller de Dubai'lilerin hızını hiç kesmemiş. Şimdi de yaklaşık 800 metre ile dünyanın en yüksek binasını Burj Dubai inşa etmek için kolları sıvamış durumdalar. Bu binanın iç tasarımını da Giorgio Armani yapacak. Kentte Al Burj isminde bir binanın daha yapımına başlanacak, ki bu binanın da en az 700 metre yükseklikte olması bekleniyor. Tabi dünyanın en büyük insan yapımı marinasının (Dubai Marina) ve dünyanın en büyük alış merkezi Dubai Mall'ın da inşaatları sürmekte.

Dubai sadece dikeyde değil yatay düzlemde de ciddi görünüm değişikliğine uğruyor. Şehire Jumeirah, Jebel Ali ve Deira isminde 3 tane palmiye görünümünde ada inşa ediliyor.Bu adalarda pek çok lüks villa, otel ve rekreasyon alanı bulunacak

Daha da çılgın bir proje ise yaklaşık 300 küçük adadan oluşan bir dünya adası projesi. Bu adalardan istediğiniz de alabiliyorsunuz. Yanlız ufak bir sorun var; Adanıza gidebilmek için ya tekneniz ya da helikopteriniz olması gerek.
Bununla da bitmiyor, Jebel Ali adasını çevreleyen 440 kilometre karelik, yaklaşık 400 bin kişinin yaşaması beklenen Dubai Waterfront adında bir yer daha kuruluyor. Gelmesi planlanan bu kalabalık nüfusu desteklemek üzere Dubai kendi Silikon Vadisini ve Eğlence parkını kurmayı da planlıyor. Dubailand isimli bu eğlence parkında Snowdome isminde cam kubbeyle örtülü bir kayak pisti de olacak. Bu park, şu anda dünyanın en büyük eğlence parkı olan Walt Disney World'ün 2 katı büyüklüğünde olacak. Ayrıca yine bu parkta dünyanın en büyük dönme dolabının yapılması planlanıyor. Bu kadar turist trafiğini karşılamak için de dünyanın en büyük havalimanının inşaatına başlanmış. Aşağıdaki adresten Dubai'deki pek çok projeye göz atabilrsiniz.
http://realestate.theemiratesnetwork.com/developments/dubai/

Tabii herşey toz pembe değil. Bu çılgın inşaat sürecini devam ettirmek üzere, kentte 24 saat çalışılıyor. Dünyadaki mevcut vinçlerin %17 sinin Dubai'de kullanıldığı sanılıyor. Bu iş yüküne yetişebilmek için Hindistan, Bangladeş,Pakistan gibi ülkelerden ucuza çalışacak işçiler getirtiliyor. Ağır çalışma şartları yüzünden Burj Dubai'nin inşaatında işçilerle çatışma yaşanmış.

Bütün bunlar elbet boşuna değil; Dubai'nin petrol rezervinin 2016 yılında sona ereceği sanılıyor. Amaç o yıla kadar Dubai'yi bir turizm cennetine dönüştürmek.
Dubai'nin hangi hızda geliştiğini göstermek için size iki fotoğraf. İlki 1991 yılında çekilmiş; Bu da 2005 yılında aynı yerden çekilen Dubai fotografı;

05 Mayıs 2006

Basit 3 boyutlu grafik animasyon programlama

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <dos.h>

#define mx 320
#define my 20
#define lvh 300 //levha uzaklığı(Arttıkça
                //perspektif büyüklük artar)
#define pi 3.14159265
#define gozz 50 //göz yüksekliği
#define yrcp 100 //göz noktasının merkez etrafında
                 //döndüğü yarıçap değeri
#define ys 12 //yüzey sayısı
struct yzy{
   int x[3],y[3],z[3];} yuzey[ys];
int i; long detyuzey[ys],detyuzeyx[ys],detyuzeyy[ys], detyuzeyz[ys],yuzeytoplam[ys]; float cstb[360],sntb[360]; void ciz(int aci) { int j,xx[3],yy[3],zz[3],px[3],py[3],pldizi[ys][8]; for (j=0;j<ys;j++) { for (i=0;i<3;i++) { xx[i]=yuzey[j].y[i]*sntb[aci] +yuzey[j].x[i]*cstb[aci]; yy[i]=yuzey[j].y[i]*cstb[aci] -yuzey[j].x[i]*sntb[aci]+yrcp; px[i]=(int)(mx+lvh*xx[i]/yy[i]); py[i]=(int)(my-lvh*(yuzey[j].z[i]-gozz)/yy[i]); } pldizi[j][0]=px[0]; pldizi[j][1]=py[0]; pldizi[j][2]=px[1]; pldizi[j][3]=py[1]; pldizi[j][4]=px[2]; pldizi[j][5]=py[2]; pldizi[j][6]=px[0]; pldizi[j][7]=py[0]; yuzeytoplam[j]= (float) detyuzeyx[j]*yrcp*sntb[aci] -detyuzeyy[j]*yrcp*cstb[aci]+detyuzeyz[j]*gozz; if (yuzeytoplam[j]>=detyuzey[j]) fillpoly(4,pldizi[j]); } } void main() { int gdriver = 9, gmode=1, errorcode; int aci=0; for (i=0;i<360;i++) { cstb[i]=cos(i*pi/180); sntb[i]=sin(i*pi/180); } //Üst yüzey yuzey[0].x[0]= 40; yuzey[0].y[0]= 30; yuzey[0].z[0]= 20; yuzey[0].x[1]=-40; yuzey[0].y[1]= 30; yuzey[0].z[1]= 20; yuzey[0].x[2]=-40; yuzey[0].y[2]=-30; yuzey[0].z[2]= 20; //Sağ yüzey yuzey[1].x[0]= 40; yuzey[1].y[0]= 30; yuzey[1].z[0]= 20; yuzey[1].x[1]= 40; yuzey[1].y[1]=-30; yuzey[1].z[1]= 20; yuzey[1].x[2]= 40; yuzey[1].y[2]=-30; yuzey[1].z[2]= 0; //Ön yüzey yuzey[2].x[0]= 40; yuzey[2].y[0]=-30; yuzey[2].z[0]= 20; yuzey[2].x[1]=-40; yuzey[2].y[1]=-30; yuzey[2].z[1]= 20; yuzey[2].x[2]=-40; yuzey[2].y[2]=-30; yuzey[2].z[2]= 0; //Sol yüzey yuzey[3].x[0]=-40; yuzey[3].y[0]=-30; yuzey[3].z[0]= 20; yuzey[3].x[1]=-40; yuzey[3].y[1]= 30; yuzey[3].z[1]= 20; yuzey[3].x[2]=-40; yuzey[3].y[2]= 30; yuzey[3].z[2]= 0; //Arka yüzey yuzey[4].x[0]=-40; yuzey[4].y[0]= 30; yuzey[4].z[0]= 20; yuzey[4].x[1]= 40; yuzey[4].y[1]= 30; yuzey[4].z[1]= 20; yuzey[4].x[2]= 40; yuzey[4].y[2]= 30; yuzey[4].z[2]= 0; //Alt yüzey yuzey[5].x[0]= 40; yuzey[5].y[0]=-30; yuzey[5].z[0]= 0; yuzey[5].x[1]=-40; yuzey[5].y[1]=-30; yuzey[5].z[1]= 0; yuzey[5].x[2]=-40; yuzey[5].y[2]= 30; yuzey[5].z[2]= 0; //Üst yüzey 2 yuzey[6].x[0]= 40; yuzey[6].y[0]= 30; yuzey[6].z[0]= 20; yuzey[6].x[1]=-40; yuzey[6].y[1]=-30; yuzey[6].z[1]= 20; yuzey[6].x[2]= 40; yuzey[6].y[2]=-30; yuzey[6].z[2]= 20; //Sağ yüzey 2 yuzey[7].x[0]= 40; yuzey[7].y[0]= 30; yuzey[7].z[0]= 20; yuzey[7].x[1]= 40; yuzey[7].y[1]=-30; yuzey[7].z[1]= 0; yuzey[7].x[2]= 40; yuzey[7].y[2]= 30; yuzey[7].z[2]= 0; //Ön yüzey 2 yuzey[8].x[0]= 40; yuzey[8].y[0]=-30; yuzey[8].z[0]= 20; yuzey[8].x[1]=-40; yuzey[8].y[1]=-30; yuzey[8].z[1]= 0; yuzey[8].x[2]= 40; yuzey[8].y[2]=-30; yuzey[8].z[2]= 0; //Sol yüzey 2 yuzey[9].x[0]=-40; yuzey[9].y[0]=-30; yuzey[9].z[0]= 20; yuzey[9].x[1]=-40; yuzey[9].y[1]= 30; yuzey[9].z[1]= 0; yuzey[9].x[2]=-40; yuzey[9].y[2]=-30; yuzey[9].z[2]= 0; //Arka yüzey 2 yuzey[10].x[0]=-40; yuzey[10].y[0]= 30; yuzey[10].z[0]= 20; yuzey[10].x[1]= 40; yuzey[10].y[1]= 30; yuzey[10].z[1]= 0; yuzey[10].x[2]=-40; yuzey[10].y[2]= 30; yuzey[10].z[2]= 0; //Alt yüzey 2 yuzey[11].x[0]= 40; yuzey[11].y[0]=-30; yuzey[11].z[0]= 0; yuzey[11].x[1]=-40; yuzey[11].y[1]= 30; yuzey[11].z[1]= 0; yuzey[11].x[2]= 40; yuzey[11].y[2]= 30; yuzey[11].z[2]= 0; for (i=0;i<ys;i++) { detyuzeyx[i]= yuzey[i].y[1]*yuzey[i].z[2] +yuzey[i].y[2]*yuzey[i].z[0] +yuzey[i].y[0]*yuzey[i].z[1] -yuzey[i].y[1]*yuzey[i].z[0] -yuzey[i].y[2]*yuzey[i].z[1] -yuzey[i].y[0]*yuzey[i].z[2]; detyuzeyy[i]= yuzey[i].x[0]*yuzey[i].z[2] +yuzey[i].x[1]*yuzey[i].z[0] +yuzey[i].x[2]*yuzey[i].z[1] -yuzey[i].x[2]*yuzey[i].z[0] -yuzey[i].x[0]*yuzey[i].z[1] -yuzey[i].x[1]*yuzey[i].z[2]; detyuzeyz[i]= yuzey[i].x[0]*yuzey[i].y[1] +yuzey[i].x[1]*yuzey[i].y[2] +yuzey[i].x[2]*yuzey[i].y[0] -yuzey[i].x[2]*yuzey[i].y[1] -yuzey[i].x[0]*yuzey[i].y[2] -yuzey[i].x[1]*yuzey[i].y[0]; detyuzey[i]= (float) yuzey[i].x[0]*yuzey[i].y[1]*yuzey[i].z[2] +yuzey[i].x[1]*yuzey[i].y[2]*yuzey[i].z[0] +yuzey[i].x[2]*yuzey[i].y[0]*yuzey[i].z[1] -yuzey[i].x[2]*yuzey[i].y[1]*yuzey[i].z[0] -yuzey[i].x[0]*yuzey[i].y[2]*yuzey[i].z[1] -yuzey[i].x[1]*yuzey[i].y[0]*yuzey[i].z[2]; } initgraph(&gdriver, &gmode, "c:\\tc\\bgi"); errorcode = graphresult(); if (errorcode != 0) { //Bir hata oluşmuşsa printf("Grafik hatası: %s\n", grapherrormsg(errorcode)); printf("Sonlandirmak icin bir tusa basin:"); getch(); exit(1); } //Grafik komutlarının başlangıcı - Alan 640x350 setfillstyle(10,4); while(!kbhit()) { setactivepage(1); cleardevice(); ciz(aci); aci++; if (aci>=360) aci-=360; setvisualpage(1); delay(100); setactivepage(1); cleardevice(); ciz(aci); aci++; if (aci>=360) aci-=360; setvisualpage(1); delay(100); } // Grafik modundan çıkış getch(); closegraph(); }
2 günlük bir çalışma sonucunda hazırladığım basit bir grafik animasyon programı. Her yüzey bir üçgen polygondan oluşuyor. Program hızlandırma için herhangi bir assembly parçaçığı kullanmıyor sadece BGI grafikleri kullanılıyor. Ayrıca Turbo C'nin kurulduğu varsayılan dizin olarak "c:/tc" yi ve EGAVGA.BIN dosyasının bulunduğu klasörü de "c:/tc/bgi" olarak kabul ettim.