static bool line_line_intersection(vec2 a0, vec2 a1, vec2 b0, vec2 b1) { #if 1 // Implemented based on http://stackoverflow.com/a/17198094/4354008 vec2 v = vec2_sub(a0, a1); vec2 normal = vec2_new(v.y, -v.x); vec2 v0 = vec2_sub(b0, a0); vec2 v1 = vec2_sub(b1, a0); float proj0 = vec2_dot(v0, normal); float proj1 = vec2_dot(v1, normal); if ((proj0 == 0) || (proj1 == 0)) return true; // TODO: float_sign() if ((proj0 > 0) && (proj1 < 0)) return true; if ((proj0 < 0) && (proj1 > 0)) return true; return false; #else vec2 intersection = vec2_zero(); vec2 b = vec2_sub(a1, a0); vec2 d = vec2_sub(b1, b0); float b_dot_p_perp = (b.x * d.y) - (b.y * d.x); if (b_dot_p_perp == 0) return false; vec2 c = vec2_sub(b0, a0); float t = ((c.x * d.y) - (c.y * d.x)) / b_dot_p_perp; if ((t < 0) || (t > 1)) return false; float u = ((c.x * b.y) - (c.y * b.x)) / b_dot_p_perp; if ((u < 0) || (u > 1)) return false; // TODO: make this an output parameter intersection = vec2_add(a0, vec2_mul(b, t)); return true; #endif }
static float get_angle(const float a0[2], const float a1[2], const float b0[2], const float b1[2]) { float u[2], v[2], dot, det; vec2_sub(a1, a0, u); vec2_normalize(u, u); vec2_sub(b1, b0, v); vec2_normalize(v, v); dot = vec2_dot(u, v); det = vec2_cross(u, v); return atan2(det, dot); }
///////////////////////////// // Input_GetDir // // Reports the direction of the dpad. int Input_GetDir(vec2 dir) { float vlen; Uint8 buttons; int mx, my; float dlen; extern int _width, _height; // Get mouse state buttons = SDL_GetMouseState(&mx, &my); if (buttons) { // Use the mouse vec2_set(dir, mx - (_width / 2), my - (_height / 2.0f)); dlen = 1.0f / sqrtf(vec2_dot(dir, dir)); vec2_scale(dir, dir, dlen); return (1); } else { // Use the keyboar vec2_set(dir, 0.0f, 0.0f); if (Input_GetKey(InputKey_Up)) { dir[1] -= 1.0f; } if (Input_GetKey(InputKey_Down)) { dir[1] += 1.0f; } if (Input_GetKey(InputKey_Left)) { dir[0] -= 1.0f; } if (Input_GetKey(InputKey_Right)) { dir[0] += 1.0f; } vlen = vec2_dot(dir, dir); if (vlen > 0.0f) { vlen = sqrtf(vlen); vec2_scale(dir, dir, 1.0f / vlen); return (1); } else { return (0); } } }
static int _llfunc_vec2_dot(lua_State *L) { vec2 *a = (vec2*)userdata_get_or_die(L, 1); vec2 *b = (vec2*)userdata_get_or_die(L, 2); lua_pushnumber(L, vec2_dot(a, b)); return 1; }