Skip to main content

Işın İzleme (Ray Tracing) - Adım 1.

Işın izleme (Ray Tracing), bilgisayar ile modelleme uygulamalarında, son adımda gerçekçi görüntünün en gerçekçi haline geldiği aşamadır. Burda yapmaya çalışacağımız şey kendi basit ışın izleme sistemimizi oluşturmak. Bunun için öncelikle çıktı olarak elde edeceğimiz resim dosyasını yaratmamızı sağlayan kütüphaneleri oluşturuyoruz.


İzleyeceğimiz yol ve kodlar, Peter Shirley'in yazdığı "Realistic Ray Tracing" kitabının ikinci baskısından alınarak bazı modifikasyonlarla güncellenmiştir. Kodlar c++ ile yazılmıştır. Nasıl derleneceği yazının sonunda anlatılacaktır.


İlk iki kütüphanemiz rgb.h ve image.h aşağıdaki şekildedir.


--------------------------------------------------------------------------------------------------------------
#ifndef RGB_H
#define RGB_H


#include <assert.h>


#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <fstream>
#include <istream>
#include <string.h>


using namespace std;


class rgb {
public:



rgb() {}
rgb(float r, float g, float b) { data[0] = int(r)%256; data[1] = int(g)%256; data[2] = int(b)%256; }


rgb(const rgb &c)
{ data[0] = c.r(); data[1] = c.g(); data[2] = c.b(); }
float r() const { return data[0]; }


float g() const { return data[1]; }
float b() const { return data[2]; }


rgb operator+() const { return rgb( data[0], data[1], data[2]); }


rgb operator-() const { return rgb(-data[0],-data[1],-data[2]); }


float operator[](int i) const {assert(i >= 0 && i < 3); return data[i];}


float& operator[](int i) {assert(i >= 0 && i < 3); return data[i];}


rgb& operator+=(const rgb &c) { data[0] += c[0]; data[1] += c[1];


data[2] += c[2]; return *this; }
rgb& operator-=(const rgb &c) { data[0] -= c[0]; data[1] -= c[1];


data[2] -= c[2]; return *this; }
rgb& operator*=(const rgb &c) { data[0] *= c[0]; data[1] *= c[1];


data[2] *= c[2]; return *this; }
rgb& operator/=(const rgb &c) { data[0] /= c[0]; data[1] /= c[1];


data[2] /= c[2]; return *this; }
rgb& operator*=(float f) { data[0] *= f; data[1] *= f;


data[2] *= f; return *this; }
rgb& operator/=(float f) { data[0] /= f; data[1] /= f;


data[2] /= f; return *this; }


float data[3];


};


inline bool operator==(rgb c1, rgb c2) {
return (c1.r() == c2.r() && c1.g() == c2.g() && c1.b() == c2.b()); }


inline bool operator!=(rgb c1, rgb c2) {
return (c1.r() != c2.r() || c1.g() != c2.g() || c1.b() != c2.b()); }


inline istream &operator>>(istream &is, rgb &c) {return (is >> c[0] >> c[1] >> c[2]); }


inline ostream &operator<<(ostream &os, rgb &c) {return (os << c[0] << " " << c[1] << " " << c[2]); }


inline rgb operator+(rgb c1, rgb c2) {
return rgb(c1.r()+c2.r(), c1.g()+c2.g(), c1.b()+c2.b());}
inline rgb operator-(rgb c1, rgb c2) {


return rgb(c1.r()-c2.r(), c1.g()-c2.g(), c1.b()-c2.b());}
inline rgb operator*(rgb c1, rgb c2) {
return rgb(c1.r()*c2.r(), c1.g()*c2.g(), c1.b()*c2.b());}
inline rgb operator/(rgb c1, rgb c2) {


return rgb(c1.r()/c2.r(), c1.g()/c2.g(), c1.b()/c2.b());}
inline rgb operator*(rgb c, float f) {
return rgb(c.r()*f, c.g()*f, c.b()*f);}


inline rgb operator*(float f, rgb c) {
return rgb(c.r()*f, c.g()*f, c.b()*f);}
inline rgb operator/(rgb c, float f) {


return rgb(c.r()/f, c.g()/f, c.b()/f);}


#endif


--------------------------------------------------------------------------------------------------------------


#ifndef IMAGE_H
#define IMAGE_H


#include "rgb.h"


using namespace std;


class Image
{
public:


Image() {}
Image(int w, int h);
Image(int w, int h , rgb c);


void setPixel(int x, int y, rgb c)
{
if (!(x >= 0 && x < w && y >= 0 && y < h))


{
cerr << "Image::setPixel w = " << w << " h = " << h
<< " requested pixel (" << x << ", " << y << ")"


<< endl;
exit(0);
}
data[x][y] = c;
}


rgb getPixel(int x, int y) const
{
x = ( x >= 0 ? x : 0);


x = ( x < w ? x : w-1);
y = ( y >= 0 ? y : 0);
y = ( y < h ? y : h-1);


if (!(x >= 0 && x < w && y >= 0 && y < h))


{
cerr << "Image::getPixel w = " << w << " h = " << h << endl


<< " requested pixel (" << x << ", " << y << ")"
<< endl;


exit(0);
}

return data[x][y];
}


int width() const { return w; }
int height() const { return h; }


void readPPM (char* file_name);
void writePPM(char * filename) const;


private:
rgb **data;
int w, h;
};
#endif


--------------------------------------------------------------------------------------------------------------


#include "image.h"


using namespace std;


Image::Image(int w_, int h_ ) : w(w_), h(h_) {
assert(w > 0 && h > 0);


data = new rgb*[w];
assert(data != 0);
for (int i = 0; i < w; i++) {


data[i] = new rgb[h];
assert(data[i]);
}
}


Image::Image(int w_, int h_ , rgb c) : w(w_), h(h_) {


assert(w > 0 && h > 0);
data = new rgb*[w];


assert(data != 0);
for (int i = 0; i < w; i++) {


data[i] = new rgb[h];
assert(data[i]);
for (int j = 0; j < h; j++)


data[i][j] = c;
}
}


void Image::writePPM(char * filename) const {


ofstream s;

s.open(filename);


s << "P3\n" <<"#"<<filename<<"\n"<<w << " " << h << "\n255\n";


for (int y = h-1; y >= 0; y--)
{


for (int x = 0; x < w; x++)
{
s<<data[x][y].r()<<" "<<data[x][y].g()<<" "<<data[x][y].b()<<" ";


}
s<<endl;
}

s.close();
}




void Image::readPPM (char* file_name)
{
int i, j;
ifstream in;


in.open(file_name);
if (!in)
{
cerr << "ERROR -- Can't find PPM file \'" << string(file_name) << "\'\n";


exit(0);
}
string file_type, garbage;
rgb pix_col;

// read in ppm header info


in >> file_type >> w >> h >> garbage;

// create new raster with correct size
data = new rgb*[w];


for (i = 0; i < w; i++)
data[i] = new rgb[h];


// now read in pixel rgb values and assign to raster


int red, green, blue;
for (i = h-1; i >= 0; i--)
for (j = 0; j < w; j++)


{
in >> red >> green >> blue;
pix_col[0] = (float(red));


pix_col[1] = (float(green));
pix_col[2] = (float(blue));


data[j][i] = pix_col;


}
}
--------------------------------------------------------------------------------------------------------------
Hemen yukarıdaki kod da image.cc olarak kaydedilebilir. Burada da görüldüğü üzere image.h içinde belirtilen fonksiyonların tanımları yapılmaktadır. Bir ana programda bu kütüphanelerin nasıl kullanılabilieceğini gösterelim


//by Sukru OZAN, Sept. 2009
#include <vector>
#include <iostream>


#include "rgb.h"
#include "image.h"


using namespace std;


int main ()
{



Image im(500,500);
for (int i=0;i<500;i++)


for (int j=0;j<500;j++) im.setPixel(i,j,rgb(0.0,0.0,128.0));


im.writePPM("Deneme.ppm");
}


Bu dosyayı da step1.cc olarak kaydettiğimizi düşünelim. Tüm bu kodlar aynı klasörde bulunurken


g++ -o step1 step1.cc image.cc


Komutu ile derleyip "./step1" ile çalıştırdığımızda 500x500 büyüklüğünde koyu mavi bir imge elde ederiz.




Comments

Popular posts from this blog

LaTeX'te Sunum Hazırlamak

Latex'i kullanarak projeksiyon cihazlarında sunulmaya yönelik çok güzel sunumlar hazırlamak mümkün olmaktadır. Oluşturulan dosya PDF olduğundan ve her işletim sisteminde (linux, mac os, unix, windows vs.) en azından bir tane PDF okuyucu program olduğundan, hazırlanan sunumların taşınabilirliği de azami seviyede olmaktadır. Tabi ki latex'in en üstün olduğu nokta olan mükemmel fontlar ve matematiksel denklem yazılımları latex'te hazırlanan sunumlar için de geçerli olmaktadır. Aşağıdaki linklerden indireceğiniz pakette örnek sunuma ait gerekli dosyaları bulabilirsiniz. Daha ayrıntılı bilgi almak isterseniz bana ulaşabilirsiniz.
Link : DROPBOX

Hazırladığım örnek sunumun slaytları şu şekilde:





















Yılbaşına Nerede Girilmez - İzmir Narlıdere Naci Usta Restoran

Geçen hafta yılbaşı dolayısıyla eşim "iki senedir evdeyiz hadi bu sene dışarıya çıkalım yılbaşında" dedi. Bu fikir her ne kadar bu tarz mekanda eğlenme olayları beni açmasa da, bana da mantıklı geldi, bir değişiklik olur dedim, iki arkadaşım ve eşleri ile birlikte toplam 6 kişi yılbaşı gecesini bir makanda geçirmeye karar verdik. Şimdi hal böyle olunca tabi insan herşey tam olsun istiyor, o yüzden biz de İzmir'deki olası mekanları değerlendirip bir fiyat filtresinden geçirdikten sonra gördük ki, "yıldız tilbe ile yeni yıl coşkusu" tadındaki eğlenceler, şayet yıldız tilbeyi izlemeye gidip yıldız tilbeyi görmek istiyorsanız kişi başı yaklaşı 400 TL ye mal oluyor. Tabi biz de oha dedik. Sonra ayrı bir olası mekan grubu daha keşfettik, bu gruptaki fiyatlar 90 (limitli içecek) ila 150 tl (limitsiz içecek) arasında değişiyordu. Konum ve müşteri profili düşünülünce bu mekanların bize daha çok hitabedebileceğini düşündük. Sonra limitli içecek olayında vazgeçip limitsi…