programming etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
programming etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

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.

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.