**comp.graphics.algorithms**

## Subject: **Re: Understanding raytracing code**

On Mon, 15 May 2006 19:54:12 GMT, john

>This code will generate a "hole" that is mapped with a texture.

>The resolution is 320x200. And I see that the code loops through

>every pixel, and calculates some map that will be stored in

>textcoord. But I don't understand how the hole is created. So

>I would really appreciate if someone could explain this for me.

>Thanks!

Starting at beginning of the loop:

float dx = (float)i / 200;

float dy = (float)-j / 200;

float dz = 1;

Here it computes the direction of a ray originating somewhere behind

the image, centered in the x, y plane. Imagine if you could look at

each pixel of the screen, this code gets the direction towards each

pixel (in turn). I'll call this the view vector.

float d = 20 / sqrt(dx*dx + dy*dy + 1);

dx *= d;

dy *= d;

dz *= d;

The comment for the above code is a bit missleading, as it does not

normalize the view vector to unit length, but to a length of 20. More

on that in a bit.

// continue until we hit a wall

while (((x-get_x_pos(z))*(x-get_x_pos(z))+(y-get_y_pos(z))*

(y-get_y_pos(z)) < get_radius(z)) && (z<1024)) {

x += dx;

y += dy;

z += dz;

}

Here's the meat of the thing. It starts out in the origin (ala the

position of you eyes), and then moves in the direction of the view

vector, each step the same length as the length of the view vector.

Now, the assumtion here is that the origin is located inside the

cylinder you're viewing, and that the cylinder is aligned along the z

direction. Now, this cylinder is basically a bunch of circles stacked

on top of each other. The walls of the cylinder is defined by the

circle.

Now, to find out if you're inside a circle, all you need to do is

compute the distance from you to the center of the circle, basic

pythagoras: sqrt(sqr(px-cx)+sqr(py-cy)) if (px, py) is your current

position and (cx, cy) is the center of the circle. If this distance is

less than the radius of the circle, you're inside.

This is what the above code does. The code allows for the center of

the circle to vary as a function of z, so it gets the center for the

current z value. Then it subtracts the current (x, y) position from

this and squares.

Now, since it doesnt actually USE the distance to the center directly,

only to compare, it doesn't have to compute the square root. If

sqrt(a) < b, square both sides and you get a < b^2 (since a is always

positive).

It then gets the radius for the current z value (which would then

actually be the radius squared), and checks if the current position is

inside the circle at the current z position. It also makes sure that

the z value is not larger than the length of the cylinder.

The pseudo code for the above block would be something like:

while (inside circle at this z && not beyond length of cylinder) {

move in the direction of the view vector,

by the lenght of the view vector

}

Now, once this while loop is done, its either outside the cylinder

walls or beyond the end of the cylinder.

x -= dx; dx /= 2;

y -= dy; dy /= 2;

z -= dz; dz /= 2;

d -= 1;

So what it does then is to undo the last step by moving back, and then

make the view vector length half of its previous value. This makes it

move half the distance in the while loop above. It also decreases a

counter which keeps track of how many such undo's it's allowed to

make. This is to prevent it from going on forever (as the dx/2 etc

could eventually become 0 and it wouldn't go anywhere, becomming stuck

outside the walls).

Once it has done this 16 times, it's bound to be fairly close to the

cylinder wall (as you started out with a steplength of 20, and it has

been halved 16 times, the last steps would be about 0.0003)

x -= get_x_pos(z);

y -= get_y_pos(z);

float ang = atan2(y, x) * 256 / M_PI;

unsigned char u = (unsigned char)ang;

unsigned char v = (unsigned char)z;

Here it makes (x, y) relative to the center of the circle for the

current z value, and uses trigonometry to compute the angle to the

current position. The angle is used as one texture coordinate and the

z as the other. The result is as if you had wrapped a picture around

the cylinder.

It then stores the texture coordinates for each pixel in an array,

which i presume it uses later to draw the texture onto the screen.

Hope it helps

- Asbjørn

Reply

View All Messages in

**comp.graphics.algorithms**

path:

Understanding raytracing code =>

Replies:

Re: Understanding raytracing code

Copyright © 2006 WatermarkFactory.com. All Rights Reserved.