[update] Tidied codes to calculate distance between the origin and a line segment.

This commit is contained in:
falsycat 2019-10-15 00:00:00 +00:00
parent d36ee07b72
commit bd1c58f26e
2 changed files with 38 additions and 25 deletions

View File

@ -7,7 +7,8 @@ import std.algorithm,
import gl4d; import gl4d;
import sjplayer.ElementDrawer, import sjplayer.ElementDrawer,
sjplayer.ElementInterface; sjplayer.ElementInterface,
sjplayer.util.linalg;
/// ///
class CircleElement : ElementInterface { class CircleElement : ElementInterface {
@ -36,34 +37,14 @@ class CircleElement : ElementInterface {
if (!alive) return DamageCalculationResult(0, 0); if (!alive) return DamageCalculationResult(0, 0);
const m = matrix.inverse; const m = matrix.inverse;
const a = (m * vec3(p1, 1)).xy; const a = (m * vec3(p1, 1)).xy;
const b = (m * vec3(p2, 1)).xy; const b = (m * vec3(p2, 1)).xy;
const s = b - a; const d = CalculateDistanceOriginAndLineSegment(a, b);
const s_length = s.length; if (d <= 1) {
if (s_length == 0) { return DamageCalculationResult(damage, 0);
// TODO: nearness calculation
return DamageCalculationResult(a.length < 1? damage: 0, 0);
} }
return DamageCalculationResult(0, 1 - (d-1).clamp(0, 1));
const d = cross(vec3(s, 0), vec3(a, 0)).length / s_length;
if (d > 1) {
const nearness = (1 - (d-1).min(1f)).pow(2);
return DamageCalculationResult(0, nearness * nearness_coe);
}
const a_length = a.length;
const b_length = b.length;
const hit =
a.dot(s) * b.dot(s) <= 0 ||
a_length < 1 ||
b_length < 1;
if (hit) return DamageCalculationResult(damage, 0);
// TODO: nearness calculation
return DamageCalculationResult(0, 0);
} }
/// ///

View File

@ -0,0 +1,32 @@
/// License: MIT
module sjplayer.util.linalg;
import std.algorithm;
import gl4d;
///
float CalculateDistanceOriginAndLineSegment(vec2 a, vec2 b) {
const s = b - a;
const s_len = s.length;
if (s_len == 0) return a.length;
if (dot(a, s) * dot(b, s) < 0) {
return cross(vec3(s, 0), vec3(a, 0)).length / s_len;
}
return min(a.length, b.length);
}
///
unittest {
import std;
assert(CalculateDistanceOriginAndLineSegment(
vec2(0, 0), vec2(0, 0)).approxEqual(0f));
assert(CalculateDistanceOriginAndLineSegment(
vec2(-1, 1), vec2(1, 1)).approxEqual(1f));
assert(CalculateDistanceOriginAndLineSegment(
vec2(1, 1), vec2(2, 1)).approxEqual(sqrt(2f)));
assert(CalculateDistanceOriginAndLineSegment(
vec2(-2, 1), vec2(-1, 1)).approxEqual(sqrt(2f)));
}