[update] Tidied codes to calculate distance between the origin and a line segment.
This commit is contained in:
parent
d36ee07b72
commit
bd1c58f26e
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
32
sjplayer/src/sjplayer/util/linalg.d
Normal file
32
sjplayer/src/sjplayer/util/linalg.d
Normal 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)));
|
||||||
|
}
|
Reference in New Issue
Block a user