[TypeScript] 제스처로 대화하기. #13 - 플릭(with. 범위) 편

고라니드로고라니드로
4 min read

이번 편은 이전 편으로부터 이어집니다.

플릭의 이동 범위를 제한하고 싶다면 어떻게 해야 할까요? 단순히 계산 시마다 대상이 유효한 범위 내에 있는지 확인할 수도 있을 것입니다. 하지만 이는 다소 비합리적으로 보일 수 있습니다. 우리는 조금 더 영리한 방법으로 이를 해결할 수 있습니다.

최대 변위

변위가 아래를 만족해야 한다고 합시다.

$$\begin{aligned} & s \leq k \end{aligned}$$

우리는 수식을 다음과 같이 전개할 수 있습니다.

$$\begin{aligned} & s = v_0t + \frac{1}{2}at^2 \leq k \\ & at^2 + 2v_0t - 2k \leq 0 \\ & a(t^2 + \frac{2}{a}v_0t - \frac{2}{a}k) \leq 0 \end{aligned}$$

만약 \(t^2 + \frac{2}{a}v_0t - \frac{2}{a}k = 0\) 이라면,

$$\begin{aligned} & t^2 + \frac{2}{a}v_0t - \frac{2}{a}k = 0 \\ & t^2 + \frac{2}{a}v_0t + (\frac{v_0}{a})^2 = (\frac{v_0}{a})^2 + \frac{2}{a}k \\ & (t + \frac{v_0}{a})^2 = (\frac{v_0}{a})^2 + \frac{2}{a}k \\ & t + \frac{v_0}{a} = \pm\sqrt{(\frac{v_0}{a})^2 + \frac{2}{a}k} \\ & t = -\frac{v_0}{a}\pm\sqrt{(\frac{v_0}{a})^2 + \frac{2}{a}k} \\ & t = -\frac{v_0\pm\sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

이므로,

$$a(t + \frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a})(t + \frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \leq 0$$

이다. 따라서 \(a < 0\) 일 경우,

$$\begin{aligned} & (t + \frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a})(t + \frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \geq 0 \\ & t \leq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a} \lor t \geq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

\(a \geq 0\) 일 경우,

$$\begin{aligned} & (t + \frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a})(t + \frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \leq 0 \\ & t \geq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a} \land t \leq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

그리고 \(0 \leq t \leq -\frac{v_0}{a}\) 이므로, \(a < 0\) 일 경우,

$$\begin{aligned} & 0 \leq t \leq min(-\frac{v_0}{a}, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \\ & 0 \leq t \leq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

\(a \geq 0\) 일 경우,

$$\begin{aligned} & max(0, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a}) \leq t \leq min(-\frac{v_0}{a}, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \\ & max(0, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a}) \leq t \leq -\frac{v_0}{a} \end{aligned}$$

최소 변위

\(s \geq k\) 인 경우에는 부등호 방향이 반대가 되므로 결과는 아래와 같습니다. \(a < 0\) 일 경우,

$$\begin{aligned} & (t + \frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a})(t + \frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \leq 0 \\ & t \geq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a} \land t \leq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

\(a \geq 0\) 일 경우,

$$\begin{aligned} & (t + \frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a})(t + \frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \geq 0 \\ & t \leq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a} \lor t \geq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

마찬가지로 \(0 \leq t \leq -\frac{v_0}{a}\) 이므로, \(a < 0\) 일 경우,

$$\begin{aligned} & max(0, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \leq t \leq min(-\frac{v_0}{a}, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a}) \\ & max(0, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak}}{a}) \leq t \leq -\frac{v_0}{a} \end{aligned}$$

\(a \geq 0\) 일 경우,

$$\begin{aligned} & 0 \leq t \leq min(-\frac{v_0}{a}, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a}) \\ & 0 \leq t \leq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak}}{a} \end{aligned}$$

\(t\)의 범위

따라서 \(t\)의 범위는 \(a < 0\) 일 경우,

$$\begin{aligned} & max(0, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak_{min}}}{a}) \leq t \leq min(-\frac{v_0}{a}, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak_{max}}}{a}) \\ & max(0, -\frac{v_0 - \sqrt{{v_0}^2 + 2ak_{min}}}{a}) \leq t \leq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak_{max}}}{a} \end{aligned}$$

\(a \geq 0\) 일 경우, 일 경우,

$$\begin{aligned} & max(0, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak_{max}}}{a}) \leq t \leq min(-\frac{v_0}{a}, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak_{min}}}{a}) \\ & max(0, -\frac{v_0 + \sqrt{{v_0}^2 + 2ak_{max}}}{a}) \leq t \leq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak_{min}}}{a} \end{aligned}$$

초기 시점 즉, \(t = 0\) 일 때, 대상이 유효 범위 내에 존재함을 가정하면 아래와 같이 단순화할 수 있습니다.

\(a < 0\) 일 경우,

$$t \leq -\frac{v_0 - \sqrt{{v_0}^2 + 2ak_{max}}}{a}$$

\(a \geq 0\) 일 경우,

$$t \leq -\frac{v_0 + \sqrt{{v_0}^2 + 2ak_{min}}}{a}$$

또 \({v_0}^2 + 2ak < 0\) 인 경우, 허근을 가지므로 어떠한 경우에도 경계에 도달할 수 없습니다. 따라서 아래와 같이 단순화할 수 있습니다.

$$t \leq -\frac{v_0}{a}$$

코드로 나타내면 다음과 같습니다.

function findDuration(
    initialVelocity: number,
    acceleration: number,
    minDisplacement: number,
    maxDisplacement: number
): number {
    if(acceleration === 0) { return Infinity; }

    let D = initialVelocity ** 2 +
        2 * acceleration * (
            acceleration < 0 ?
                maxDisplacement :
                minDisplacement
        );
    return D > 0 ?
        -(initialVelocity + Math.sign(acceleration) * Math.sqrt(D)) / acceleration :
        -initialVelocity / acceleration;
}

시리즈는 다음 편에서 계속됩니다. 읽어주셔서 감사합니다!

묻고 답하기

개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.

0
Subscribe to my newsletter

Read articles from 고라니드로 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

고라니드로
고라니드로