Skip to main content
gamedev.net
🔒 Locked

Bresenham's Algorithm + Ray Casting Help

Started by fpsgamer Jun 3, 2006 at 3:53 PM 0 replies 3.1k views
Original Post
fpsgamer
fpsgamer
I am trying to use Bresenham line algo to detect walls in my ray caster but I am getting unexpected results. Some walls seem to extend past where they are spposed to as well as a few other strange anomalies. In the function I have a vector called "ray_direction" which I use to increment the rays's position vector in the world untill it hits a wall. Here is screen cap: :( And of course here is what is its supposed to look like: :) And here is the algo: -ray_direction is a vector represented by a struct with two members which are floats (x,y); -there comes a point where I have to put the two floats x and y into integers so I multiply them by 10000 so to give them some significant digits for when they are truncated. -map[][] of course is the world map

void Trace_Ray(){
        int dx,dy,dx2,dy2,x_inc, y_inc, error;

	dx = ray_direction.x * 10000; //dx and dy are ints so scale the vector!
	dy = ray_direction.y * 10000;

	if(dx >= 0) //rate of change of x is positive
		x_inc = 1;
	else{	//rate of change of x is negative
		x_inc = -1;
		dx = abs(dx);
	}

	if(dy >= 0) //rate of change of y is positive
		y_inc = 1;
	else{	//rate of change of y is negative
		y_inc = -1;
		dy = abs(dy);
	}

	dx2 = dx << 1; //multiply by 2
	dy2 = dy << 1; //multiply by 2

	hit = NO_HIT;
	if(dx > dy){ //x-major
		error = dy2 - dx;
		while(1){
			if(error >= 0){
				error-=dx2;
				map_y+=y_inc;
				if(map[map_x][map_y] > 0){hit = HIT_Y_SIDE; break;}
			}
			error+=dy2;
			map_x+=x_inc;
			if(map[map_x][map_y] > 0){ hit = HIT_X_SIDE; break;}
		}
	}else{		//y-major
		error = dx2 - dy;
		while(1){
			if(error >= 0){
				error-=dy2;
				map_x+=x_inc;
				if(map[map_x][map_y] > 0){hit = HIT_X_SIDE;break;}
			}
			error+=dx2;
			map_y+=y_inc;
			if(map[map_x][map_y] > 0){ hit = HIT_Y_SIDE; break;}
		}
	}
}






Rockoon1
Rockoon1
Bresenhams algorithm isnt useful for raycasting.

What you need is a "supercover" line algorithm, which can simply be based off a modified bresenham.. such as http://lifc.univ-fcomte.fr/~dedu/projects/bresenham/

And then, if this is a 2D raycaster ala Wolf3D and such, you need to modify that so that you get the actual intercept point.

Far better, if this is a Wolf3D style engine, is to simply scan all x-intercepts until you hit a wall, and then all y-intercepts until you hit a wall, and then return the closest of the two. Modern processors are so overpowered for this sort of thing that you don't even have to consider optimisations.


Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.