I've been building a really simple raycaster in hopes of having a better understanding on how they work. Unfortunately I learn a lot bette from tinkering than reading (permadi would be a goldmine otherwise). Through my tinkering I've ironed out a lot of bugs, but a few persist:

And here is a slightly different angle where it matches a hit:

And here's a large scale example:

I've drawn white points on all the edges it detects, and the ray is yellow if it collides with anything solid. Here's the method that drives the rays movement:
def next_edge(self):
#extends to next edge intersection, horizontal or vertical.
side = 'NS'
size = 32
ray_slope = [ math.cos(math.radians(self.angle)) + 0.0001, -math.sin(math.radians(self.angle) + 0.0001) ]
step_dir = [1 if x >= 0 else -1 for x in ray_slope]
map_position = [int(math.ceil(x / float(32) ) ) for x in self.position] # snap to grid
if self.moved:
edge_position = [ map_position[0] + step_dir[0] , map_position[1] + step_dir[1] ]
else:
edge_position = [ map_position[0], map_position[1] ]
self.moved = True
#delta should never be < 0, and we shouldn't have a floating point position.
dx = abs( edge_position[0] * size - self.position[0] )
dy = abs( edge_position[1] * size - self.position[1] )
#length of the change that will be made
distx = math.sqrt( dx * dx + ( dx * ray_slope[1] / ray_slope[0] ) * ( dx * ray_slope[1] / ray_slope[0] ) )
disty = math.sqrt( dy * dy + ( dy * ray_slope[0] / ray_slope[1] ) * ( dy * ray_slope[0] / ray_slope[1] ) )
print distx, disty,
print edge_position, self.position
print self.angle
if distx > disty:
#use disty
# [ dx = dy * delx/dely , dy + (alignment for grid)]
delta_position = [ dy * step_dir[1] * ray_slope[0] / ray_slope[1], dy * step_dir[1] + step_dir[1] ]
self.position = [x+y for x,y in zip(delta_position, self.position)]
else:
#use distx
delta_position = [ dx * step_dir[0] + step_dir[0], dx * step_dir[0] * ray_slope[1] / ray_slope[0] ]
self.position = [x+y for x,y in zip(delta_position, self.position)]
diff = [math.fabs(x-y) for x,y in zip(self.position, self.start)]
self.length = math.sqrt( diff[0] + diff[1] )
return self.position, side
I'm used to working with multiple eyes on my code for my job, so I figure this might be the best way for me to just get a sense at what I'm doing. If anything looks extremely alient to the process please point it out
