#include "ray.h" #include "map.h" #include <math.h> float v2_cross(v2 a, v2 b) { return fabs(a.x * b.y - a.y * b.x); } float v2_len(v2 a) { return sqrt(a.x * a.x + a.y * a.y); } float v2_dist(v2 a, v2 b) { return sqrt(v2_square_dist(a, b)); } float v2_square_dist(v2 a, v2 b) { return pow(a.x - b.x, 2) + pow(a.y - b.y, 2); } uint32_t cast_ray(v2 pos, float theta, v2* hit_pos) { const v2i move = { sign(cos(theta)), sign(sin(theta)), }; const v2i offset = { move.x == -1 ? 1 : 0, move.y == -1 ? 1 : 0 }; const float tanc = tan(theta); const float cotc = tan(PIH - (theta)); v2i posi = { (int)pos.x + offset.x, (int)pos.y + offset.y }; bool fx = false; uint32_t vx = 0; float x; while (!fx) { posi.y += move.y; x = cotc * (posi.y - pos.y) + pos.x; if (fabs(x) - pos.x >= MAP_SIZE) break; vx = value((int)x, posi.y - offset.y); if (vx != 0) { fx = true; } } bool fy = false; uint32_t vy = 0; float y; while (!fy) { posi.x += move.x; y = tanc * (posi.x - pos.x) + pos.y; if (fabs(y) - pos.y >= MAP_SIZE) break; vy = value(posi.x - offset.x, (int)y); if (vy != 0) { fy = true; } } uint32_t hit; if (!fx && !fy) { hit = 0; hit_pos->x = pos.x + 1000 * move.x; hit_pos->y = pos.y + 1000 * move.y; return false; } else if (fx && !fy) { hit = vx; hit_pos->x = x; hit_pos->y = posi.y; } else if (fy && !fx) { hit = vy; hit_pos->x = posi.x; hit_pos->y = y; } else { const v2 posx = {x, posi.y}; const v2 posy = {posi.x, y}; if (v2_square_dist(posx, pos) < v2_square_dist(posy, pos)) { hit = vx; hit_pos->x = x; hit_pos->y = posi.y; } else { hit = vy; hit_pos->x = posi.x; hit_pos->y= y; } } return hit; }