[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 sjplayer.ElementDrawer,
|
||||
sjplayer.ElementInterface;
|
||||
sjplayer.ElementInterface,
|
||||
sjplayer.util.linalg;
|
||||
|
||||
///
|
||||
class CircleElement : ElementInterface {
|
||||
@ -36,34 +37,14 @@ class CircleElement : ElementInterface {
|
||||
if (!alive) return DamageCalculationResult(0, 0);
|
||||
|
||||
const m = matrix.inverse;
|
||||
|
||||
const a = (m * vec3(p1, 1)).xy;
|
||||
const b = (m * vec3(p2, 1)).xy;
|
||||
const s = b - a;
|
||||
const d = CalculateDistanceOriginAndLineSegment(a, b);
|
||||
|
||||
const s_length = s.length;
|
||||
if (s_length == 0) {
|
||||
// TODO: nearness calculation
|
||||
return DamageCalculationResult(a.length < 1? damage: 0, 0);
|
||||
if (d <= 1) {
|
||||
return DamageCalculationResult(damage, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
return DamageCalculationResult(0, 1 - (d-1).clamp(0, 1));
|
||||
}
|
||||
|
||||
///
|
||||
|
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