Отрисовка сцены "Отражающиеся дорожки" алгоритмом обратной трассировки лучей

Разработка и практическая апробация программы для соответствия поставленным требованиям: реализация трассировки лучей с просчетом теней, освещения, отражения, преломления лучей, что является несомненным достоинством данной спроектированной программы.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 14.04.2011
Размер файла 662,7 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Курсовая работа

на тему:

«Отрисовка сцены «Отражающиеся дорожки» алгоритмом обратной трассировки лучей»

Екатеринбург 2011 г.

Алгоритм работы программы

1) Заранее в программе заданы объекты и источники света, тип поверхности объектов, размеры окна для отображения изображения, цвет фона, а также координаты точки обзора;

2) Затем для каждого пикселя изображения рассчитываем цвет, для этого направляем лучи;

3) Если заданный луч не пересекает ни одного объекта сцены, то закрашиваем данный пиксель в цвет фона.

4) Если же заданный луч пересекает какой-либо объект сцены, то обращаемся к методу класса Ray рассчитывающему цвет в точке пересечения. Он в свою очередь обращается к аналогичному методу класса Sphere, который находит координаты точки пересечения луча с объектом, увеличивает длину луча (вектора) до точки пересечения с объектом, находит вектор нормали к поверхности в точке пересечения.

5) Программа передает все найденные выше параметры в метод класса Surface, который рассчитывает цвет в данной точке. В зависимости от свойств материала пересеченного объекта данный метод находит затененность, отражение, преломление в данной точке. При наличии двух последних генерируется новый луч, который трассируется (т.е. проходит заново пункты 3-5 данного алгоритма (рекурсия)). При трассировке этого луча мы получаем цвет в данной точке, который модифицируется при помощи коэффициентов и возвращается в главную функцию для последующей отрисовки.

Блок-схема программы

программа трассировка тень освещение

Заключение

В результате работы над программой были выполнены поставленные требования: реализована трассировка лучей с просчетом теней, освещения, отражения, преломления лучей, что является несомненным достоинством программы. Также задан объект - сфера. Недостатком программы считаю то, что не рассмотрены такие источники света, как свет окружающей среды и направленный свет.

Приложение 1

Полученное изображение

Приложение 2

Листинг Light.java

package objects;

/**

*

* @author Алексей

*/

 // Источник света

public class Light {

public WorkVector lightvec; // позиция истоника света

public float lightred, lightgreen, lightblue; // цвет источника света

public Light (WorkVector v, float r, float g, float b) {

lightvec = v;

lightred = r;

lightgreen = g;

lightblue = b;

}

}

Приложение 3

Листинг Ray.java

package objects;

import java.awt. Color;

import java.util. Vector;

/**

*

* @author Алексей

*/

 // Луч

public class Ray {

float max_distance = Float.MAX_VALUE; // максимальная значение для currentDistance луча

WorkVector initRay; // начало луча

WorkVector finalRay; // направление луча

float currentDistance; // Текущее расстояние до обьекта

Sphere object; // Обьект, с которым произошло столкновение луча

public Ray (WorkVector eye, WorkVector dir) {

initRay = new WorkVector(eye);

finalRay = WorkVector.normalize(dir);

}

public boolean trace (Vector objects) {

currentDistance = max_distance;

object = null;

for (int i = 0; i < objects.size(); i++) {

Sphere object = (Sphere) objects.elementAt(i);

object.intersection(this); // проверка пересечения с объектом

}

return (object!= null); // возвращение true если было пересечение

}

public final Color Shade (Vector lights, Vector objects, Color bgnd) {

return object. Shade (this, lights, objects, bgnd);

}

}

Приложение 4

Листинг Sphere.java

package objects;

import java.awt. Color;

import java.util. Vector;

/**

*

* @author Алексей

*/

 // Сфера

public class Sphere {

Surface surface; // тип поверхности

WorkVector center; // положение сферы

float radius; // радиус сферы

public Sphere (Surface s, WorkVector c, float r) {

surface = s;

center = c;

radius = r;

}

public boolean intersection (Ray ray) { // поиск пересечения со сферой

WorkVector dv = center.sub (ray.initRay);

float v = ray.finalRay.dot(dv);

 // Проверка того, может ли вообще произойти пересечение

if (v - radius > ray.currentDistance)

return false;

 // нахождение суммы квадрата v и квадратов элементов вектора dv

float t = radius*radius + v*v - dv.x*dv.x - dv.y*dv.y - dv.z*dv.z;

if (t < 0)

return false;

 // проверка знака пересечения и того что оно самое близкое

t = v - ((float) Math.sqrt(t));

if ((t > ray.currentDistance) || (t < 0))

return false;

ray.currentDistance = t; // расстояние до обьекта пересечения приравнивается к currentDistance

ray.object = this; // текущий обьект становится объектом пересечения с лучем

return true;

}

public Color Shade (Ray ray, Vector lights, Vector objects, Color bgnd) {

 // вызывается, если была найдена точка пересечения обьекта и луча

 // направление луча увеличивается на расстояние до точки пересечения

float px = ray.initRay.x + ray.currentDistance*ray.finalRay.x;

float py = ray.initRay.y + ray.currentDistance*ray.finalRay.y;

float pz = ray.initRay.z + ray.currentDistance*ray.finalRay.z;

WorkVector p = new WorkVector (px, py, pz); // нахождение точки пересечения луча и обьекта

WorkVector v = new WorkVector (-ray.finalRay.x, - ray.finalRay.y, - ray.finalRay.z); // нахождение вектора - отрицательного направления луча

WorkVector n = new WorkVector((px - center.x), (py - center.y), (pz - center.z)); // находится вектор, которому принадлежит нормаль в текущей точке поверхности

n.normalize(); // получаем нормаль

return surface. Shade (p, n, v, lights, objects, bgnd); // возвращяестя цвет в данной точке

}

}

Приложение 5

Листинг Surface.java

package objects;

import java.awt. Color;

import java.util. Vector;

/**

*

* @author Алексей

*/

public class Surface {

public float ir, ig, ib; // цвет обьекта

public float kRasseivania, kOtragenia, ns; // константы для освещения обьекта

public float kt, kr; // коэффициенты материала

private float TINY = 0.001f;

private float I255 = 0.00392156f;

private WorkVector luch;

public Surface (float rval, float gval, float bval, float d,

float s, float n, float r, float t) {

ir = rval; ig = gval; ib = bval; // задание цвета поверхности

kRasseivania = d; // рассеивающая составляющая поверхности

kOtragenia = s; // отражающая составляющая поверхности

ns = n;

kr = r*I255;

kt = t*I255;

}

public Color Shade (WorkVector p, WorkVector n, WorkVector v, Vector lights, Vector objects, Color bgnd) // возвращает полученный цвет обьекта в точке

 // точка пересечения (p)

 // нормаль в точке пересечения (n)

 // вектор направленный в точку из которой пришел лучь (v)

{

float r = 0; // обнуляем

float g = 0;

float b = 0;

for (int i = 0; i < lights.size(); i++) { // цикл, в котором расчитывается освещенность

Light light = (Light) lights.elementAt(i); // взятие текущего истчоника освещения

luch = new WorkVector (light.lightvec.sub(p)); // задаем вектор luch как вектор от источника освещения до точки обьекта

luch.normalize(); // нормализируем вектор luch чтобы получить вектор направления от источника освещения к точке обьекта

 // ЗАТЕНЕННОСТЬ

WorkVector poffset = p.add (luch.mul(TINY)); // к основанию нового луча добавляется очень мальенький вектор luch чтобы при проверке не пересечь сам себя

Ray shadowRay = new Ray (poffset, luch); // создание луча проверки на затененность

if (shadowRay.trace(objects)) // в случае пеоесечения какого либо обьекта

continue; // переходим к следующему источнику освещения

float lambert = WorkVector.dot (n, luch); // нахождение коэффициента освещенности в зависимости от нормали обьекта в данной точке и напраления источника света

if (lambert > 0) {

if (kRasseivania > 0) {

float diffuse = kRasseivania*lambert;

r += diffuse*ir*light.lightred;

g += diffuse*ig*light.lightgreen;

b += diffuse*ib*light.lightblue;

}

if (kOtragenia > 0) {

lambert *= 2;

float spec = v.dot (lambert*n.x - luch.x, lambert*n.y - luch.y, lambert*n.z - luch.z);

if (spec > 0) {

spec = kOtragenia*((float) Math.pow((double) spec, (double) ns));

r += spec*light.lightred;

g += spec*light.lightgreen;

b += spec*light.lightblue;

}

}

}

}

 // ОТРАЖЕНИЕ

if (kr > 0) { // если коэффициент отражения больше нуля, то обьект может отражать

float t = v.dot(n); // получение результата скалярного произведения вектора направленного к началу источника луча и нормали поверхности в данной точке

if (t > 0) {

t *= 2;

WorkVector reflect = new WorkVector (n.mul(t).sub(v));

WorkVector poffset = new WorkVector (p.add (reflect.mul(TINY)));

Ray reflectedRay = new Ray (poffset, reflect);

if (reflectedRay.trace(objects)) {

Color rcolor = reflectedRay. Shade (lights, objects, bgnd);

r += kr*rcolor.getRed();

g += kr*rcolor.getGreen();

b += kr*rcolor.getBlue();

} else {

r += kr*bgnd.getRed();

g += kr*bgnd.getGreen();

b += kr*bgnd.getBlue();

}

}

}

 // ПРИЛОМЛЕНИЕ

if (kt > 0) {

WorkVector tr;

WorkVector incident = v.add(p);

float eta = (float) 0.7;

float c1 = incident.mul(-1).dot(n);

float c2;

c2 = 1 - eta*eta*(1-c1*c1);

if (c2 > 0.0) {

c2 = (float) (Math.sqrt(c2));

float maae = (eta*c1 - c2);

tr = incident.mul(eta).add (n.mul(maae));

tr.normalize();

WorkVector poffset = p.add (n.mul(-TINY));

Ray reflectedRay = new Ray (poffset, tr);

if (reflectedRay.trace(objects)) {

Color rcolor = reflectedRay. Shade (lights, objects, bgnd);

r += kt*rcolor.getRed();

g += kt*rcolor.getGreen();

b += kt*rcolor.getBlue();

} else {

r += kt*bgnd.getRed();

g += kt*bgnd.getGreen();

b += kt*bgnd.getBlue();

}

}

}

 // чтобы избежать выход за границы

r = (r > 1f)? 1f: r;

r = (r < 0f)? 0f: r;

g = (g > 1f)? 1f: g;

g = (g < 0f)? 0f: g;

b = (b > 1f)? 1f: b;

b = (b < 0f)? 0f: b;

return new Color (r, g, b); // возвращение цвета точки

}

}

Приложение 6

Листинг WorkVector.java

package objects;

/**

*

* @author Алексей

*/

public class WorkVector {

public float x, y, z; // координаты вектора

public WorkVector() {}

public WorkVector (float X, float Y, float Z) {

x = X;

y = Y;

z = Z;

}

public WorkVector (WorkVector v) {

x = v.x;

y = v.y;

z = v.z;

}

 // методы

public float dot (WorkVector v) { // скалярное произведение

return (x*v.x + y*v.y + z*v.z);

}

public float dot (float Bx, float By, float Bz) {

return (x*Bx + y*By + z*Bz);

}

public static float dot (WorkVector A, WorkVector B) {

return (A.x*B.x + A.y*B.y + A.z*B.z);

}

public WorkVector add (WorkVector A) { // Вектор сложения

return new WorkVector (x+A.x, y+A.y, z+A.z);

}

public WorkVector sub (WorkVector A) { // Вектор разности

return new WorkVector (x-A.x, y-A.y, z-A.z);

}

public WorkVector mul (float A) { // Вектор, умноженный на число

return new WorkVector (x*A, y*A, z*A);

}

public WorkVector set (WorkVector A) { // Задание координат

return new WorkVector (A.x, A.y, A.z);

}

public WorkVector set (float Ax, float Ay, float Az) {

return new WorkVector (Ax, Ay, Az);

}

public WorkVector cross (WorkVector B) {

return new WorkVector (y*B.z - z*B.y, z*B.x - x*B.z, x*B.y - y*B.x);

}

public WorkVector cross (float Bx, float By, float Bz) {

return new WorkVector (y*Bz - z*By, z*Bx - x*Bz, x*By - y*Bx);

}

public WorkVector cross (WorkVector A, WorkVector B) {

return new WorkVector (A.y*B.z - A.z*B.y, A.z*B.x - A.x*B.z, A.x*B.y - A.y*B.x);

}

public float length() { // Нахождение длины вектора

return (float) Math.sqrt (x*x + y*y + z*z);

}

public float length (WorkVector A) {

return (float) Math.sqrt (A.x*A.x + A.y*A.y + A.z*A.z);

}

public void normalize() { // нормализация вектора

float t = x*x + y*y + z*z;

if (t!= 0 && t!= 1) t = (float) (1 / Math.sqrt(t));

x *= t;

y *= t;

z *= t;

}

public static WorkVector normalize (WorkVector A) {

float t = A.x*A.x + A.y*A.y + A.z*A.z;

if (t!= 0 && t!= 1) t = (float) (1 / Math.sqrt(t));

return new WorkVector (A.x*t, A.y*t, A.z*t);

}

}

Приложение 7

Листинг Main.java

package ray_tracing;

import objects.*;

import java.awt. Color;

import java.awt. Frame;

import java.awt. Graphics;

import java.awt. Image;

import java.awt.event. WindowAdapter;

import java.awt.event. WindowEvent;

import java.util. Vector;

/**

*

* @author Алексей

*/

public class Main {

final static int kol_vo = 600;

static Image screen;

static Graphics gc;

static Vector listOfObjects;

static Vector listOfLights;

static Surface currentSurface;

static WorkVector eye, lookat, up; // векторы необходимые для задания проекции

static float angle = 40; // угол обзора

static Color background = new Color (0,0,0); // цвет фона

static int width=640, height=480;

static Frame frame = new Frame («Raytracing»); // создание фрейма для отображения

public static void main (String[] args) {

frame.setSize (width, height);

frame.setLocationRelativeTo(null);

frame.setVisible(true);

screen = frame.createImage (width, height);

gc = screen.getGraphics();

gc.setColor (frame.getBackground());

gc.fillRect (0, 0, width, height);

frame.addWindowListener (new WindowAdapter() {

@Override

public void windowClosing (WindowEvent e) {

System.exit(0);

}

});

 // задание списков обьектов и источников освещения

listOfObjects = new Vector (kol_vo, kol_vo);

listOfLights = new Vector (kol_vo, kol_vo);

 // добавление источника освещения

listOfLights.addElement (new Light (new WorkVector((float) 2, (float) 2, (float) 1), 1, 1, 1));

listOfLights.addElement (new Light (new WorkVector((float) - 3, (float) 5, (float) 3), 1, 1, 1));

 // добавления сфер на сцену

for (int i=0; i<40; i++)

for (int j=0; j<10; j++)

{

 // Задание материала для обьектов

currentSurface = new Surface (i*j*0.02f, 0.7f, i*j*0.01f, 0.4f, 0.4f, 10.0f, 0f, 0f);

 // Добавление обьекта

listOfObjects.addElement (new Sphere (currentSurface, new WorkVector((float) i*(float) 1.0-9, (float) - 5*(float) Math.sqrt((float) i)+7, (float) - j*j*(float) 1.00+(float) 6), (float) 0.8));

}

currentSurface = new Surface (0.6f, 0.6f, 0.4f, 0.2f, 0.4f, 10.0f, 1.0f, 0.2f);

listOfObjects.addElement (new Sphere (currentSurface, new WorkVector((float) 20, (float) 0, (float) - 40), (float) 15));

 // Задание необходимых переменных для рендера

eye = new WorkVector (5, 0, 40); // координаты точки обзора

lookat = new WorkVector (0, 0, 0); // координаты точки направления взгляда

up = new WorkVector (0, 1, 0); // вектор указывающий верх

Graphics g = frame.getGraphics();

WorkVector Eye, Du, Dv, Vp;

WorkVector look = new WorkVector (lookat.x - eye.x, lookat.y - eye.y, lookat.z - eye.z);

float fl = (float) (width / (2*Math.tan((0.5*angle)*Math.PI/180)));

Eye = eye;

Du = WorkVector.normalize (look.cross(up)); // вектор являющийся вспомогательным вектором для рендера «по оси х»

Dv = WorkVector.normalize (look.cross(Du)); // вектор являющийся вспомогательным вектором для рендера «по оси y»

Vp = WorkVector.normalize(look); // вектор являющийся вспомогательным вектором для рендера «по оси z»

Vp = (Vp.mul(fl)).sub((((Du.mul(width)).add (Dv.mul(height))).mul (0.5f)));

for (int j = 0; j < height; j++) {

for (int i = 0; i < width; i++) {

WorkVector dir = new WorkVector(((Du.mul(i)).add (Dv.mul(j)).add(Vp))); // задание точки начала луча

Ray ray = new Ray (Eye, dir); // задание вектора направления луча

if (ray.trace(listOfObjects)) { // если было найдено пересечение с обектом

gc.setColor (ray. Shade (listOfLights, listOfObjects, background)); // то точка получает расчитываемый цвет

} else {

gc.setColor(background); // Если не было пересечения с обьектами то точка имеет цвет фона

}

gc.drawLine (i, j, i, j); // рисование точки на буферном изображении

}

}

g.drawImage (screen, 0, 0, frame); // отрисовка всего изображения на экране

}

}

Размещено на Allbest.ru


Подобные документы

  • Алгоритмы получения реалистических изображений. Применение алгоритма обратной трассировки лучей, ее математическая основа. Составление матрицы и программная реализация. Формирование отраженного и преломленного луча. Модульная структура программы.

    курсовая работа [219,3 K], добавлен 24.06.2009

  • Алгоритмы построения изображений, близких к фотореалистичным. Трассировка лучей и построение теней. Схема расчета интенсивности света. Параметры, задающие свойства тел. Зависимость времени построения от глубины рекурсии и количества источников освещения.

    курсовая работа [734,3 K], добавлен 18.06.2009

  • Обратная трассировка лучей: ограничения при реализации, достоинства и недостатки. Математические и физические предпосылки алгоритма, блок-схема. Выбор языка программирования. Зависимость времени генерации от глубины рекурсии, количества источников.

    курсовая работа [503,0 K], добавлен 27.05.2013

  • Создание программы, выполняющей трассировку проводного монтажа алгоритмом Краскала. Конфигурация программы для работы под управлением операционных систем семейства Microsoft Windows. Исследование алгоритмических методов трассировки печатных соединений.

    курсовая работа [663,0 K], добавлен 24.03.2014

  • Использование алгоритмов машинной графики для разработки модели прозрачных и отражающих объектов. Визуальная оценка реалистичности изображения, эффектов отражения и преломления. Поиск отраженного и преломленного лучей. Описание интерфейса программы.

    курсовая работа [1,6 M], добавлен 04.06.2013

  • Интегрированная среда программирования C++ Builder 6. Методы вычерчивания графических примитивов. Основные свойства инструментов рисования. Разработка рисунка паутины с центром в точке с произвольным числом лучей. Алгоритм программы в виде блок-схемы.

    курсовая работа [842,5 K], добавлен 13.10.2017

  • Разработка программного продукта, который выполняет демонстрацию явления преломления лучей на границе раздела двух сред. Функциональные требования к программному продукту. Входные и выходные данные. Выбор языка программирования. Явление преломления света.

    курсовая работа [126,2 K], добавлен 29.01.2009

  • Методика и основные этапы проектирования логической и физической модели базы данных. Реализация спроектированной модели в системе управления базами данных, принципы создания и апробация специального клиентского приложения для работы данной программы.

    курсовая работа [1,3 M], добавлен 27.06.2013

  • Поняття трассировки та її значення в роботі комп'ютерного дизайнера. Розвиток інструментів трассировки в програмі Corel Drow. Способи та процеси векторної трассировки растрових зображень: автоматичне, ручне та утиліта, їх головні недоліки та привілеї.

    реферат [1,8 M], добавлен 30.05.2010

  • Реализация комплекса программ поиска подстроки в тексте алгоритмом прямого поиска и алгоритмом Кнута-Морриса-Пратта. Сравнительный анализ теоретических и экспериментальных оценок эффективности алгоритмов. Разработка структуры программы, ее листинг.

    курсовая работа [2,8 M], добавлен 22.01.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.