mirror of https://github.com/bjornbytes/lovr.git
Add Vec2/3/4:angle(other)
Functions to calculate the angle between two vectors. Angle is always positive. Implementations give the same result as this Lua code: ```lua local function lua_angle(v1, v2) return math.acos(v1:dot(v2) / (v1:length() * v2:length())) end ``` If either vector is zero-length, the pi/2 value is returned.
This commit is contained in:
parent
517b104c1e
commit
ef41e06fc9
|
@ -253,7 +253,7 @@ static int l_lovrVec2Distance(lua_State* L) {
|
|||
uvec[1] = luax_checkfloat(L, 3);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC2, NULL);
|
||||
u = luax_checkvector(L, 2, V_VEC2, "vec2 or number");
|
||||
}
|
||||
float dx = v[0] - u[0];
|
||||
float dy = v[1] - u[1];
|
||||
|
@ -270,7 +270,7 @@ static int l_lovrVec2Dot(lua_State* L) {
|
|||
uvec[1] = luax_checkfloat(L, 3);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC2, NULL);
|
||||
u = luax_checkvector(L, 2, V_VEC2, "vec2 or number");
|
||||
}
|
||||
lua_pushnumber(L, v[0] * u[0] + v[1] * u[1]);
|
||||
return 1;
|
||||
|
@ -287,7 +287,7 @@ static int l_lovrVec2Lerp(lua_State* L) {
|
|||
u = uvec;
|
||||
t = luax_checkfloat(L, 4);
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC2, NULL);
|
||||
u = luax_checkvector(L, 2, V_VEC2, "vec2 or number");
|
||||
t = luax_checkfloat(L, 3);
|
||||
}
|
||||
v[0] = v[0] + (u[0] - v[0]) * t;
|
||||
|
@ -296,6 +296,29 @@ static int l_lovrVec2Lerp(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec2Angle(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC2, NULL);
|
||||
float* u;
|
||||
float uvec[2];
|
||||
float dot, length_v, length_u;
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
uvec[0] = lua_tonumber(L, 2);
|
||||
uvec[1] = luax_checkfloat(L, 3);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC2, "vec2 or number");
|
||||
}
|
||||
length_v = sqrtf(v[0] * v[0] + v[1] * v[1]);
|
||||
length_u = sqrtf(u[0] * u[0] + u[1] * u[1]);
|
||||
if ((length_v == 0.f) || (length_u == 0.f)) {
|
||||
lua_pushnumber(L, (float) M_PI / 2);
|
||||
} else {
|
||||
dot = v[0] * u[0] + v[1] * u[1];
|
||||
lua_pushnumber(L, acosf(dot / (length_v * length_u)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec2__add(lua_State* L) {
|
||||
float* out = luax_newtempvector(L, V_VEC2);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
|
@ -497,6 +520,7 @@ const luaL_Reg lovrVec2[] = {
|
|||
{ "distance", l_lovrVec2Distance },
|
||||
{ "dot", l_lovrVec2Dot },
|
||||
{ "lerp", l_lovrVec2Lerp },
|
||||
{ "angle", l_lovrVec2Angle },
|
||||
{ "__add", l_lovrVec2__add },
|
||||
{ "__sub", l_lovrVec2__sub },
|
||||
{ "__mul", l_lovrVec2__mul },
|
||||
|
@ -687,6 +711,22 @@ static int l_lovrVec3Lerp(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec3Angle(lua_State* L) {
|
||||
vec3 v = luax_checkvector(L, 1, V_VEC3, NULL);
|
||||
vec3 u;
|
||||
float uvec[4];
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
uvec[0] = lua_tonumber(L, 2);
|
||||
uvec[1] = luax_checkfloat(L, 3);
|
||||
uvec[2] = luax_checkfloat(L, 4);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC3, "vec3 or number");
|
||||
}
|
||||
lua_pushnumber(L, vec3_angle(v, u));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec3__add(lua_State* L) {
|
||||
vec3 out = luax_newtempvector(L, V_VEC3);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
|
@ -891,6 +931,7 @@ const luaL_Reg lovrVec3[] = {
|
|||
{ "dot", l_lovrVec3Dot },
|
||||
{ "cross", l_lovrVec3Cross },
|
||||
{ "lerp", l_lovrVec3Lerp },
|
||||
{ "angle", l_lovrVec3Angle },
|
||||
{ "__add", l_lovrVec3__add },
|
||||
{ "__sub", l_lovrVec3__sub },
|
||||
{ "__mul", l_lovrVec3__mul },
|
||||
|
@ -1039,7 +1080,7 @@ static int l_lovrVec4Distance(lua_State* L) {
|
|||
uvec[3] = luax_checkfloat(L, 5);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
}
|
||||
float dx = v[0] - u[0];
|
||||
float dy = v[1] - u[1];
|
||||
|
@ -1060,7 +1101,7 @@ static int l_lovrVec4Dot(lua_State* L) {
|
|||
uvec[3] = luax_checkfloat(L, 5);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
}
|
||||
lua_pushnumber(L, v[0] * u[0] + v[1] * u[1] + v[2] * u[2] + v[3] * u[3]);
|
||||
return 1;
|
||||
|
@ -1079,7 +1120,7 @@ static int l_lovrVec4Lerp(lua_State* L) {
|
|||
u = uvec;
|
||||
t = luax_checkfloat(L, 6);
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC4, NULL);
|
||||
u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
t = luax_checkfloat(L, 3);
|
||||
}
|
||||
v[0] = v[0] + (u[0] - v[0]) * t;
|
||||
|
@ -1090,6 +1131,31 @@ static int l_lovrVec4Lerp(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4Angle(lua_State* L) {
|
||||
float* v = luax_checkvector(L, 1, V_VEC4, NULL);
|
||||
float* u;
|
||||
float uvec[4];
|
||||
float dot, length_v, length_u;
|
||||
if (lua_type(L, 2) == LUA_TNUMBER) {
|
||||
uvec[0] = lua_tonumber(L, 2);
|
||||
uvec[1] = luax_checkfloat(L, 3);
|
||||
uvec[2] = luax_checkfloat(L, 4);
|
||||
uvec[3] = luax_checkfloat(L, 5);
|
||||
u = uvec;
|
||||
} else {
|
||||
u = luax_checkvector(L, 2, V_VEC4, "vec4 or number");
|
||||
}
|
||||
length_v = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
|
||||
length_u = sqrtf(u[0] * u[0] + u[1] * u[1] + u[2] * u[2] + u[3] * u[3]);
|
||||
if ((length_v == 0.f) || (length_u == 0.f)) {
|
||||
lua_pushnumber(L, (float) M_PI / 2);
|
||||
} else {
|
||||
dot = v[0] * u[0] + v[1] * u[1] + v[2] * u[2] + v[3] * u[3];
|
||||
lua_pushnumber(L, acosf(dot / (length_v * length_u)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrVec4__add(lua_State* L) {
|
||||
float* out = luax_newtempvector(L, V_VEC4);
|
||||
if (lua_type(L, 1) == LUA_TNUMBER) {
|
||||
|
@ -1329,6 +1395,7 @@ const luaL_Reg lovrVec4[] = {
|
|||
{ "distance", l_lovrVec4Distance },
|
||||
{ "dot", l_lovrVec4Dot },
|
||||
{ "lerp", l_lovrVec4Lerp },
|
||||
{ "angle", l_lovrVec4Angle },
|
||||
{ "__add", l_lovrVec4__add },
|
||||
{ "__sub", l_lovrVec4__sub },
|
||||
{ "__mul", l_lovrVec4__mul },
|
||||
|
|
|
@ -122,6 +122,15 @@ MAF vec3 vec3_max(vec3 v, const vec3 u) {
|
|||
return v;
|
||||
}
|
||||
|
||||
MAF float vec3_angle(const vec3 v, const vec3 u) {
|
||||
float denom = vec3_length(v) * vec3_length(u);
|
||||
if (denom == 0.f) {
|
||||
return (float) M_PI / 2;
|
||||
} else {
|
||||
return acosf(vec3_dot(v, u) / denom);
|
||||
}
|
||||
}
|
||||
|
||||
// quat
|
||||
|
||||
MAF quat quat_set(quat q, float x, float y, float z, float w) {
|
||||
|
|
Loading…
Reference in New Issue