#apply
#include "../_include.txt"
#include "../../define/_vector2.txt"

/*
@param
円の中心点x
y
移動後の中心点x
y
半径
線分の始点x
y
線分の終点x
y
半径

@return
衝突時間 (-1:衝突なし)
円の中心点x
y
法線x
y
衝突点x
y
*/
cev[CEV_CIRCLE_TO_SEGMENT] .name(">>>>動く円と静止する線の衝突") bl {
    defv {
        r_time = TV_RETURN
        r_cx1
        r_cy1
        r_nx
        r_ny
        r_hx
        r_hy

        a_sx1 = TV_CIRCLE_TO_CIRCLE
        a_sy1
        a_ex1
        a_ey1
        a_ra1
        a_sx2
        a_sy2
        a_ex2
        a_ey2
        a_ra2

        sumRad
        time
        mag
        magSq
        alpha
        beta
        omega
        judge
        ex
        ey
        vx
        vy
        rx
        ry
        ax
        ay
        bx
        by//28
    }

    //返り値を初期化
    r_time = -1

    //半径の合計
    sumRad = a_ra1 + a_ra2

    //簡易判定
    V2_ifRectOverlap_ex(a_sx1, a_ex1, a_sx2, a_ex2, sumRad,
    EMPTY_BLOCK, ABORT_BLOCK)

    //線分の長さがゼロの場合、衝突しない
    V2_ifEqual(a_sx2, a_ex2, ABORT_BLOCK)

    //E, V*mag, R, magSq
    V2_sub(ex, a_ex1, a_sx1)
    V2_sub(vx, a_ex2, a_sx2)
    V2_sub(rx, a_sx2, a_sx1)
    V2_magSq(magSq, vx)

    //A
    V2_dot(beta, ex, vx, 1)
    V2_math( bl { v[$a] = muldiv(v[$v], beta, magSq) - v[$e] },
        bl {
            $a = $i + __id(ax)
            $v = $i + __id(vx)
            $e = $i + __id(ex)
        }
    )

    //B
    V2_dot(beta, rx, vx, 1)
    V2_math( bl { v[$b] = v[$r] - muldiv(v[$v], beta, magSq) },
        bl {
            $b = $i + __id(bx)
            $v = $i + __id(vx)
            $r = $i + __id(rx)
        }
    )

    //alpha, beta, omega, judge
    V2_magSq(alpha, ax)
    V2_dot(beta, ax, bx, 1)
    omega = bx * bx + by * by - sumRad * sumRad
    judge = beta * beta - alpha * omega

    //めりこんでいる
    @if omega < 0 bl {
        time = 0

    } .else bl {
        //衝突していないか、止まっている
        @if `abs(alpha) <= 0 || judge < 0 ABORT_BLOCK

        //衝突時間
        time = muldiv(sqrt(judge, 1) + beta, UNIT_SECOND, alpha) * -1

        //衝突時刻が範囲外にあるか
        @if `time < 0 || UNIT_SECOND < time ABORT_BLOCK

    }

    //平方根を取得
    mag = sqrt(magSq, 1)

    //衝突した瞬間の円の座標
    V2_lerp(r_cx1, a_sx1, a_ex1, time, UNIT_SECOND)

    //線分の始点と衝突後の中心点までのベクトル
    V2_sub(ax, r_cx1, a_sx2)

    //衝突後の中心点から線分上の衝突点までの距離
    V2_dot(alpha, vx, ax, 1)
    beta = muldiv(alpha / mag, UNIT_SECOND, mag)

    //直線上の点が線分上にあるか
    @if `beta < 0 || UNIT_SECOND < beta ABORT_BLOCK

    //線分上の衝突点
    V2_lerp(r_hx, a_sx2, a_ex2, beta, UNIT_SECOND)

    //法線
    V2_cross(alpha, vx, ax, 1)//回転方向
    beta = alpha >= 0 ? 1 : -1

    //線分を90度回転させ、正規化する事で法線を作る
    r_nx = muldiv(-vy, UNIT_NORMAL, mag) * beta
    r_ny = muldiv( vx, UNIT_NORMAL, mag) * beta

    //めり込みを修正する
    @if time <= 0 bl {
        beta = sumRad - abs(alpha / mag)
        V2_asAddMuldiv(r_cx1, r_nx, beta, UNIT_NORMAL)

    }

    //衝突時間を返す
    r_time = time

}