#include "jp/ggaf/lib/util/StgUtil.h"

#include "jp/ggaf/core/actor/ex/ActorDepository.h"
#include "jp/ggaf/dx/actor/FigureActor.h"
#include "jp/ggaf/dx/actor/supporter/VecDriver.h"
#include "jp/ggaf/dx/util/Input.h"
#include "jp/ggaf/lib/LibConfig.h"
#include "jp/ggaf/lib/util/StgUtil.h"
#include "jp/ggaf/lib/util/CollisionChecker2D.h"
#include "jp/ggaf/lib/util/CollisionChecker3D.h"
#include "jp/ggaf/lib/util/ColliSphere.h"
#include "jp/ggaf/lib/util/ColliAAPrism.h"
#include "jp/ggaf/lib/util/ColliAAPyramid.h"



using namespace GgafLib;

bool StgUtil::_was_StgUtil_inited_flg = false;
float StgUtil::ROOT_1_MINUS_XX[1000];
uint32_t StgUtil::BITNUM[33];
std::map<pos_t,pos_t> StgUtil::POS_R_TRIANGLE_inv_X;
std::map<pos_t,pos_t> StgUtil::POS_R_TRIANGLE_inv_Y;


#define C_INT64(X)  ( (int_fast64_t)((X) * (1.0 / LEN_UNIT)) )


void StgUtil::init() {
    GgafDx::Util::init();
    if (StgUtil::_was_StgUtil_inited_flg) {
        return;
    }

    //ROOT_1_MINUS_XX偺愝掕
    for (int i = 0; i < 1000; i++) {
        StgUtil::ROOT_1_MINUS_XX[i] = sqrt(1.0 - ((double)i/1000.0) * ((double)i/1000.0));
    }

    BITNUM[0] = (uint32_t)0;
    for (int i = 1; i < 33; i++) {
        BITNUM[i] = ((uint32_t)1 << (i-1));
    }

    StgUtil::POS_R_TRIANGLE_inv_X[POS_R_TRIANGLE_NN] = POS_R_TRIANGLE_PN;
    StgUtil::POS_R_TRIANGLE_inv_X[POS_R_TRIANGLE_NP] = POS_R_TRIANGLE_PP;
    StgUtil::POS_R_TRIANGLE_inv_X[POS_R_TRIANGLE_PN] = POS_R_TRIANGLE_NN;
    StgUtil::POS_R_TRIANGLE_inv_X[POS_R_TRIANGLE_PP] = POS_R_TRIANGLE_NP;

    StgUtil::POS_R_TRIANGLE_inv_Y[POS_R_TRIANGLE_NN] = POS_R_TRIANGLE_NP;
    StgUtil::POS_R_TRIANGLE_inv_Y[POS_R_TRIANGLE_NP] = POS_R_TRIANGLE_NN;
    StgUtil::POS_R_TRIANGLE_inv_Y[POS_R_TRIANGLE_PN] = POS_R_TRIANGLE_PP;
    StgUtil::POS_R_TRIANGLE_inv_Y[POS_R_TRIANGLE_PP] = POS_R_TRIANGLE_PN;

    StgUtil::_was_StgUtil_inited_flg = true;
}

GgafDx::Checker* StgUtil::createChecker(GgafDx::GeometricActor* prm_pActor) {
    if (CONFIG::IS_HIT_CHECK_3D) {
        return NEW CollisionChecker3D(prm_pActor);
    } else {
        return NEW CollisionChecker2D(prm_pActor);
    }
}

bool StgUtil::isHit3D(const GgafDx::GeometricActor* const pActor01, const ColliSphere* const pSphere01 ,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere* const pSphere02 ) {
    //亙媴 偲 媴亜
    //媴1 丗 拞怱揰偺嵗昗P1(x1, y1, z1), 敿宎r1
    //媴2 丗 拞怱揰偺嵗昗P2(x2, y2, z2), 敿宎r2
    //(x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 <= (r1+r2)^2
    double dx = (double)( (pActor02->_x+pSphere02->_cx) - (pActor01->_x+pSphere01->_cx) );
    double dy = (double)( (pActor02->_y+pSphere02->_cy) - (pActor01->_y+pSphere01->_cy) );
    double dz = (double)( (pActor02->_z+pSphere02->_cz) - (pActor01->_z+pSphere01->_cz) );
    double dd = dx*dx + dy*dy + dz*dz;
    if (dd <= (double)(pSphere02->_r + pSphere01->_r) * (double)(pSphere02->_r + pSphere01->_r)
    ) {
        return true;
    } else {
        return false;
    }
}

bool StgUtil::isHit3D(const GgafDx::GeometricActor* const pActor01, const ColliAABox*  pAABox01,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere* pSphere02) {
    //亙AAB 偲 媴亜
    const coord o_scx = pActor02->_x + pSphere02->_cx;
    const coord o_scy = pActor02->_y + pSphere02->_cy;
    const coord o_scz = pActor02->_z + pSphere02->_cz;
    const coord bx1 = pActor01->_x + pAABox01->_x1;
    const coord bx2 = pActor01->_x + pAABox01->_x2;
    const coord by1 = pActor01->_y + pAABox01->_y1;
    const coord by2 = pActor01->_y + pAABox01->_y2;
    const coord bz1 = pActor01->_z + pAABox01->_z1;
    const coord bz2 = pActor01->_z + pAABox01->_z2;

    double square_length = 0; //媴偺拞怱偲AAB偺嵟抁嫍棧傪擇忔偟偨抣
    if(o_scx < bx1) {
        square_length += (double)(o_scx - bx1) * (o_scx - bx1);
    }
    if(o_scx > bx2) {
        square_length += (double)(o_scx - bx2) * (o_scx - bx2);
    }

    if(o_scy < by1) {
        square_length += (double)(o_scy - by1) * (o_scy - by1);
    }
    if(o_scy > by2) {
        square_length += (double)(o_scy - by2) * (o_scy - by2);
    }

    if(o_scz < bz1) {
        square_length += (double)(o_scz - bz1) * (o_scz - bz1);
    }
    if(o_scz > bz2) {
        square_length += (double)(o_scz - bz2) * (o_scz - bz2);
    }
    //仾偺敾掕偑慡偰僴僘儗偰丄square_length == 0 側傜偽丄
    //媴偺拞怱偑丄BOX撪偵偁傞偲偄偆堄枴偵側傞丅

    //square_length偑媴偺敿宎乮偺擇忔乯傛傝傕抁偗傟偽徴撍偟偰偄傞
    if (square_length <= pSphere02->_rr) {
        return true;
    } else {
        return false;
    }
}


bool StgUtil::isHit3D(const GgafDx::GeometricActor* const pActor01, const ColliAAPrism* const pAAPrism01,
                      const GgafDx::GeometricActor* const pActor02, const ColliAABox*   const pAABox02     ) {
    //亙僾儕僘儉 偲 AAB亜
    const coord aX = pActor01->_x;
    const coord aY = pActor01->_y;
    const coord aZ = pActor01->_z;
    const coord aX1 = aX + pAAPrism01->_x1;
    const coord aY1 = aY + pAAPrism01->_y1;
    const coord aZ1 = aZ + pAAPrism01->_z1;
    const coord aX2 = aX + pAAPrism01->_x2;
    const coord aY2 = aY + pAAPrism01->_y2;
    const coord aZ2 = aZ + pAAPrism01->_z2;
    const coord bX1 = pActor02->_x + pAABox02->_x1;
    const coord bY1 = pActor02->_y + pAABox02->_y1;
    const coord bZ1 = pActor02->_z + pAABox02->_z1;
    const coord bX2 = pActor02->_x + pAABox02->_x2;
    const coord bY2 = pActor02->_y + pAABox02->_y2;
    const coord bZ2 = pActor02->_z + pAABox02->_z2;

    if (aZ2 >= bZ1 && aZ1 <= bZ2 && aY2 >= bY1 && aY1 <= bY2 && aX2 >= bX1 && aX1 <= bX2) {
        //偙偺帪揰偱AAB 偲 AAB 側傜偽僸僢僩
        const int pos = pAAPrism01->_pos_info;
        const double a = pAAPrism01->_a;
        if (pos & POS_PRISM_XY_xx) { //XY暯柺僗儔僀僗偺僾儕僘儉
            //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = y - ax
            const double b = ((aY+pAAPrism01->_cy) - pAAPrism01->_a * (aX+pAAPrism01->_cx)) + pAAPrism01->_b;

            if (pos & POS_PRISM_xx_PP) {
                //            仾 y+
                //
                //        劇劅劅劅劉
                //        劆乢偙偪劆
                // x- 仼  劆丂乢傜劆  仺 x+
                //      劇劑仜丂乢劆
                //      劆劋劑劅劅劊
                //      劋劅劊
                //            伀 y-
                //
                //僾儕僘儉嫬奅慄 y = ax + b 偲
                //仜偺嵗昗(bX2, bY2)丄偲偺埵抲娭學傪峫偊傞
                //y > ax + b 偱偁傟偽僸僢僩
                if (bY2 > a * bX2 +  b) {
                    return true;
                }

            } else if (pos & POS_PRISM_xx_NP) {
                //            仾 y+
                //
                //        劇劅劅劅劉
                //        劆偙偪乛劆
                // x- 仼  劆傜乛丂劆  仺 x+
                //        劆乛丂仜劑劉
                //        劋劅劅劑劊劆Opp
                //              劋劅劊
                //            伀 y-
                //
                //僾儕僘儉嫬奅慄 y = ax + b 偲
                //仜偺嵗昗(bX1, bY2)丄偲偺埵抲娭學傪峫偊傞
                //y > ax + b 偱偁傟偽僸僢僩
                if (bY2 > a * bX1 +  b) {
                    return true;
                }

            } else if (pos & POS_PRISM_xx_PN) {
                //            仾 y+
                //      劇劅劉
                //      劆劇劑劅劅劉
                //      劋劑仜丂乛劆
                // x- 仼  劆丂乛偙劆  仺 x+
                //        劆乛偪傜劆
                //        劋劅劅劅劊
                //
                //            伀 y-
                //
                //僾儕僘儉嫬奅慄 y = ax + b 偲
                //仜偺嵗昗(bX2, bY1)丄偲偺埵抲娭學傪峫偊傞
                //y < ax + b 偱偁傟偽僸僢僩
                if (bY1 < a * bX2 +  b) {
                    return true;
                }

            } else { // 偺偙傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
                //            仾 y+
                //              劇劅劉
                //        劇劅劅劑劉劆Opp
                //        劆乢丂仜劑劊
                // x- 仼  劆偙乢丂劆  仺 x+
                //        劆偪傜乢劆
                //        劋劅劅劅劊
                //
                //            伀 y-
                //
                //僾儕僘儉嫬奅慄 y = ax + b 偲
                //仜偺嵗昗(bX1, bY1)丄偲偺埵抲娭學傪峫偊傞
                //y < ax + b 偱偁傟偽僸僢僩
                if (bY1 < a * bX1 +  b) {
                    return true;
                }


            }
        } else if (pos & POS_PRISM_YZ_xx) {//YZ暯柺僗儔僀僗偺僾儕僘儉
            //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = z - ay
            int b = ((aZ+pAAPrism01->_cz) - pAAPrism01->_a * (aY+pAAPrism01->_cy)) + pAAPrism01->_b;
            if (pos & POS_PRISM_xx_PP) {
                //            仾 z+
                //
                //        劇劅劅劅劉
                //        劆乢偙偪劆
                // y- 仼  劆丂乢傜劆  仺 y+
                //      劇劑仜丂乢劆
                //      劆劋劑劅劅劊
                //      劋劅劊
                //            伀 z-
                //
                //僾儕僘儉嫬奅慄 z = ay + b 偲
                //仜偺嵗昗(bY2, bZ2)丄偲偺埵抲娭學傪峫偊傞
                //z > ay + b 偱偁傟偽僸僢僩
                if (bZ2 > a * bY2 +  b) {
                    return true;
                }

            } else if (pos & POS_PRISM_xx_NP) {
                //            仾 z+
                //
                //        劇劅劅劅劉
                //        劆偙偪乛劆
                // y- 仼  劆傜乛丂劆  仺 y+
                //        劆乛丂仜劑劉
                //        劋劅劅劑劊劆Opp
                //              劋劅劊
                //            伀 z-
                //
                //僾儕僘儉嫬奅慄 z = ay + b 偲
                //仜偺嵗昗(bY1, bZ2)丄偲偺埵抲娭學傪峫偊傞
                //z > ay + b 偱偁傟偽僸僢僩
                if (bZ2 > a * bY1 +  b) {
                    return true;
                }

            } else if (pos & POS_PRISM_xx_PN) {
                //            仾 z+
                //      劇劅劉
                //      劆劇劑劅劅劉
                //      劋劑仜丂乛劆
                // y- 仼  劆丂乛偙劆  仺 y+
                //        劆乛偪傜劆
                //        劋劅劅劅劊
                //
                //            伀 z-
                //
                //僾儕僘儉嫬奅慄 z = ay + b 偲
                //仜偺嵗昗(bY2, bZ1)丄偲偺埵抲娭學傪峫偊傞
                //z < ay + b 偱偁傟偽僸僢僩
                if (bZ1 < a * bY2 +  b) {
                    return true;
                }

            } else { //偺偙傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
                //            仾 z+
                //              劇劅劉
                //        劇劅劅劑劉劆Opp
                //        劆乢丂仜劑劊
                // y- 仼  劆偙乢丂劆  仺 y+
                //        劆偪傜乢劆
                //        劋劅劅劅劊
                //
                //            伀 z-
                //
                //僾儕僘儉嫬奅慄 z = ay + b 偲
                //仜偺嵗昗(bY1, bZ1)丄偲偺埵抲娭學傪峫偊傞
                //z < ay + b 偱偁傟偽僸僢僩
                if (bZ1 < a * bY1 +  b) {
                    return true;
                }
            }

        } else if (pos & POS_PRISM_ZX_xx) {
            //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = x - az
            int b = ((aX+pAAPrism01->_cx) - pAAPrism01->_a * (aZ+pAAPrism01->_cz)) + pAAPrism01->_b;
            if (pos & POS_PRISM_xx_PP) {
                //            仾 x+
                //
                //        劇劅劅劅劉
                //        劆乢偙偪劆
                // z- 仼  劆丂乢傜劆  仺 z+
                //      劇劑仜丂乢劆
                //      劆劋劑劅劅劊
                //      劋劅劊
                //            伀 x-
                //
                //僾儕僘儉嫬奅慄 x = az + b 偲
                //仜偺嵗昗(bZ2, bX2)丄偲偺埵抲娭學傪峫偊傞
                //x > az + b 偱偁傟偽僸僢僩
                if (bX2 > a * bZ2 +  b) {
                    return true;
                }

            } else if (pos & POS_PRISM_xx_NP) {
                //            仾 x+
                //
                //        劇劅劅劅劉
                //        劆偙偪乛劆
                // z- 仼  劆傜乛丂劆  仺 z+
                //        劆乛丂仜劑劉
                //        劋劅劅劑劊劆Opp
                //              劋劅劊
                //            伀 x-
                //
                //僾儕僘儉嫬奅慄 x = az + b 偲
                //仜偺嵗昗(bZ1, bX2)丄偲偺埵抲娭學傪峫偊傞
                //x > az + b 偱偁傟偽僸僢僩
                if (bX2 > a * bZ1 +  b) {
                    return true;
                }

            } else if (pos & POS_PRISM_xx_PN) {
                //            仾 x+
                //      劇劅劉
                //      劆劇劑劅劅劉
                //      劋劑仜丂乛劆
                // z- 仼  劆丂乛偙劆  仺 z+
                //        劆乛偪傜劆
                //        劋劅劅劅劊
                //
                //            伀 x-
                //
                //僾儕僘儉嫬奅慄 x = az + b 偲
                //仜偺嵗昗(bZ2, bX1)丄偲偺埵抲娭學傪峫偊傞
                //x < az + b 偱偁傟偽僸僢僩
                if (bX1 < a * bZ2 +  b) {
                    return true;
                }

            } else { //巆傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
                //            仾 x+
                //              劇劅劉
                //        劇劅劅劑劉劆Opp
                //        劆乢丂仜劑劊
                // z- 仼  劆偙乢丂劆  仺 z+
                //        劆偪傜乢劆
                //        劋劅劅劅劊
                //
                //            伀 x-
                //
                //僾儕僘儉嫬奅慄 x = az + b 偲
                //仜偺嵗昗(bZ1, bX1)丄偲偺埵抲娭學傪峫偊傞
                //x < az + b 偱偁傟偽僸僢僩
                if (bX1 < a * bZ1 +  b) {
                    return true;
                }
            }
        }
    }
    return false;
}


bool StgUtil::isHit3D(const GgafDx::GeometricActor* const pActor01, const ColliAAPrism* const pAAPrism01,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere*  const pSphere02  ) {
    //亙僾儕僘儉 偲 媴亜
    //MEMO:尩枾側摉偨傝敾掕寁嶼偼峴偭偰偄傑偣傫丅
    //傑偢丄媴 懳 AAB 偺敾掕傪峴偆
    const coord aX = pActor01->_x;
    const coord aY = pActor01->_y;
    const coord aZ = pActor01->_z;
    const coord o_scx = pActor02->_x + pSphere02->_cx;
    const coord o_scy = pActor02->_y + pSphere02->_cy;
    const coord o_scz = pActor02->_z + pSphere02->_cz;
    const coord aX1 = aX + pAAPrism01->_x1;
    const coord aY1 = aY + pAAPrism01->_y1;
    const coord aZ1 = aZ + pAAPrism01->_z1;
    const coord aX2 = aX + pAAPrism01->_x2;
    const coord aY2 = aY + pAAPrism01->_y2;
    const coord aZ2 = aZ + pAAPrism01->_z2;
    double square_length = 0; //媴偺拞怱偲AAB偺嵟抁嫍棧傪擇忔偟偨抣
    if(o_scx < aX1) {
        square_length += (double)(o_scx - aX1) * (o_scx - aX1);
    }
    if(o_scx > aX2) {
        square_length += (double)(o_scx - aX2) * (o_scx - aX2);
    }
    if(o_scy < aY1) {
        square_length += (double)(o_scy - aY1) * (o_scy - aY1);
    }
    if(o_scy > aY2) {
        square_length += (double)(o_scy - aY2) * (o_scy - aY2);
    }
    if(o_scz < aZ1) {
        square_length += (double)(o_scz - aZ1) * (o_scz - aZ1);
    }
    if(o_scz > aZ2) {
        square_length += (double)(o_scz - aZ2) * (o_scz - aZ2);
    }
    //square_length偑媴偺敿宎乮偺擇忔乯傛傝傕抁偗傟偽徴撍偟偰偄傞
    if (square_length > pSphere02->_rr) {
        return false;
    }
    //偙偺帪揰偱AAB 懳 媴偱僸僢僩丅偙偙偐傜僾儕僘儉偱傕僸僢僩偐専徹偡傞

    const int pos = pAAPrism01->_pos_info;
    const double a = pAAPrism01->_a;
    if (pos & POS_PRISM_XY_xx) { //XY暯柺僗儔僀僗偺僾儕僘儉
        //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = y - ax
        const double b = ((aY+pAAPrism01->_cy) - pAAPrism01->_a * (aX+pAAPrism01->_cx)) + pAAPrism01->_b;

        int oppX, oppY;
        const int bZc = o_scz; //媴偺拞怱Z嵗昗
        if (aZ1 < bZc && bZc < aZ2) {
            //媴偺拞怱Z嵗昗偑僾儕僘儉偺Z暆斖埻撪側傜偽丄梊傔曐帩偟偰偄傞_vIH_x,_vIH_y傪巊梡偟偰
            //僾儕僘儉幬曈偲嵟抁嫍棧偺墌廃忋偺XY嵗昗傪媮傔傞
            oppX = o_scx + pAAPrism01->_vIH_x * pSphere02->_r;
            oppY = o_scy + pAAPrism01->_vIH_y * pSphere02->_r;
        } else if (bZc >= aZ2) {
            //媴偺拞怱Z嵗昗偑僾儕僘儉偺Z暆斖埻奜偺応崌
            //棧傟傞嫍棧偵墳偠偰丄媴懁偺敿宎(pSphere02->_r)傪彫偝偔偟偰嵎暘傪寁嶼
            //彫偝偔偡傞妱崌偼 ROOT_1_MINUS_XX (1/4墌偺夝偺僥乕僽儖攝楍乯傪巊梡丅
            //                 |
            //                 乢
            //        劇劅劅劅劉 `劅
            // z- 仼  劆      劆  仺 z+
            int r = pSphere02->_r * UTIL::ROOT_1_MINUS_XX[(int)((1.0*(bZc - aZ2) / pSphere02->_r)*1000)];
            oppX = o_scx + pAAPrism01->_vIH_x * r;
            oppY = o_scy + pAAPrism01->_vIH_y * r;
        } else { //if (aZ1 >= bZc) {
            int r = pSphere02->_r * UTIL::ROOT_1_MINUS_XX[(int)((1.0*(aZ1 - bZc) / pSphere02->_r)*1000)];
            oppX = o_scx + pAAPrism01->_vIH_x * r;
            oppY = o_scy + pAAPrism01->_vIH_y * r;
        }

        if (pos & POS_PRISM_xx_PP) {
            //            仾 y+
            //
            //        劇劅劅劅劉
            //        劆乢偙偪劆
            // x- 仼  劆丂乢傜劆  仺 x+
            //       ,劑仜丂乢劆
            //      劆劋劑劅劅劊
            //       `劅'
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX2, bY2)丄偲偺埵抲娭學傪峫偊傞
            //y > ax + b 偱偁傟偽僸僢僩
            if (oppY > a * oppX +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_NP) {
            //            仾 y+
            //
            //        劇劅劅劅劉
            //        劆偙偪乛劆
            // x- 仼  劆傜乛丂劆  仺 x+
            //        劆乛丂仜劑丄
            //        劋劅劅劑劊劆Opp
            //               `劅'
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX1, bY2)丄偲偺埵抲娭學傪峫偊傞
            //y > ax + b 偱偁傟偽僸僢僩
            if (oppY > a * oppX +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_PN) {
            //            仾 y+
            //       ,劅丄
            //      劆劇劑劅劅劉
            //       `劑仜丂乛劆
            // x- 仼  劆丂乛偙劆  仺 x+
            //        劆乛偪傜劆
            //        劋劅劅劅劊
            //
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX2, bY1)丄偲偺埵抲娭學傪峫偊傞
            //y < ax + b 偱偁傟偽僸僢僩
            if (oppY < a * oppX +  b) {
                return true;
            }

        } else { // 偺偙傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
            //            仾 y+
            //               ,劅丄
            //        劇劅劅劑劉劆Opp
            //        劆乢丂仜劑'
            // x- 仼  劆偙乢丂劆  仺 x+
            //        劆偪傜乢劆
            //        劋劅劅劅劊
            //
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX1, bY1)丄偲偺埵抲娭學傪峫偊傞
            //y < ax + b 偱偁傟偽僸僢僩
            if (oppY < a * oppX +  b) {
                return true;
            }


        }
    } else if (pos & POS_PRISM_YZ_xx) {//YZ暯柺僗儔僀僗偺僾儕僘儉
        //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = z - ay
        const int b = ((aZ+pAAPrism01->_cz) - pAAPrism01->_a * (aY+pAAPrism01->_cy)) + pAAPrism01->_b;
        int oppY, oppZ;

        const int bXc = o_scx;
        if (aX1 < bXc && bXc < aX2) {
            oppY = o_scy + pAAPrism01->_vIH_x * pSphere02->_r;
            oppZ = o_scz + pAAPrism01->_vIH_y * pSphere02->_r;
        } else {
            if (bXc >= aX2) {
                int r = pSphere02->_r * UTIL::ROOT_1_MINUS_XX[(int)((1.0*(bXc - aX2) / pSphere02->_r)*1000)];
                oppY = o_scy + pAAPrism01->_vIH_x * r;
                oppZ = o_scz + pAAPrism01->_vIH_y * r;
            } else if (aX1 >= bXc) {
                int r = pSphere02->_r * UTIL::ROOT_1_MINUS_XX[(int)((1.0*(aX1 - bXc) / pSphere02->_r)*1000)];
                oppY = o_scy + pAAPrism01->_vIH_x * r;
                oppZ = o_scz + pAAPrism01->_vIH_y * r;
            }
        }
        if (pos & POS_PRISM_xx_PP) {
            //            仾 z+
            //
            //        劇劅劅劅劉
            //        劆乢偙偪劆
            // y- 仼  劆丂乢傜劆  仺 y+
            //       ,劑仜丂乢劆
            //      劆劋劑劅劅劊
            //       `劅'
            //            伀 z-
            //
            //僾儕僘儉嫬奅慄 z = ay + b 偲
            //仜偺嵗昗(bY2, bZ2)丄偲偺埵抲娭學傪峫偊傞
            //z > ay + b 偱偁傟偽僸僢僩
            if (oppZ > a * oppY +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_NP) {
            //            仾 z+
            //
            //        劇劅劅劅劉
            //        劆偙偪乛劆
            // y- 仼  劆傜乛丂劆  仺 y+
            //        劆乛丂仜劑丄
            //        劋劅劅劑劊劆Opp
            //               `劅'
            //            伀 z-
            //
            //僾儕僘儉嫬奅慄 z = ay + b 偲
            //仜偺嵗昗(bY1, bZ2)丄偲偺埵抲娭學傪峫偊傞
            //z > ay + b 偱偁傟偽僸僢僩
            if (oppZ > a * oppY +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_PN) {
            //            仾 z+
            //       ,劅丄
            //      劆劇劑劅劅劉
            //       `劑仜丂乛劆
            // y- 仼  劆丂乛偙劆  仺 y+
            //        劆乛偪傜劆
            //        劋劅劅劅劊
            //
            //            伀 z-
            //
            //僾儕僘儉嫬奅慄 z = ay + b 偲
            //仜偺嵗昗(bY2, bZ1)丄偲偺埵抲娭學傪峫偊傞
            //z < ay + b 偱偁傟偽僸僢僩
            if (oppZ < a * oppY +  b) {
                return true;
            }

        } else { //偺偙傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
            //            仾 z+
            //               ,劅丄
            //        劇劅劅劑劉劆Opp
            //        劆乢丂仜劑'
            // y- 仼  劆偙乢丂劆  仺 y+
            //        劆偪傜乢劆
            //        劋劅劅劅劊
            //
            //            伀 z-
            //
            //僾儕僘儉嫬奅慄 z = ay + b 偲
            //仜偺嵗昗(bY1, bZ1)丄偲偺埵抲娭學傪峫偊傞
            //z < ay + b 偱偁傟偽僸僢僩
            if (oppZ < a * oppY +  b) {
                return true;
            }
        }

    } else if (pos & POS_PRISM_ZX_xx) {
        //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = x - az
        const int b = ((aX+pAAPrism01->_cx) - pAAPrism01->_a * (aZ+pAAPrism01->_cz)) + pAAPrism01->_b;
        int oppZ,oppX;
        const int bYc = o_scy;
        if (aY1 < bYc && bYc < aY2) {
            oppZ = o_scz + pAAPrism01->_vIH_x * pSphere02->_r;
            oppX = o_scx + pAAPrism01->_vIH_y * pSphere02->_r;
        } else {
            if (bYc >= aY2) {
                int r = pSphere02->_r * UTIL::ROOT_1_MINUS_XX[(int)((1.0*(bYc - aY2) / pSphere02->_r)*1000)];
                oppZ = o_scz + pAAPrism01->_vIH_x * r;
                oppX = o_scx + pAAPrism01->_vIH_y * r;
            } else if (aY1 >= bYc) {
                int r = pSphere02->_r * UTIL::ROOT_1_MINUS_XX[(int)((1.0*(aY1 - bYc) / pSphere02->_r)*1000)];
                oppZ = o_scz + pAAPrism01->_vIH_x * r;
                oppX = o_scx + pAAPrism01->_vIH_y * r;
            }
        }
        if (pos & POS_PRISM_xx_PP) {
            //            仾 x+
            //
            //        劇劅劅劅劉
            //        劆乢偙偪劆
            // z- 仼  劆丂乢傜劆  仺 z+
            //       ,劑仜丂乢劆
            //      劆劋劑劅劅劊
            //       `劅'
            //            伀 x-
            //
            //僾儕僘儉嫬奅慄 x = az + b 偲
            //仜偺嵗昗(bZ2, bX2)丄偲偺埵抲娭學傪峫偊傞
            //x > az + b 偱偁傟偽僸僢僩
            if (oppX > a * oppZ +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_NP) {
            //            仾 x+
            //
            //        劇劅劅劅劉
            //        劆偙偪乛劆
            // z- 仼  劆傜乛丂劆  仺 z+
            //        劆乛丂仜劑丄
            //        劋劅劅劑劊劆Opp
            //               `劅'
            //            伀 x-
            //
            //僾儕僘儉嫬奅慄 x = az + b 偲
            //仜偺嵗昗(bZ1, bX2)丄偲偺埵抲娭學傪峫偊傞
            //x > az + b 偱偁傟偽僸僢僩
            if (oppX > a * oppZ +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_PN) {
            //            仾 x+
            //       ,劅丄
            //      劆劇劑劅劅劉
            //       `劑仜丂乛劆
            // z- 仼  劆丂乛偙劆  仺 z+
            //        劆乛偪傜劆
            //        劋劅劅劅劊
            //
            //            伀 x-
            //
            //僾儕僘儉嫬奅慄 x = az + b 偲
            //仜偺嵗昗(bZ2, bX1)丄偲偺埵抲娭學傪峫偊傞
            //x < az + b 偱偁傟偽僸僢僩
            if (oppX < a * oppZ +  b) {
                return true;
            }

        } else { //巆傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
            //            仾 x+
            //               ,劅丄
            //        劇劅劅劑劉劆Opp
            //        劆乢丂仜劑'
            // z- 仼  劆偙乢丂劆  仺 z+
            //        劆偪傜乢劆
            //        劋劅劅劅劊
            //
            //            伀 x-
            //
            //僾儕僘儉嫬奅慄 x = az + b 偲
            //仜偺嵗昗(bZ1, bX1)丄偲偺埵抲娭學傪峫偊傞
            //x < az + b 偱偁傟偽僸僢僩
            if (oppX < a * oppZ +  b) {
                return true;
            }
        }
    }
    return false;
}

bool StgUtil::isHit3D(const GgafDx::GeometricActor* const pActor01, const ColliAAPyramid* const pAAPyramid01,
                      const GgafDx::GeometricActor* const pActor02, const ColliAABox*     const pAABox02     ) {
    //僺儔儈僢僪偲BOX
    const coord aX1 = pActor01->_x + pAAPyramid01->_x1;
    const coord aY1 = pActor01->_y + pAAPyramid01->_y1;
    const coord aZ1 = pActor01->_z + pAAPyramid01->_z1;
    const coord aX2 = pActor01->_x + pAAPyramid01->_x2;
    const coord aY2 = pActor01->_y + pAAPyramid01->_y2;
    const coord aZ2 = pActor01->_z + pAAPyramid01->_z2;
    //幬柺偺朄慄
    float a = pAAPyramid01->_s_nvx;
    float b = pAAPyramid01->_s_nvy;
    float c = pAAPyramid01->_s_nvz;
    //幬柺偲懳妏慄偺岎揰
    const coord px = pActor01->_x + pAAPyramid01->_l_px;
    const coord py = pActor01->_y + pAAPyramid01->_l_py;
    const coord pz = pActor01->_z + pAAPyramid01->_l_pz;

    const coord bX1 = pActor02->_x + pAABox02->_x1;
    const coord bY1 = pActor02->_y + pAABox02->_y1;
    const coord bZ1 = pActor02->_z + pAABox02->_z1;
    const coord bX2 = pActor02->_x + pAABox02->_x2;
    const coord bY2 = pActor02->_y + pAABox02->_y2;
    const coord bZ2 = pActor02->_z + pAABox02->_z2;


    if (aX2 >= bX1 && aX1 <= bX2 && aZ2 >= bZ1 && aZ1 <= bZ2 && aY2 >= bY1 && aY1 <= bY2) {
        //偙偺帪揰偱AAB 偲 AAB 側傜偽僸僢僩

        //僺儔儈僢僪幬柺偵懳偟偰僺儔儈僢僪懁偺BOX椞堟撪偱丄憡庤BOX偺嵟嬤朤揰傪媮傔傞
        const pos_t pos_info = pAAPyramid01->_pos_info;
        coord nnx, nny, nnz; //BOX撪嵟嬤朤揰
        if (pos_info & POS_PYRAMID_Pxx) {
            //bX2偵嫽枴偑偁傞
            if (/* aX1 <= bX2 && */ bX2 <= aX2) {
                //bX2 偑拞偵偁傞
                nnx = bX2;
            } else { //if (aX2 < bX2) {
                //bX2 偑奜偵偁傞
                nnx = aX2;
            }
        } else {
            //bX1偵嫽枴偑偁傞
            if (aX1 <= bX1 /* && bX1 <= aX2*/ ) {
                //bX1 偑拞偵偁傞
                nnx = bX1;
            } else { // if (aX1 > bX1) {
                //bX1 偑奜偵偁傞
                nnx = aX1;
            }
        }
        if (pos_info & POS_PYRAMID_xPx) {
            //bY2偵嫽枴偑偁傞
            if (/* aY1 <= bY2 &&*/ bY2 <= aY2) {
                //bY2 偑拞偵偁傞
                nny = bY2;
            } else { //if (aY2 < bY2) {
                //bY2 偑奜偵偁傞
                nny = aY2;
            }
        } else {
            //bY1偵嫽枴偑偁傞
            if (aY1 <= bY1 /*&& bY1 <= aY2*/) {
                //by1 偑拞偵偁傞
                nny = bY1;
            } else { //if (aY1 > bY1) {
                //bx1 偑奜偵偁傞
                nny = aY1;
            }
        }

        if (pos_info & POS_PYRAMID_xxP) {
            //bZ2偵嫽枴偑偁傞
            if (/*aZ1 <= bZ2 &&*/ bZ2 <= aZ2) {
                //bZ2 偑拞偵偁傞
                nnz = bZ2;
            } else { //if (aZ2 < bZ2) {
                //bZ2 偑奜偵偁傞
                nnz = aZ2;
            }
        } else {
            //bZ1偵嫽枴偑偁傞
            if (aZ1 <= bZ1 /* && bZ1 <= aZ2*/) {
                //bz1 偑拞偵偁傞
                nnz = bZ1;
            } else { //if (aZ1 > bZ1) {
                //bx1 偑奜偵偁傞
                nnz = aZ1;
            }
        }
        //(nnx,nny,nnz) 偑BOX撪嬤朤揰
        //幬柺偺朄慄儀僋僩儖 (a, b, c)
        //幬柺忋偺揰(px, py, pz) 偐傜 嬤朤揰(nnx,nny,nnz) 偺儀僋僩儖
        // (nnx-px, nny-py, nnz-pz) 偺撪愊偑 晧 側傜偽嬤朤揰 (nnx,nny,nnz) 偑僺儔儈僢僪偺拞偵偁傞
        double d = a*(nnx-px) + b*(nny-py) + c*(nnz-pz);
        if (d < 0) {
            return true;
        } else {
            return false;
        }
    }
    return false;
}

bool StgUtil::isHit3D(const GgafDx::GeometricActor* const pActor01, const ColliAAPyramid* const pAAPyramid01,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere*    const pSphere02  ) {
    //嶰捈妏嶰妏悕偺嶰捈妏捀揰偺嵗昗傪尨揰(0,0,0)偵偍偒丄
    //A(ex,0,0), B(0,ey,0), C(0,0,ez) 偺嶰捈妏嶰妏悕偱摉偨傝敾掕傪峫偊偨偄偺偱丄
    //媴偺埵抲(o_cx, o_cy, o_cz)傪嵗昗曄姺偡傞丅

    const int_fast64_t ex = C_INT64(pAAPyramid01->_dx); //暆偑偦偺傑傑捀揰A偺X幉嵗昗偲側傞
    const int_fast64_t ey = C_INT64(pAAPyramid01->_dy); //崅偝偑偦偺傑傑捀揰B偺Y幉嵗昗偲側傞
    const int_fast64_t ez = C_INT64(pAAPyramid01->_dz); //墱峴偒偝偑偦偺傑傑捀揰C偺Z幉嵗昗偲側傞
    const int_fast64_t o_r  = C_INT64(pSphere02->_r);   //媴偺敿宎偼嵗昗曄姺偵柍塭嬁側偺偱偦偺傑傑
    const int_fast64_t o_rr = o_r*o_r;

    //杮棃偺媴偺埵抲
    int_fast64_t o_cx = C_INT64(pActor02->_x + pSphere02->_cx);
    int_fast64_t o_cy = C_INT64(pActor02->_y + pSphere02->_cy);
    int_fast64_t o_cz = C_INT64(pActor02->_z + pSphere02->_cz);
    const pos_t pos_info = pAAPyramid01->_pos_info; //嶰捈妏嶰妏悕偺巔惃忣曬
    if (pos_info & POS_PYRAMID_Pxx) {
        //尦偺嶰捈妏嶰妏悕偺捀揰偺X幉偼惓偺曽岦
        o_cx -= C_INT64(pActor01->_x + pAAPyramid01->_x2);
        o_cx = -o_cx; //x幉斀揮
    } else {
        //尦偺嶰捈妏嶰妏悕偺捀揰偺X幉偼晧偺曽岦
        o_cx -= C_INT64(pActor01->_x + pAAPyramid01->_x1);
    }
    if (pos_info & POS_PYRAMID_xPx) {
        //尦偺嶰捈妏嶰妏悕偺捀揰偺Y幉偼惓偺曽岦
        o_cy -= C_INT64(pActor01->_y + pAAPyramid01->_y2);
        o_cy = -o_cy; //y幉斀揮
    } else {
        //尦偺嶰捈妏嶰妏悕偺捀揰偺Y幉偼晧偺曽岦
        o_cy -= C_INT64(pActor01->_y + pAAPyramid01->_y1);
    }

    if (pos_info & POS_PYRAMID_xxP) {
        //尦偺嶰捈妏嶰妏悕偺捀揰偺Z幉偼惓偺曽岦
        o_cz -= C_INT64(pActor01->_z + pAAPyramid01->_z2);
        o_cz = -o_cz; //z幉斀揮
    } else {
        //尦偺嶰捈妏嶰妏悕偺捀揰偺Z幉偼晧偺曽岦
        o_cz -= C_INT64(pActor01->_z + pAAPyramid01->_z1);
    }
    //媴偺埵抲曄姺姰椆丄偙偙偐傜摉偨傝敾掕儘僕僢僋

    //xy暯柺傛傝撪(戞堦孴尷懁)偐
    const bool xy = (o_cz > 0);
    //yz暯柺傛傝撪(戞堦孴尷懁)偐
    const bool yz = (o_cx > 0);
    //zx暯柺傛傝撪(戞堦孴尷懁)偐
    const bool zx = (o_cy > 0);
    //xy暯柺偵暯峴側揰C傪捠傞暯柺(true:尨揰懁)
    const bool xy_C = (o_cz < ez);
    //yz暯柺偵暯峴側揰A傪捠傞暯柺(true:尨揰懁)
    const bool yz_A = (o_cx < ex);
    //zx暯柺偵暯峴側揰B傪捠傞暯柺(true:尨揰懁)
    const bool zx_B = (o_cy < ey);

    //媴懳BOX偺摉偨傝敾掕傪傑偢峴偆
    const int_fast64_t o_cx2 = o_cx*o_cx;
    const int_fast64_t o_cy2 = o_cy*o_cy;
    const int_fast64_t o_cz2 = o_cz*o_cz;
    const int_fast64_t o_cx_MINUS_ex2 = (o_cx - ex)*(o_cx - ex);
    const int_fast64_t o_cy_MINUS_ey2 = (o_cy - ey)*(o_cy - ey);
    const int_fast64_t o_cz_MINUS_ez2 = (o_cz - ez)*(o_cz - ez);
    int_fast64_t slength = 0; //媴偺拞怱偲AAB偺嵟抁嫍棧傪擇忔偟偨抣
    if (!yz) {
        slength += o_cx2;
    }
    if (!yz_A) {
        slength += o_cx_MINUS_ex2;
    }
    if (!zx) {
        slength += o_cy2;
    }
    if (!zx_B) {
        slength += o_cy_MINUS_ey2;
    }
    if (!xy) {
        slength += o_cz2;
    }
    if (!xy_C) {
        slength += o_cz_MINUS_ez2;
    }
    if (slength > o_rr) {
        //square_length 偑媴偺敿宎乮偺擇忔乯傛傝傕挿偗傟偽BOX偲偡傜徴撍偟偰偄側偄丅
        return false;
    }
    //偙偙偐傜埲崀偼丄媴 懳 BOX 偱徴撍偟偰偄傞偙偲偵側傞丅
    //嶰捈妏嶰妏悕偺偳偺晹暘乮捀揰丄曈丄柺乯偲偺嫍棧偱敾掕偡傟偽傛偄偐
    //応崌傢偗偱峫偊傞

    if (!xy && !yz && !zx) {
        //尨揰偲偺嫍棧偱敾掕
        //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
        return true;
    }

    if (xy) {
        if (!yz) {
            if (!zx) {
                if (xy_C) {
                    //曈OC偲偺嫍棧偱敾掕
                    //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
                    return true;
                }
            }
        }
    } else {
        if (yz) {
            if (!zx) {
                if (yz_A) {
                    //曈OA偲偺嫍棧偱敾掕
                    //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
                    return true;
                }
            }
        } else {
            if (zx) {
                if (zx_B) {
                    //曈OB偲偺嫍棧偱敾掕
                    //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
                    return true;
                }
            }
        }
    }

    const int_fast64_t exey = ex*ey;
    const int_fast64_t eyez = ey*ez;
    const int_fast64_t ezex = ez*ex;
    // A(ex,0,0), B(0,ey,0) 傪娷傓xy暯柺偵悅捈側柺傛傝撪乮尨揰偑偁傞懁乯
    const bool vxy_AB = (-ey*o_cx - ex*o_cy           + exey > 0);
    // B(0,ey,0), C(0,0,ez) 傪娷傓yz暯柺偵悅捈側柺傛傝撪乮尨揰偑偁傞懁乯
    const bool vyz_BC = (          -ez*o_cy - ey*o_cz + eyez > 0);
    // C(0,0,ez), A(ex,0,0) 傪娷傓zx暯柺偵悅捈側柺傛傝撪乮尨揰偑偁傞懁乯
    const bool vzx_CA = (-ez*o_cx           - ex*o_cz + ezex > 0);
    if (xy) {
        if (yz) {
            if (!zx) {
                if (vzx_CA) {
                    //柺OCA偲偺嫍棧偱敾掕
                    //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
                    return true;
                }

            }
        } else {
            if (zx) {
                if (vyz_BC) {
                    //柺OBC偲偺嫍棧偱敾掕
                    //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
                    return true;
                }
            }
        }
    } else {
        if (yz) {
            if (zx) {
                if (vxy_AB) {
                    //柺OAB偲偺嫍棧偱敾掕
                    //媴 懳 BOX 偱徴撍偟偰偄傞偺偱僸僢僩
                    return true;
                }
            }
        }
    }

    const int_fast64_t ex2 = ex*ex;
    const int_fast64_t ey2 = ey*ey;
    const int_fast64_t ez2 = ez*ez;
    //揰A偲曈AB偺嫬奅柺(true:尨揰懁)
    const bool bo_A_AB = ( ezex * o_cx - eyez * o_cy               - ex2*ez > 0);
    //揰A偲曈AC偺嫬奅柺(true:尨揰懁)
    const bool bo_A_AC = ( exey * o_cx               - eyez * o_cz - ey*ex2 > 0);
    //側偤偙偆側傞偺偐偼丄乽媴偲僺儔儈僢僪乮捀揰偲曈偺嫬奅柺乯乿嶲徠
    if (!yz_A && bo_A_AB && bo_A_AC) {
        //捀揰A偲偺嫍棧偱敾掕
        int_fast64_t length = o_cx_MINUS_ex2 + o_cy2 + o_cz2;
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }

    //揰B偲曈BA偺嫬奅柺(true:尨揰懁)
    const bool bo_B_BA = (-ezex * o_cx + eyez * o_cy               - ey2*ez > 0);
    //揰B偲曈BC偺嫬奅柺(true:尨揰懁)
    const bool bo_B_BC = (               exey * o_cy - ezex * o_cz - ey2*ex > 0);
    if (!zx_B && bo_B_BA && bo_B_BC) {
        //捀揰B偲偺嫍棧偱敾掕
        int_fast64_t length = o_cx2 + o_cy_MINUS_ey2 + o_cz2;
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }
    //揰C偲曈CA偺嫬奅柺(true:尨揰懁)
    const bool bo_C_CA = (-exey * o_cx               + eyez * o_cz - ey*ez2 > 0);
    //揰C偲曈CB偺嫬奅柺
    const bool bo_C_CB = (              -exey * o_cy + ezex * o_cz - ex*ez2 > 0);
    if (!xy_C && bo_C_CA && bo_C_CB) {
        //捀揰C偲偺嫍棧偱敾掕
        int_fast64_t length = o_cx2 + o_cy2 + o_cz_MINUS_ez2;
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }

    //A(ex,0,0), B(0,ey,0) 傪娷傓幬柺偵悅捈側柺傛傝撪乮尨揰偑偁傞懁乯
    bool vramp_AB = ((-ex*ey2)*o_cx      + (-ex2*ey)*o_cy      + (ez*(ex2+ey2))*o_cz + (ex2*ey2) > 0);
    //側偤偙偆側傞偺偐偼丄乽媴偲僺儔儈僢僪乮幬柺偲偺嫍棧偱敾掕偡傞斖埻乯乿嶲徠
    if (!vxy_AB && !bo_A_AB && !bo_B_BA && !vramp_AB) {
        //曈AB偲偺嫍棧偱敾掕
        // A(ex,0,0), B(0,ey,0)  傛傝
        // 曈AB偺捈慄偺幃偼
        //
        // 揰P(o_cx, o_cy, o_cz) 偲
        // AB傪捠傞捈慄l (x,y,z) = (ex,0,0) + t(-ex, ey, 0)偺嫍棧傪峫偊傞丅
        // 揰P偐傜捈慄l偵悅捈偵崀傠偟偨慄偺岎揰傪 H 偲偡傞偲丄揰H偼捈慄l忋側偺偱
        // 揰H(ex-t*ex, t*ey, 0) 偱偁傜傢偝傟傞
        //
        // |PH|^2 = ((ex-t*ex)-o_cx)^2 + (t*ey - o_cy)^2 + (0-o_cz)^2
        //
        // 偲偙傠偱丄AB偲PH偼悅捈側偺偱
        // (-ex, ey, 0)丒((ex-t*ex)-o_cx, t*ey-o_cy, -o_cz) = 0
        //
        // (-ex*((ex-t*ex)-o_cx)) + (ey*(t*ey-o_cy)) + (0) = 0
        // t=(ey*o_cy-ex*o_cx+ex^2)/(ey^2+ex^2)
        double t = (ey*o_cy - ex*o_cx + ex2) / double(ey2+ex2);
        int_fast64_t length = ((ex-t*ex)-o_cx)*((ex-t*ex)-o_cx) + (t*ey - o_cy)*(t*ey - o_cy) + o_cz2;
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }

    //B(0,ey,0) C(0,0,ez)  傪娷傓幬柺偵悅捈側柺傛傝撪乮尨揰偑偁傞懁乯
    bool vramp_BC = ((ex*(ey2+ez2))*o_cx + (-ey*ez2)*o_cy      + (-ey2*ez)*o_cz      + (ey2*ez2) > 0);
    if (!vyz_BC && !bo_B_BC && !bo_C_CB && !vramp_BC) {
        //曈BC偲偺嫍棧偱敾掕
        double t = (ez*o_cz - ey*o_cy + ey2) / double(ez2+ey2);
        int_fast64_t length = o_cx2 + ((ey-t*ey) - o_cy)*((ey-t*ey) - o_cy) + (t*ez - o_cz)*(t*ez - o_cz);
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }

    //C(0,0,ez) A(ex,0,0)  傪娷傓幬柺偵悅捈側柺傛傝撪乮尨揰偑偁傞懁乯
    bool vramp_CA = ((-ez2*ex)*o_cx      + (ey*(ez2+ex2))*o_cy + (-ez*ex2)*o_cz      + (ez2*ex2) > 0);
    if (!vzx_CA && !bo_A_AC && !bo_C_CA && !vramp_CA) {
        //曈CA偲偺嫍棧偱敾掕
        double t = (ex*o_cx - ez*o_cz + ez2) / double(ez2+ex2);
        int_fast64_t length = (t*ex-o_cx)*(t*ex-o_cx) + o_cy2 + ((ez-t*ez) - o_cz)*((ez-t*ez) - o_cz);
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }

    //幬柺傛傝奜偐乮尨揰偺柍偄懁乯
    int_fast64_t ramp_value = eyez*o_cx + ezex*o_cy + exey*o_cz - ex*ey*ez;
    bool ramp = (ramp_value > 0);
    if (vramp_AB && vramp_BC && vramp_CA && ramp) {
        //柺ABC偲偺嫍棧偱敾掕
        //墌偺拞怱偐傜幬柺偵崀傠偟偨悅慄偺岎揰(lx,ly,lz)傪媮傔傞
        //幬柺偼
        //a*x + b*y + c*z - ex*ey*ez = 0
        //悅慄偺曽掱幃偼
        //(x,y,z) = (o_cx,o_cy,o_cz) + t(a,b,c)
        // x = o_cx + t*a
        // y = o_cy + t*b
        // z = o_cz + t*c
        // t傪媮傔傞
        // a*(o_cx + t*a) + b*(o_cy + t*b) + c*(o_cz + t*c) - ex*ey*ez = 0
        // t=-(c*o_cz+b*o_cy+a*o_cx-ex*ey*ez)/(c^2+b^2+a^2)
        //幬柺偺曽掱幃偺梫慺

        //幬柺偺朄慄(a,b,c)
        //int_fast64_t a = eyez;
        //int_fast64_t b = ezex;
        //int_fast64_t c = exey;
        //double d = -(ex*ex*ez);
        //double t =-(a*o_cx + b*o_cy +c*o_cz - ex*ey*ez) / double(a*a + b*b + c*c);
        double t = -ramp_value / double(eyez*eyez + ezex*ezex + exey*exey);
        //岎揰偼
        int_fast64_t lx = o_cx + t*eyez;
        int_fast64_t ly = o_cy + t*ezex;
        int_fast64_t lz = o_cz + t*exey;
        //墌偺拞怱偐傜丄幬柺偵悅慄傪壓傠偟偨偲偒偺岎揰偲偺嫍棧(偺俀忔)
        int_fast64_t length = (o_cx-lx)*(o_cx-lx) + (o_cy-ly)*(o_cy-ly) + (o_cz-lz)*(o_cz-lz);
        if (length < o_rr) {
            return true;
        } else {
            return false;
        }
    }

    if (xy && yz && zx && !ramp) {
        //嶰妏悕撪晹
        return true;
    } else {
        _TRACE_("亙寈崘亜StgUtil::isHit3D() 悢抣斖埻偑僆乕僶乕僼儘乕偟偰丄惓偟偔敾掕偝傟偰偄傑偣傫丅");
    }

    return false;
}

bool StgUtil::isHit2D(const GgafDx::GeometricActor* const pActor01, const ColliSphere* const pSphere01 ,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere* const pSphere02 ) {
    //亙媴 偲 媴亜
    //媴1 丗 拞怱揰偺嵗昗P1(x1, y1, z1), 敿宎r1
    //媴2 丗 拞怱揰偺嵗昗P2(x2, y2, z2), 敿宎r2
    //(x2-x1)^2 + (y2-y1)^2 <= (r1+r2)^2
    double d2 = (double)((pActor02->_x+pSphere02->_cx) - (pActor01->_x+pSphere01->_cx)) * ((pActor02->_x+pSphere02->_cx) - (pActor01->_x+pSphere01->_cx)) +
                (double)((pActor02->_y+pSphere02->_cy) - (pActor01->_y+pSphere01->_cy)) * ((pActor02->_y+pSphere02->_cy) - (pActor01->_y+pSphere01->_cy));
    if (d2 <= (double)(pSphere02->_r + pSphere01->_r) * (pSphere02->_r + pSphere01->_r)
    ) {
        return true;
    } else {
        return false;
    }
}


bool StgUtil::isHit2D(const GgafDx::GeometricActor* const pActor01, const ColliAABox*  pAABox01,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere* pSphere02) {
    //亙AAB 偲 媴亜
    const coord o_scx = pActor02->_x + pSphere02->_cx;
    const coord o_scy = pActor02->_y + pSphere02->_cy;
    const coord bx1 = pActor01->_x + pAABox01->_x1;
    const coord bx2 = pActor01->_x + pAABox01->_x2;
    const coord by1 = pActor01->_y + pAABox01->_y1;
    const coord by2 = pActor01->_y + pAABox01->_y2;

    double square_length = 0; //媴偺拞怱偲AAB偺嵟抁嫍棧傪擇忔偟偨抣
    if(o_scx < bx1) {
        square_length += (double)(o_scx - bx1) * (o_scx - bx1);
    }
    if(o_scx > bx2) {
        square_length += (double)(o_scx - bx2) * (o_scx - bx2);
    }

    if(o_scy < by1) {
        square_length += (double)(o_scy - by1) * (o_scy - by1);
    }
    if(o_scy > by2) {
        square_length += (double)(o_scy - by2) * (o_scy - by2);
    }
    //square_length偑媴偺敿宎乮偺擇忔乯傛傝傕抁偗傟偽徴撍偟偰偄傞
    if (square_length <= pSphere02->_rr) {
        return true;
    } else {
        return false;
    }
}
bool StgUtil::isHit2D(const GgafDx::GeometricActor* const pActor01, const ColliAAPrism* const pAAPrism01,
                      const GgafDx::GeometricActor* const pActor02, const ColliAABox*   const pAABox02   ) {
    const coord aX1 = pActor01->_x + pAAPrism01->_x1;
    const coord aY1 = pActor01->_y + pAAPrism01->_y1;
    const coord aX2 = pActor01->_x + pAAPrism01->_x2;
    const coord aY2 = pActor01->_y + pAAPrism01->_y2;
    const coord bX1 = pActor02->_x + pAABox02->_x1;
    const coord bY1 = pActor02->_y + pAABox02->_y1;
    const coord bX2 = pActor02->_x + pAABox02->_x2;
    const coord bY2 = pActor02->_y + pAABox02->_y2;

    if (aY2 >= bY1 && aY1 <= bY2 && aX2 >= bX1 && aX1 <= bX2) {
        //偙偺帪揰偱AAB 偲 AAB 側傜偽僸僢僩
        const int pos = pAAPrism01->_pos_info;
        const double a = pAAPrism01->_a;
        const double b = ((pActor01->_y+pAAPrism01->_cy) - pAAPrism01->_a * (pActor01->_x+pAAPrism01->_cx)) + pAAPrism01->_b;
        if (pos & POS_PRISM_xx_PP) {
            //            仾 y+
            //
            //        劇劅劅劅劉
            //        劆乢偙偪劆
            // x- 仼  劆丂乢傜劆  仺 x+
            //      劇劑仜丂乢劆
            //      劆劋劑劅劅劊
            //      劋劅劊
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX2, bY2)丄偲偺埵抲娭學傪峫偊傞
            //y > ax + b 偱偁傟偽僸僢僩
            if (bY2 > a * bX2 +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_NP) {
            //            仾 y+
            //
            //        劇劅劅劅劉
            //        劆偙偪乛劆
            // x- 仼  劆傜乛丂劆  仺 x+
            //        劆乛丂仜劑劉
            //        劋劅劅劑劊劆Opp
            //              劋劅劊
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX1, bY2)丄偲偺埵抲娭學傪峫偊傞
            //y > ax + b 偱偁傟偽僸僢僩
            if (bY2 > a * bX1 +  b) {
                return true;
            }

        } else if (pos & POS_PRISM_xx_PN) {
            //            仾 y+
            //      劇劅劉
            //      劆劇劑劅劅劉
            //      劋劑仜丂乛劆
            // x- 仼  劆丂乛偙劆  仺 x+
            //        劆乛偪傜劆
            //        劋劅劅劅劊
            //
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX2, bY1)丄偲偺埵抲娭學傪峫偊傞
            //y < ax + b 偱偁傟偽僸僢僩
            if (bY1 < a * bX2 +  b) {
                return true;
            }

        } else { // 偺偙傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
            //            仾 y+
            //              劇劅劉
            //        劇劅劅劑劉劆Opp
            //        劆乢丂仜劑劊
            // x- 仼  劆偙乢丂劆  仺 x+
            //        劆偪傜乢劆
            //        劋劅劅劅劊
            //
            //            伀 y-
            //
            //僾儕僘儉嫬奅慄 y = ax + b 偲
            //仜偺嵗昗(bX1, bY1)丄偲偺埵抲娭學傪峫偊傞
            //y < ax + b 偱偁傟偽僸僢僩
            if (bY1 < a * bX1 +  b) {
                return true;
            }
        }
    }
    return false;
}
bool StgUtil::isHit2D(const GgafDx::GeometricActor* const pActor01, const ColliAAPrism* const pAAPrism01,
                      const GgafDx::GeometricActor* const pActor02, const ColliSphere*  const pSphere02  ) {
    //亙僾儕僘儉 偲 媴亜
    //MEMO:尩枾側摉偨傝敾掕寁嶼偼峴偭偰偄傑偣傫丅

    //傑偢丄媴 懳 AAB 偺敾掕傪峴偆
    const coord o_scx = pActor02->_x + pSphere02->_cx;
    const coord o_scy = pActor02->_y + pSphere02->_cy;
    const coord aX1 = pActor01->_x + pAAPrism01->_x1;
    const coord aY1 = pActor01->_y + pAAPrism01->_y1;
    const coord aX2 = pActor01->_x + pAAPrism01->_x2;
    const coord aY2 = pActor01->_y + pAAPrism01->_y2;
    double square_length = 0; //媴偺拞怱偲AAB偺嵟抁嫍棧傪擇忔偟偨抣
    if(o_scx < aX1) {
        square_length += (double)(o_scx - aX1) * (o_scx - aX1);
    }
    if(o_scx > aX2) {
        square_length += (double)(o_scx - aX2) * (o_scx - aX2);
    }
    if(o_scy < aY1) {
        square_length += (double)(o_scy - aY1) * (o_scy - aY1);
    }
    if(o_scy > aY2) {
        square_length += (double)(o_scy - aY2) * (o_scy - aY2);
    }
    //square_length偑媴偺敿宎乮偺擇忔乯傛傝傕抁偗傟偽徴撍偟偰偄傞
    if (square_length > pSphere02->_rr) {
        return false;
    }
    //偙偺帪揰偱AAB 懳 媴偱僸僢僩丅偙偙偐傜僾儕僘儉偱傕僸僢僩偐専徹偡傞

    const int pos = pAAPrism01->_pos_info;
    const double a = pAAPrism01->_a;
    //儚乕儖僪嵗昗偱偺僾儕僘儉嫬奅慄偺愗曅傪媮傔傞 b = y - ax
    const double b = ((pActor01->_y+pAAPrism01->_cy) - pAAPrism01->_a * (pActor01->_x+pAAPrism01->_cx)) + pAAPrism01->_b;

    //梊傔曐帩偟偰偄傞_vIH_x,_vIH_y傪巊梡偟偰
    //僾儕僘儉幬曈偲嵟抁嫍棧偺墌廃忋偺XY嵗昗傪媮傔傞
    int oppX = o_scx + pAAPrism01->_vIH_x * pSphere02->_r;
    int oppY = o_scy + pAAPrism01->_vIH_y * pSphere02->_r;
    if (pos & POS_PRISM_xx_PP) {
        //            仾 y+
        //
        //        劇劅劅劅劉
        //        劆乢偙偪劆
        // x- 仼  劆丂乢傜劆  仺 x+
        //       ,劑仜丂乢劆
        //      劆劋劑劅劅劊
        //       `劅'
        //            伀 y-
        //
        //僾儕僘儉嫬奅慄 y = ax + b 偲
        //仜偺嵗昗(bX2, bY2)丄偲偺埵抲娭學傪峫偊傞
        //y > ax + b 偱偁傟偽僸僢僩
        if (oppY > a * oppX +  b) {
            return true;
        }

    } else if (pos & POS_PRISM_xx_NP) {
        //            仾 y+
        //
        //        劇劅劅劅劉
        //        劆偙偪乛劆
        // x- 仼  劆傜乛丂劆  仺 x+
        //        劆乛丂仜劑丄
        //        劋劅劅劑劊劆Opp
        //               `劅'
        //            伀 y-
        //
        //僾儕僘儉嫬奅慄 y = ax + b 偲
        //仜偺嵗昗(bX1, bY2)丄偲偺埵抲娭學傪峫偊傞
        //y > ax + b 偱偁傟偽僸僢僩
        if (oppY > a * oppX +  b) {
            return true;
        }

    } else if (pos & POS_PRISM_xx_PN) {
        //            仾 y+
        //       ,劅丄
        //      劆劇劑劅劅劉
        //       `劑仜丂乛劆
        // x- 仼  劆丂乛偙劆  仺 x+
        //        劆乛偪傜劆
        //        劋劅劅劅劊
        //
        //            伀 y-
        //
        //僾儕僘儉嫬奅慄 y = ax + b 偲
        //仜偺嵗昗(bX2, bY1)丄偲偺埵抲娭學傪峫偊傞
        //y < ax + b 偱偁傟偽僸僢僩
        if (oppY < a * oppX +  b) {
            return true;
        }

    } else { // 偺偙傝偼 POS_PRISM_xx_NN 偺傒偱偁傞
        //            仾 y+
        //               ,劅丄
        //        劇劅劅劑劉劆Opp
        //        劆乢丂仜劑'
        // x- 仼  劆偙乢丂劆  仺 x+
        //        劆偪傜乢劆
        //        劋劅劅劅劊
        //
        //            伀 y-
        //
        //僾儕僘儉嫬奅慄 y = ax + b 偲
        //仜偺嵗昗(bX1, bY1)丄偲偺埵抲娭學傪峫偊傞
        //y < ax + b 偱偁傟偽僸僢僩
        if (oppY < a * oppX +  b) {
            return true;
        }
    }
    return false;
}

bool StgUtil::isHit2D(const GgafDx::GeometricActor* const pActor01, const ColliAAPrism* const pAAPrism01,
                      const GgafDx::GeometricActor* const pActor02, const ColliAAPrism* const pAAPrism02  ) {
    const coord aX = pActor01->_x;
    const coord aY = pActor01->_y;
    const coord bX = pActor02->_x;
    const coord bY = pActor02->_y;

    coord bX1 = bX + pAAPrism02->_x1;
    coord bY1 = bY + pAAPrism02->_y1;
    coord bX2 = bX + pAAPrism02->_x2;
    coord bY2 = bY + pAAPrism02->_y2;
    if (aY + pAAPrism01->_y2 >= bY1 && aY + pAAPrism01->_y1 <= bY2 &&
        aX + pAAPrism01->_x2 >= bX1 && aX + pAAPrism01->_x1 <= bX2)
    {
        //偙偺帪揰偱AAB 偲 AAB 側傜偽僸僢僩
    } else {
        //偙偺帪揰偱AAB 偲 AAB 偩偲偟偰傕僸僢僩偟偰側偄
        return false;
    }
    int pos1 = pAAPrism01->_pos_info; //帺暘偺嶰妏宍偺捈妏捀揰偺埵抲
    double aA = pAAPrism01->_a;       //帺暘偺嶰妏宍偺幬曈偺孹偒
    coord aB = aY + pAAPrism01->_b;   //帺暘偺嶰妏宍偺幬曈偺愗曅
    float aNx = -pAAPrism01->_vIH_x;  //帺暘偺嶰妏宍偺幬曈偺朄慄儀僋僩儖X梫慺
    float aNy = -pAAPrism01->_vIH_y;  //帺暘偺嶰妏宍偺幬曈偺朄慄儀僋僩儖Y梫慺

    int pos2 = pAAPrism02->_pos_info; //帺暘偺嶰妏宍偺捈妏捀揰偺埵抲
    double bA = pAAPrism02->_a;       //帺暘偺嶰妏宍偺幬曈偺孹偒
    coord bB = bY + pAAPrism02->_b;   //帺暘偺嶰妏宍偺幬曈偺愗曅
    float bNx = -pAAPrism02->_vIH_x;  //帺暘偺嶰妏宍偺幬曈偺朄慄儀僋僩儖X梫慺
    float bNy = -pAAPrism02->_vIH_y;  //帺暘偺嶰妏宍偺幬曈偺朄慄儀僋僩儖Y梫慺

    //帺暘偺捈妏嶰妏宍偵偮偄偰丄捈妏捀揰傪(0, 0) 偵偍偒丄巆傝偺捀揰傪 A(aEx,0), B(0,aEy) 偲偡傞
    //捈妏嶰妏宍偱偺摉偨傝敾掕傪峫偊偨偄乮POS_R_TRIANGLE_NN 偵屌掕偟偨偄乯
    const coord aEx = pAAPrism01->_dx;
    const coord aEy = pAAPrism01->_dy;
    const coord aCX = aEx / 2; //帺暘偺嶰妏宍偺幬曈忋偺揰偺X梫慺
    const coord aCY = aEy / 2; //帺暘偺嶰妏宍偺幬曈忋偺揰偺Y梫慺
    //偦偙偱丄帺暘偲憡庤偺捈妏嶰妏宍偺埵抲娭學傪僟僀僫儈僢僋偵曄姺両
    if (pos1 & POS_R_TRIANGLE_Px) {
        //憡庤捈妏嶰妏宍嵗昗偺丄X幉暯峴堏摦丒X嵗昗斀揮(Y幉斀揮)
        const coord aX2 = aX + pAAPrism01->_x2;
        const coord tmp_bX2 = bX2;
        bX2 = aX2 - bX1;
        bX1 = aX2 - tmp_bX2;
        //aB bB 愗曅偼偦偺傑傑
        //憡庤捈妏嶰妏宍梫慺偺丄X嵗昗斀揮(Y幉斀揮)
        aA = -aA;
        bA = -bA;
        aNx = -aNx;
        bNx = -bNx;
        pos2 = StgUtil::POS_R_TRIANGLE_inv_X[pos2];
    } else {
        //X幉暯峴堏摦
        const coord aX1 = aX + pAAPrism01->_x1;
        bX1 -= aX1;
        bX2 -= aX1;
    }

    if (pos1 & POS_R_TRIANGLE_xP) {
        //憡庤捈妏嶰妏宍嵗昗偺丄Y幉暯峴堏摦丒Y嵗昗斀揮(X幉斀揮)
        const coord aY2 = aY + pAAPrism01->_y2;
        const coord tmp_bY2 = bY2;
        bY2 = aY2 - bY1;
        bY1 = aY2 - tmp_bY2;
        aB  = aY2 - aB;
        bB  = aY2 - bB;
        //憡庤捈妏嶰妏宍梫慺偺丄Y嵗昗斀揮(X幉斀揮)
        aA = -aA;
        bA = -bA;
        aNy = -aNy;
        bNy = -bNy;
        pos2 = StgUtil::POS_R_TRIANGLE_inv_Y[pos2];
    } else {
        //Y幉暯峴堏摦
        const coord aY1 = aY + pAAPrism01->_y1;
        bY1 -= aY1;
        bY2 -= aY1;
        aB  -= aY1;
        bB  -= aY1;
    }
    coord bCX = bX1 + (pAAPrism02->_dx / 2); //憡庤偺嶰妏宍偺幬曈忋偺揰偺X梫慺
    coord bCY = bY1 + (pAAPrism02->_dy / 2); //憡庤偺嶰妏宍偺幬曈忋偺揰偺Y梫慺

    //帺暘偺捀揰偼(0,0)偱 POS_R_TRIANGLE_NN 屌掕
    //憡庤偺捈妏嶰妏宍偼丄偦傟偵敽偄埵抲娭學偑曄姺偝傟偨忬懺
    if (pos2 == POS_R_TRIANGLE_NN) {
        //憡庤偺捈妏捀揰偼 (bX1, bY1)
        if (bX1 <= 0) {
            if (bY1 <= 0) {
                //埵抲1
                //帺恎偺捈妏捀揰偑丄嬤朤揰(0, 0)
                //憡庤偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (bNx, bNy) 偲
                //憡庤偺捈妏嶰妏宍偺幬曈偺揰 (bCX, bCY) 偐傜  嬤朤揰(0, 0) 偺儀僋僩儖(-bCX, -bCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(0, 0) 偑憡庤偺捈妏嶰妏宍偺拞偵偁傞
                //(bNx, bNy)丒(-bCX, -bCY) = bNx*(-bCX) + bNy*(bCY)
                if ((bNx*(-bCX) + bNy*(-bCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (bY1 <= aEy) {
                //埵抲4
                if (bX2 > 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //埵抲7
                return false;
            }
        } else if (bX1 <= aEx) {
            if (bY1 <= 0) {
                //埵抲2
                if (bY2 > 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (bY1 <= aEy) {
                //埵抲5
                //憡庤偺捈妏捀揰偑丄嬤朤揰(bX1, bY1)
                //帺恎偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (aNx, aNy) 偲
                //帺恎偺捈妏嶰妏宍偺幬曈偺揰 (aCX, aCY) 偐傜  嬤朤揰(bX1, bY1) 偺儀僋僩儖(bX1-aCX, bY1-aCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(bX1, bY1) 偑捈妏嶰妏宍偺拞偵偁傞
                //(aNx, aNy)丒(bX1-aCX, bY1-aCY) = aNx*(bX1-aCX) + aNy*(bY1-aCY)
                if ((aNx*(bX1-aCX) + aNy*(bY1-aCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //埵抲8
                return false;
            }
        } else {
            //埵抲3 or 6 or 9
            return false;
        }
    } //pos2 == POS_R_TRIANGLE_NN

    if (pos2 == POS_R_TRIANGLE_NP) {
        //憡庤偺捈妏捀揰偼 (bX1, bY2)
        if (bX1 <= 0) {
            if (bY2 <= 0) {
                //埵抲1
                return false;
            } else if (bY2 <= aEy) {
                //埵抲4
                if (bX2 > 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //埵抲7
                //帺恎偺捀揰嬤朤揰(0, aEy)
                //憡庤偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (bNx, bNy) 偲
                //憡庤偺捈妏嶰妏宍偺幬曈偺揰 (bCX, bCY) 偐傜  嬤朤揰(0, aEy) 偺儀僋僩儖(-bCX, aEy-bCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(0, aEy) 偑憡庤偺捈妏嶰妏宍偺拞偵偁傞
                //(bNx, bNy)丒(-bCX, aEy-bCY) = bNx*(-bCX) + bNy*(aEy-bCY)
                if ((bNx*(-bCX) + bNy*(aEy-bCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            }
        } else if (bX1 <= aEx) {
            if (bY2 <= 0) {
                //埵抲2
                return false;
            } else if (bY2 <= aEy) {
                //埵抲5
                //憡庤偺捀揰嬤朤揰(bX1, bY1)
                //帺恎偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (aNx, aNy) 偲
                //帺恎偺捈妏嶰妏宍偺幬曈偺揰 (aCX, aCY) 偐傜  嬤朤揰(bX1, bY1) 偺儀僋僩儖(bX1-aCX, bY1-aCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(bX1, bY1) 偑捈妏嶰妏宍偺拞偵偁傞
                //(aNx, aNy)丒(bX1-aCX, bY1-aCY) = aNx*(bX1-aCX) + aNy*(bY1-aCY)
                if ((aNx*(bX1-aCX) + aNy*(bY1-aCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //埵抲8
                //埵抲5偲摨偠
                if ((aNx*(bX1-aCX) + aNy*(bY1-aCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            }
        } else {
            //埵抲3 or 6or 9
            return false;
        }
    } //pos2 == POS_R_TRIANGLE_NP

    if (pos2 == POS_R_TRIANGLE_PN) {
        //憡庤偺捈妏捀揰偼 (bX2, bY1)
        if (bX2 <= 0) {
            return false;
        } else if (bX2 <= aEx) {
            if (bY1 <= 0) {
                //埵抲2
                if (bY2 > 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (bY1 <= aEy) {
                //埵抲5
                //憡庤偺捀揰嬤朤揰(bX1, bY1)
                //帺恎偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (aNx, aNy) 偲
                //帺恎偺捈妏嶰妏宍偺幬曈偺揰 (aCX, aCY) 偐傜  嬤朤揰(bX1, bY1) 偺儀僋僩儖(bX1-aCX, bY1-aCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(bX1, bY1) 偑捈妏嶰妏宍偺拞偵偁傞
                //(aNx, aNy)丒(bX1-aCX, bY1-aCY) = aNx*(bX1-aCX) + aNy*(bY1-aCY)
                if ((aNx*(bX1-aCX) + aNy*(bY1-aCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //埵抲8
                return false;
            }
        } else {
            if (bY1 <= 0) {
                //埵抲3
                //帺恎偺捀揰嬤朤揰(aEx, 0)
                //憡庤偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (bNx, bNy) 偲
                //憡庤偺捈妏嶰妏宍偺幬曈偺揰 (bCX, bCY) 偐傜  嬤朤揰(aEx, 0) 偺儀僋僩儖(aEx-bCX, -bCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(aEx, 0) 偑憡庤偺捈妏嶰妏宍偺拞偵偁傞
                //(bNx, bNy)丒(aEx-bCX, -bCY) = bNx*(aEx-bCX) + bNy*(-bCY)
                if ((bNx*(aEx-bCX) + bNy*(-bCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else if (bY1 <= aEy) {
                //埵抲6
                //埵抲5偲摨偠
                if ((aNx*(bX1-aCX) + aNy*(bY1-aCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //埵抲9
                return false;
            }
        }
    } //pos2 == POS_R_TRIANGLE_PN

    if (pos2 == POS_R_TRIANGLE_PP) {
        //憡庤偺捈妏捀揰偼 (bX2, bY2)
        if (bX2 <= 0) {
            //埵抲1 or 4 or 7
            return false;
        } else if (bX2 <= aEx) {
            if (bY2 <= 0) {
                //埵抲2
                return false;
            } else {
                //埵抲5 or 8
            }
        } else {
            if (bY2 <= 0) {
                //埵抲3
                return false;
            } else if (bY2 <= aEy) {
                //埵抲6 or 9
            }
        }

        //埵抲5 or 6 or 8 or 9
        //傑偢孹偒傪偒傪斾妑
        // aA < bA 偺応崌丄憡庤嶰妏宍偺捀揰(bX1,bY2) 偺埵抲偵拲栚
        // aA > bA 偺応崌丄憡庤嶰妏宍偺捀揰(bX2,bY1) 偺埵抲偵拲栚
        // aA = bA 偺応崌丄幬曈偑暯峴側偺偱偳偭偪偱傕偄偄
        // 拲栚偺捀揰偵偮偄偰丄
        // A(aEx,0) 傪娷傓幬曈偺朄慄偵暯峴側慄偲
        // B(0,aEy) 傪娷傓幬曈偺朄慄偵暯峴側慄偲偺娫偺斖埻(斖埻R偲偡傞)
        // 偺撪懁偵憡庤偺捀揰偑偁傞偐柍偄偐偱応崌傢偗
        //
        //A(aEx,0) 傪娷傓幬曈偺朄慄偵暯峴側慄偼丄
        //捈慄偺朄慄 仺AB=(-aEx, aEy) 偵岦偗偨偄偺偱
        //-aEx * x + aEy * y + c = 0
        //偙傟偑丄A(aEx,0)傪捠傞偺偱
        //-aEx * aEx + c = 0
        //c = aEx^2
        //傛偭偰
        //-aEx * x + aEy * y + aEx^2 > 0
        //
        //B(0,aEy) 傪娷傓幬曈偺朄慄偵暯峴側慄偼丄
        //捈慄偺朄慄 仺BA=(aEx, -aEy) 偵岦偗偨偄偺偱
        //aEx * x - aEy * y + c = 0
        //偙傟偑丄B(0,aEy) 傪捠傞偺偱
        //- aEy * aEy + c = 0
        //c = aEy^2
        //傛偭偰
        //aEx * x - aEy * y + aEy^2 > 0

        //椞堟R偼
        //-aEx * x + aEy * y + aEx^2 > 0
        //aEx * x - aEy * y + aEy^2 > 0
        //偺斖埻

        const double ex = aEx;
        const double ey = aEy;
        if (aA < bA) {
            //幬曈偺孹偒乮晧乯偑丄憡庤嶰妏宍偺曽偑傛傝悈暯偵嬤偄

            //憡庤嶰妏宍偺捀揰(bX1,bY2) 偺埵抲偵拲栚
            if ((-ex*bX1 + ey*bY2 + ex*ex) < 0) {
                //拲栚偺捀揰(bX1,bY2)偑A(ex,0) 傪娷傓幬曈偺朄慄偵暯峴側慄偺奜懁
                return false;
            } else if ((ex*bX1 - ey*bY2 + ey*ey) < 0) {
                //拲栚偺捀揰(bX1,bY2)偑B(0,ey) 傪娷傓幬曈偺朄慄偵暯峴側慄偺奜懁

                //帺恎偺捀揰嬤朤揰(0, aEy)
                //憡庤偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (bNx, bNy) 偲
                //憡庤偺捈妏嶰妏宍偺幬曈偺揰 (bCX, bCY) 偐傜  嬤朤揰(0, aEy) 偺儀僋僩儖(-bCX, aEy-bCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(0, aEy) 偑憡庤偺捈妏嶰妏宍偺拞偵偁傞
                //(bNx, bNy)丒(-bCX, aEy-bCY) = bNx*(-bCX) + bNy*(aEy-bCY)
                if ((bNx*(-bCX) + bNy*(aEy-bCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else {
                //拲栚偺捀揰(bX1,bY2)偑斖埻R偺斖埻撪偺応崌

                //憡庤偺捀揰嬤朤揰(bX1,bY2)
                //帺恎偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (aNx, aNy) 偲
                //帺恎偺捈妏嶰妏宍偺幬曈偺揰 (aCX, aCY) 偐傜  嬤朤揰(bX1,bY2) 偺儀僋僩儖(bX1-aCX, bY2-aCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(bX1, bY2) 偑捈妏嶰妏宍偺拞偵偁傞
                //(aNx, aNy)丒(bX1-aCX, bY2-aCY) = aNx*(bX1-aCX) + aNy*(bY2-aCY)
                if ((aNx*(bX1-aCX) + aNy*(bY2-aCY)) < 0)  {
                    return true;
                } else {
                    return false;
                }
            }

        } else {
            //幬曈偺孹偒乮晧乯偑丄憡庤嶰妏宍偺曽偑傛傝悅捈偵嬤偄
            //憡庤嶰妏宍偺捀揰(bX2,bY1) 偺埵抲偵拲栚
            if ((-ex*bX2 + ey*bY1 + ex*ex) < 0) {
                //拲栚偺捀揰(bX2,bY1)偑A(ex,0) 傪娷傓幬曈偺朄慄偵暯峴側慄偺奜懁

                //帺恎偺捀揰嬤朤揰(aEx, 0)
                //憡庤偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (bNx, bNy) 偲
                //憡庤偺捈妏嶰妏宍偺幬曈偺揰 (bCX, bCY) 偐傜  嬤朤揰(aEx, 0) 偺儀僋僩儖(aEx-bCX, -bCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(aX2, 0) 偑憡庤偺捈妏嶰妏宍偺拞偵偁傞
                //(bNx, bNy)丒(aEx-bCX, -bCY) = bNx*(aEx-bCX) + bNy*(-bCY)
                if ((bNx*(aEx-bCX) + bNy*(-bCY)) < 0) {
                    return true;
                } else {
                    return false;
                }
            } else if ((ex*bX2 - ey*bY1 + ey*ey) < 0) {
                //拲栚偺捀揰(bX2,bY1)偑B(0,ey) 傪娷傓幬曈偺朄慄偵暯峴側慄偺奜懁

                return false;
            } else {
                //拲栚偺捀揰(bX2,bY1)偑斖埻R偺斖埻撪偺応崌

                //憡庤偺捀揰嬤朤揰(bX2,bY1)
                //帺恎偺捈妏嶰妏宍偺幬曈偺朄慄儀僋僩儖 (aNx, aNy) 偲
                //帺恎偺捈妏嶰妏宍偺幬曈偺揰 (aCX, aCY) 偐傜  嬤朤揰(bX2,bY1) 偺儀僋僩儖(bX2-aCX, bY1-aCY)偺
                //撪愊偑晧 側傜偽嬤朤揰(bX2, bY1) 偑捈妏嶰妏宍偺拞偵偁傞
                //(aNx, aNy)丒(bX2-aCX, bY1-aCY) = aNx*(bX2-aCX) + aNy*(bY1-aCY)
                if ((aNx*(bX2-aCX) + aNy*(bY1-aCY)) < 0)  {
                    return true;
                } else {
                    return false;
                }
            }

        }
    } //pos2 == POS_R_TRIANGLE_PP

    return false;
}

GgafDx::FigureActor* StgUtil::shotWay001(coord prm_x, coord prm_y, coord prm_z,
                                       angle prm_rz, angle prm_ry,
                                       GgafCore::ActorDepository* prm_pDepo_shot,
                                       coord prm_r,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int)) {
    if (prm_set_num <= 0) {  return nullptr;  }
    float vx, vy, vz;
    GgafDx::Util::convRzRyToVector(prm_rz, prm_ry, vx, vy, vz);
    coord x = vx * prm_r;
    coord y = vy * prm_r;
    coord z = vz * prm_r;
    GgafDx::FigureActor* pActor_shot = nullptr;
    velo now_velo = prm_velo_first;
    acce now_acce = prm_acce;
    int dispatch_num = 0;
    for (int n = 0; n < prm_set_num; n++) {
        pActor_shot = (GgafDx::FigureActor*)prm_pDepo_shot->dispatch(n*prm_interval_frames+1);
        if (pActor_shot) {
            dispatch_num++;
            pActor_shot->setPosition(prm_x + x,
                                     prm_y + y,
                                     prm_z + z);
            pActor_shot->getVecDriver()->setRzRyMvAng(prm_rz, prm_ry);
            pActor_shot->getVecDriver()->setMvVelo(now_velo);
            pActor_shot->getVecDriver()->setMvAcce(now_acce);
            if (pFunc_call_back_dispatched) {
                pFunc_call_back_dispatched(pActor_shot, dispatch_num, n);
            }
        }
        now_velo *= prm_attenuated;
    }
    return pActor_shot;
}

GgafDx::FigureActor* StgUtil::shotWay001(const GgafDx::GeometricActor* prm_pFrom,
                                       GgafCore::ActorDepository* prm_pDepo_shot,
                                       coord prm_r,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int)) {
    return shotWay001(prm_pFrom->_x, prm_pFrom->_y, prm_pFrom->_z,
                      prm_pFrom->_rz, prm_pFrom->_ry,
                      prm_pDepo_shot,
                      prm_r,
                      prm_velo_first, prm_acce,
                      prm_set_num, prm_interval_frames, prm_attenuated,
                      pFunc_call_back_dispatched);
}

GgafDx::FigureActor* StgUtil::shotWay001(coord prm_from_x, coord prm_from_y, coord prm_from_z,
                                       coord prm_to_x, coord prm_to_y, coord prm_to_z,
                                       GgafCore::ActorDepository* prm_pDepo_shot,
                                       coord prm_r,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int)) {
    angle rz,ry;
    GgafDx::Util::convVectorToRzRy(prm_to_x - prm_from_x,
                                 prm_to_y - prm_from_y,
                                 prm_to_z - prm_from_z,
                                 rz, ry);
    return shotWay001(prm_from_x, prm_from_y, prm_from_z,
                      rz, ry,
                      prm_pDepo_shot,
                      prm_r,
                      prm_velo_first, prm_acce,
                      prm_set_num, prm_interval_frames, prm_attenuated,
                      pFunc_call_back_dispatched);
}

GgafDx::FigureActor* StgUtil::shotWay002(coord prm_x, coord prm_y, coord prm_z,
                                       angle prm_rx, angle prm_rz, angle prm_ry,
                                       GgafCore::ActorDepository* prm_pDepo_shot,
                                       coord prm_r,
                                       int prm_way_N,
                                       angle prm_ang_clearance_N,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int, int)) {
    if (prm_way_N <= 0 || prm_set_num <= 0) {  return nullptr;  }
    angle* paAng_way_N = NEW angle[prm_way_N];
    GgafDx::Util::getWayAngle2D(0, prm_way_N, prm_ang_clearance_N, paAng_way_N);
    GgafDx::GeoElem* paGeo = NEW GgafDx::GeoElem[prm_way_N];
    float vx, vy, vz;
    float tx, ty, tz; //嵟廔曽岦偺愨懳嵗昗偺扨埵儀僋僩儖
    angle rz,ry;
    D3DXMATRIX matWorldRot;
    GgafDx::Util::setWorldMatrix_RxRzRy(prm_rx, prm_rz, prm_ry, matWorldRot);
    for (int i = 0; i < prm_way_N; i++) {
        rz = GgafDx::Util::simplifyAng(paAng_way_N[i]);
        ry = D0ANG;
        GgafDx::Util::convRzRyToVector(rz, ry, vx, vy, vz);
        tx = vx*matWorldRot._11 + vy*matWorldRot._21 + vz*matWorldRot._31;
        ty = vx*matWorldRot._12 + vy*matWorldRot._22 + vz*matWorldRot._32;
        tz = vx*matWorldRot._13 + vy*matWorldRot._23 + vz*matWorldRot._33;
        paGeo[i].x = (coord)(tx * prm_r);
        paGeo[i].y = (coord)(ty * prm_r);
        paGeo[i].z = (coord)(tz * prm_r);
        GgafDx::Util::convVectorToRzRy(tx, ty, tz,
                                     paGeo[i].rz, paGeo[i].ry);
    }
    GgafDx::FigureActor* pActor_shot = nullptr;
    velo now_velo = prm_velo_first;
    acce now_acce = prm_acce;
    int dispatch_num = 0;
    for (int n = 0; n < prm_set_num; n++) {
        for (int i = 0; i < prm_way_N; i++) {
            pActor_shot = (GgafDx::FigureActor*)prm_pDepo_shot->dispatch(n*prm_interval_frames+1);
            if (pActor_shot) {
                dispatch_num++;
                pActor_shot->setPosition(prm_x + paGeo[i].x,
                                         prm_y + paGeo[i].y,
                                         prm_z + paGeo[i].z);
                pActor_shot->getVecDriver()->setRzRyMvAng(paGeo[i].rz, paGeo[i].ry);
                pActor_shot->getVecDriver()->setMvVelo(now_velo);
                pActor_shot->getVecDriver()->setMvAcce(now_acce);
                if (pFunc_call_back_dispatched) {
                    pFunc_call_back_dispatched(pActor_shot, dispatch_num, n, i);
                }
            }
        }
        now_velo *= prm_attenuated;
    }
    GGAF_DELETEARR(paAng_way_N);
    GGAF_DELETEARR(paGeo);
    return pActor_shot;
}

GgafDx::FigureActor* StgUtil::shotWay002(const GgafDx::GeometricActor* prm_pFrom,
                                                   GgafCore::ActorDepository* prm_pDepo_shot,
                                                   coord prm_r,
                                                   int prm_way_N,
                                                   angle prm_ang_clearance_N,
                                                   velo prm_velo_first, acce prm_acce,
                                                   int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                                   void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int, int)) {
    return shotWay002(prm_pFrom->_x, prm_pFrom->_y, prm_pFrom->_z,
                      prm_pFrom->_rx, prm_pFrom->_rz, prm_pFrom->_ry,
                      prm_pDepo_shot,
                      prm_r,
                      prm_way_N,
                      prm_ang_clearance_N,
                      prm_velo_first, prm_acce,
                      prm_set_num, prm_interval_frames, prm_attenuated,
                      pFunc_call_back_dispatched);
}

GgafDx::FigureActor* StgUtil::shotWay003(coord prm_x, coord prm_y, coord prm_z,
                                       angle prm_rx, angle prm_rz, angle prm_ry,
                                       GgafCore::ActorDepository* prm_pDepo_shot1, uint32_t* prm_paUint32_dotmat1,
                                       GgafCore::ActorDepository* prm_pDepo_shot2, uint32_t* prm_paUint32_dotmat2,
                                       GgafCore::ActorDepository* prm_pDepo_shot3, uint32_t* prm_paUint32_dotmat3,
                                       coord prm_r,
                                       int prm_way_N, int prm_way_M,
                                       angle prm_ang_clearance_N, angle prm_ang_clearance_M,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int, int, int, int)) {
    if (prm_way_N <= 0 || prm_way_M <= 0 || prm_set_num <= 0) {  return nullptr;  }
    angle* paAng_way_N = NEW angle[prm_way_N];
    angle* paAng_way_M = NEW angle[prm_way_M];
    uint32_t* paUint32_dotmat = NEW uint32_t[prm_way_N];
    GgafDx::Util::getWayAngle2D(0, prm_way_N, prm_ang_clearance_N, paAng_way_N);
    GgafDx::Util::getWayAngle2D(0, prm_way_M, prm_ang_clearance_M, paAng_way_M);
    GgafDx::GeoElem** papaGeo = NEW GgafDx::GeoElem*[prm_way_N];
    float vx, vy, vz;
    float tx, ty, tz; //嵟廔曽岦偺愨懳嵗昗偺扨埵儀僋僩儖
    angle rz,ry;
    D3DXMATRIX matWorldRot;
    GgafDx::Util::setWorldMatrix_RxRzRy(prm_rx, prm_rz, prm_ry, matWorldRot);
    uint32_t dot1,dot2,dot3;
    for (int i = 0; i < prm_way_N; i++) {
        dot1 = prm_paUint32_dotmat1 ? prm_paUint32_dotmat1[i] : 0;
        dot2 = prm_paUint32_dotmat2 ? prm_paUint32_dotmat2[i] : 0;
        dot3 = prm_paUint32_dotmat3 ? prm_paUint32_dotmat3[i] : 0;
        paUint32_dotmat[i] = dot1 | dot2 | dot3;
        if (paUint32_dotmat[i] == 0) {
            papaGeo[i] = nullptr;
            continue;
        }
        rz = GgafDx::Util::simplifyAng(paAng_way_N[i]);
        papaGeo[i] = NEW GgafDx::GeoElem[prm_way_M];
        for (int j = 0; j < prm_way_M; j++) {
            if (paUint32_dotmat[i] & UTIL::BITNUM[prm_way_M-j]) {
                ry = GgafDx::Util::simplifyAng(paAng_way_M[j]);
                GgafDx::Util::convRzRyToVector(rz, ry, vx, vy, vz);
                tx = vx*matWorldRot._11 + vy*matWorldRot._21 + vz*matWorldRot._31;
                ty = vx*matWorldRot._12 + vy*matWorldRot._22 + vz*matWorldRot._32;
                tz = vx*matWorldRot._13 + vy*matWorldRot._23 + vz*matWorldRot._33;
                papaGeo[i][j].x = (coord)(tx * prm_r);
                papaGeo[i][j].y = (coord)(ty * prm_r);
                papaGeo[i][j].z = (coord)(tz * prm_r);
                GgafDx::Util::convVectorToRzRy(tx, ty, tz,
                                             papaGeo[i][j].rz, papaGeo[i][j].ry);
            }
        }
    }
    GgafDx::FigureActor* pActor_shot = nullptr;
    velo now_velo = prm_velo_first;
    acce now_acce = prm_acce;
    int dispatch_num = 0;
    int depo_no = 0;
    for (int n = 0; n < prm_set_num; n++) {
        for (int i = 0; i < prm_way_N; i++) {
            if (paUint32_dotmat[i] == 0) {
                continue;
            }
            for (int j = 0; j < prm_way_M; j++) {
                if (paUint32_dotmat[i] & UTIL::BITNUM[prm_way_M-j]) {
                    if (prm_paUint32_dotmat1 && (prm_paUint32_dotmat1[i] & UTIL::BITNUM[prm_way_M-j])) {
                        pActor_shot = (GgafDx::FigureActor*)prm_pDepo_shot1->dispatch(n*prm_interval_frames+1);
                        depo_no = 1;
                    } else if (prm_paUint32_dotmat2 && (prm_paUint32_dotmat2[i] & UTIL::BITNUM[prm_way_M-j])) {
                        pActor_shot = (GgafDx::FigureActor*)prm_pDepo_shot2->dispatch(n*prm_interval_frames+1);
                        depo_no = 2;
                    } else if (prm_paUint32_dotmat3 && (prm_paUint32_dotmat3[i] & UTIL::BITNUM[prm_way_M-j])) {
                        pActor_shot = (GgafDx::FigureActor*)prm_pDepo_shot3->dispatch(n*prm_interval_frames+1);
                        depo_no = 3;
                    } else {
                        pActor_shot = nullptr;
                        depo_no = 0;
                    }
                } else {
                    pActor_shot = nullptr;
                    depo_no = 0;
                }
                if (pActor_shot) {
                    dispatch_num++;
                    pActor_shot->setPosition(prm_x + papaGeo[i][j].x,
                                             prm_y + papaGeo[i][j].y,
                                             prm_z + papaGeo[i][j].z);
                    pActor_shot->getVecDriver()->setRzRyMvAng(papaGeo[i][j].rz, papaGeo[i][j].ry);
                    pActor_shot->getVecDriver()->setMvVelo(now_velo);
                    pActor_shot->getVecDriver()->setMvAcce(now_acce);
                    if (pFunc_call_back_dispatched) {
                        pFunc_call_back_dispatched(pActor_shot, dispatch_num, n, depo_no, i, j);
                    }
                }
            }
        }
        now_velo *= prm_attenuated;
    }

    GGAF_DELETEARR(paAng_way_N);
    GGAF_DELETEARR(paAng_way_M);
    GGAF_DELETEARR(paUint32_dotmat);
    for (int i = 0; i < prm_way_N; i++) {
        if (papaGeo[i]) {
            GGAF_DELETEARR(papaGeo[i]);
        }
    }
    GGAF_DELETEARR(papaGeo);

    return pActor_shot;
}


GgafDx::FigureActor* StgUtil::shotWay003(const GgafDx::GeometricActor* prm_pFrom,
                                       GgafCore::ActorDepository* prm_pDepo_shot1, uint32_t* prm_paUint32_dotmat1,
                                       GgafCore::ActorDepository* prm_pDepo_shot2, uint32_t* prm_paUint32_dotmat2,
                                       GgafCore::ActorDepository* prm_pDepo_shot3, uint32_t* prm_paUint32_dotmat3,
                                       coord prm_r,
                                       int prm_way_N, int prm_way_M,
                                       angle prm_ang_clearance_N, angle prm_ang_clearance_M,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int, int, int, int)) {
    return shotWay003(prm_pFrom->_x, prm_pFrom->_y, prm_pFrom->_z,
                      prm_pFrom->_rx, prm_pFrom->_rz, prm_pFrom->_ry,
                      prm_pDepo_shot1, prm_paUint32_dotmat1,
                      prm_pDepo_shot2, prm_paUint32_dotmat2,
                      prm_pDepo_shot3, prm_paUint32_dotmat3,
                      prm_r,
                      prm_way_N, prm_way_M,
                      prm_ang_clearance_N, prm_ang_clearance_M,
                      prm_velo_first, prm_acce,
                      prm_set_num, prm_interval_frames, prm_attenuated,
                      pFunc_call_back_dispatched);
}


GgafDx::FigureActor* StgUtil::shotWay004(coord prm_x, coord prm_y, coord prm_z,
                                       angle prm_rz, angle prm_ry,
                                       GgafCore::ActorDepository* prm_pDepo_shot,
                                       coord prm_r,
                                       int prm_radial_way_num, angle prm_expanse_angle,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int, int)) {
    if (prm_radial_way_num <= 0 || prm_set_num <= 0) {  return nullptr;  }
    angle* paAng_way = NEW angle[prm_radial_way_num];
    GgafDx::Util::getRadialAngle2D(0, prm_radial_way_num, paAng_way);
    GgafDx::GeoElem* paGeo = NEW GgafDx::GeoElem[prm_radial_way_num];
    angle expanse_rz = (D180ANG - prm_expanse_angle)/2;

    D3DXMATRIX matWorldRot;
    GgafDx::Util::setWorldMatrix_RzRy(GgafDx::Util::simplifyAng(prm_rz-D90ANG), prm_ry, matWorldRot);

    float vx, vy, vz;
    float tx, ty, tz; //嵟廔曽岦偺愨懳嵗昗偺扨埵儀僋僩儖
    for (int i = 0; i < prm_radial_way_num; i++) {
        GgafDx::Util::convRzRyToVector(expanse_rz, paAng_way[i], vx, vy, vz);
        tx = vx*matWorldRot._11 + vy*matWorldRot._21 + vz*matWorldRot._31;
        ty = vx*matWorldRot._12 + vy*matWorldRot._22 + vz*matWorldRot._32;
        tz = vx*matWorldRot._13 + vy*matWorldRot._23 + vz*matWorldRot._33;
        paGeo[i].x = (coord)(tx * prm_r);
        paGeo[i].y = (coord)(ty * prm_r);
        paGeo[i].z = (coord)(tz * prm_r);
        GgafDx::Util::convVectorToRzRy(tx, ty, tz,
                                     paGeo[i].rz, paGeo[i].ry);
    }
    GgafDx::FigureActor* pActor_shot = nullptr;
    velo now_velo = prm_velo_first;
    acce now_acce = prm_acce;
    int dispatch_num = 0;
    for (int n = 0; n < prm_set_num; n++) {
        for (int i = 0; i < prm_radial_way_num; i++) {
            pActor_shot = (GgafDx::FigureActor*)prm_pDepo_shot->dispatch(n*prm_interval_frames+1);
            if (pActor_shot) {
                dispatch_num++;
                pActor_shot->setPosition(prm_x + paGeo[i].x,
                                         prm_y + paGeo[i].y,
                                         prm_z + paGeo[i].z);
                pActor_shot->getVecDriver()->setRzRyMvAng(paGeo[i].rz, paGeo[i].ry);
                pActor_shot->getVecDriver()->setMvVelo(now_velo);
                pActor_shot->getVecDriver()->setMvAcce(now_acce);
//                pActor_shot->_rz = Rz;
//                pActor_shot->_ry = Ry;
                if (pFunc_call_back_dispatched) {
                    pFunc_call_back_dispatched(pActor_shot, dispatch_num, n, i);
                }
            }
        }
        now_velo *= prm_attenuated;
    }
    GGAF_DELETEARR(paAng_way);
    GGAF_DELETEARR(paGeo);
    return pActor_shot;
}

GgafDx::FigureActor* StgUtil::shotWay004(const GgafDx::GeometricActor* prm_pFrom,
                                       GgafCore::ActorDepository* prm_pDepo_shot,
                                       coord prm_r,
                                       int prm_way, angle prm_expanse_angle,
                                       velo prm_velo_first, acce prm_acce,
                                       int prm_set_num, frame prm_interval_frames, float prm_attenuated,
                                       void (*pFunc_call_back_dispatched)(GgafDx::FigureActor*, int, int, int)) {
    return shotWay004(prm_pFrom->_x, prm_pFrom->_y, prm_pFrom->_z,
                      prm_pFrom->_rz, prm_pFrom->_ry,
                      prm_pDepo_shot,
                      prm_r,
                      prm_way, prm_expanse_angle,
                      prm_velo_first, prm_acce,
                      prm_set_num, prm_interval_frames, prm_attenuated,
                      pFunc_call_back_dispatched);
}





//僺儔儈僢僪偲媴
//  暯柺 a*x + b*y + c*z + d = 0
//  揰D(x0,y0,z0)
//  揰偐傜暯柺偵壓傠偟偨懌偺崻尦傪揰H(x,y,z) 偲偡傞偲
//
//  儀僋僩儖 HD=(x0-x ,y0-y, z0-z) = t(a,b,c)  (t偼幚悢)  丒丒丒嘆
//
//  嘆傛傝
//  x0 - x = t*a
//  y0 - y = t*b
//  z0 - z = t*c
//  側偺偱
//  x = x0 - t*a
//  y = y0 - t*b
//  z = z0 - t*c
//
//  傪暯柺偺幃傊戙擖
//  a*(x0-t*a) + b*(y0-t*b) + c*(z0-t*c) + d = 0
//
//  偙傟傪t偵偮偄偰夝偔偲
//  t = (a*x0+b*y0+c*z0+d)/(a^2+b^2+c^2)  丒丒丒嘇
//
//  傛偭偰
//  x =  x0 - t*a
//    =  x0 - ((a*x0+b*y0+c*z0+d)/(a^2+b^2+c^2))*a
//
//  y = y0 - t*b
//    = y0 - ((a*x0+b*y0+c*z0+d)/(a^2+b^2+c^2))*b
//
//  z = z0 - t*c
//    = z0 - ((a*x0+b*y0+c*z0+d)/(a^2+b^2+c^2))*c
//
//  傑偨丄HD偺嫍棧偼
//  |HD|= |t(a,b,c)| = |t|*|(a,b,c)| = abs(t)*sqrt(a^2+b^2+c^2)  丒丒丒嘊
//
//  嘇偺t傪嘊傊戙擖
//
//  |HD| = abs((c*z0+b*y0+a*x0+d)/(c^2+b^2+a^2))*sqrt(a^2+b^2+c^2)
//
//  |HD| = abs(a*x0+b*y0+c*z0+d) / sqrt(a^2+b^2+c^2)



//// 摿掕偺揰(a,b,c)傪捠傝丄曽岦儀僋僩儖偑(p,q,r)偺捈慄偼丅
//(x,y,z) = (a,b,c) + t(p,q,r)  (t偼攠夘曄悢)
//
//x = a + t*p 丒丒丒 嘆
//y = b + t*q 丒丒丒 嘇
//z = c + t*r 丒丒丒 嘊
//
//t = (x-a) /p = (y-b)/q = (z-c)/r
//
//
//揰D(x0,y0,z0)
//揰偐傜捈慄偵壓傠偟偨懌偺崻尦傪揰H(x,y,z) 偲偡傞偲
//儀僋僩儖 HD = (x0-x,y0-y, z0-z)
//    = (x0-(a+t*p), y0-(b+t*q), z0-(c+t*r))  丒丒丒嘋
//
//偙傟偑丄(p,q,r) 偲捈岎偡傞偺偱丄撪愊=0
//(x0-(a+t*p), y0-(b+t*q), z0-(c+t*r))丒(p,q,r) = 0
//p*(x0-(a+t*p)) + q*(y0-(b+t*q)) + r*(z0-(c+t*r)) = 0
//
//t偵偮偄偰夝偔偲
//
//t=(r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2)
//
//嘋偺t 偵戙擖偟丄偟偨偑偭偰 HD 偼
//HD = ( x0-(a+( (r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2) )*p),
//y0-(b+( (r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2) )*q),
//z0-(c+( (r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2) )*r)    )
//
//|HD| = sqrt( (x0-(a+( (r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2) )*p))^2 +
//     (y0-(b+( (r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2) )*q))^2 +
//     (z0-(c+( (r*z0+q*y0+p*x0-c*r-b*q-a*p)/(r^2+q^2+p^2) )*r))^2   )
//
//|HD| = sqrt((q^2+p^2)*z0^2+(-2*q*r*y0-2*p*r*x0+(2*b*q+2*a*p)*r-2*c*q^2-2*c*p^2)*z0+(r^2+p^2)*y0^2+
//(-2*p*q*x0-2*b*r^2+2*c*q*r+2*a*p*q-2*b*p^2)*y0+(r^2+q^2)*x0^2+(-2*a*r^2+2*c*p*r-2*a*q^2+2*b*p*q)*x0+(b^2+a^2)*r^2+
//(-2*b*c*q-2*a*c*p)*r+(c^2+a^2)*q^2-2*a*b*p*q+(c^2+b^2)*p^2)/(sqrt(r^2+q^2+p^2))


//揰AB傪捠傞捈慄偲揰D偺嫍棧
//揰 A(a,b,c) B(d,e,f) 傪捠傞捈慄偼
//AB = (d-a, e-b, f-c)
//(x,y,z) = (a,b,c) + t(d-a, e-b, f-c)  (t偼攠夘曄悢)
//
//x = a + t*(d-a) 丒丒丒 嘆
//y = b + t*(e-b) 丒丒丒 嘇
//z = c + t*(f-c) 丒丒丒 嘊
//
//揰D(x0,y0,z0)
//揰偐傜捈慄偵壓傠偟偨懌偺崻尦傪揰H(x,y,z) 偲偡傞偲
//儀僋僩儖 HD = (x0-x,y0-y, z0-z)
//            = (x0-(a+t*(d-a)), y0-(b+t*(e-b)), z0-(c+t*(f-c)))  丒丒丒嘋
//
//
//偙傟偑丄AB=(d-a, e-b, f-c) 偲捈岎偡傞偺偱丄撪愊=0
//(x0-(a+t*(d-a)), y0-(b+t*(e-b)), z0-(c+t*(f-c)))丒(d-a, e-b, f-c) = 0
//側偺偱
//(x0-(a+t*(d-a)))*(d-a) + (y0-(b+t*(e-b)))*(e-b) + (z0-(c+t*(f-c)))*(f-c) = 0
//
//t偵偮偄偰夝偔偲
//
//t = ((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2)
//
//嘋偺 t 偵戙擖偟丄偟偨偑偭偰 HD 偼
//HD = ( x0-(a+(((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))*(d-a)) ,
//       y0-(b+(((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))*(e-b)) ,
//       z0-(c+(((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))*(f-c))   )
//
//|HD| = sqrt( (x0-(a+(((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))*(d-a)))^2 +
//             (y0-(b+(((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))*(e-b)))^2 +
//             (z0-(c+(((f-c)*z0+(e-b)*y0+(d-a)*x0-c*f-b*e-a*d+c^2+b^2+a^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))*(f-c)))^2    )
//
//=sqrt(((e^2-2*b*e+d^2-2*a*d+b^2+a^2)*z0^2+(((2*b-2*e)*f+2*c*e-2*b*c)*y0+((2*a-2*d)*f+2*c*d-2*a*c)*x0+
//(2*b*e+2*a*d-2*b^2-2*a^2)*f-2*c*e^2+2*b*c*e-2*c*d^2+2*a*c*d)*z0+(f^2-2*c*f+d^2-2*a*d+c^2+a^2)*y0^2+
//(((2*a-2*d)*e+2*b*d-2*a*b)*x0-2*b*f^2+(2*c*e+2*b*c)*f+(2*a*d-2*c^2-2*a^2)*e-2*b*d^2+2*a*b*d)*y0+
//(f^2-2*c*f+e^2-2*b*e+c^2+b^2)*x0^2+(-2*a*f^2+(2*c*d+2*a*c)*f-2*a*e^2+(2*b*d+2*a*b)*e+(-2*c^2-2*b^2)*d)*x0+(b^2+a^2)*
//f^2+(-2*b*c*e-2*a*c*d)*f+(c^2+a^2)*e^2-2*a*b*d*e+(c^2+b^2)*d^2)/(f^2-2*c*f+e^2-2*b*e+d^2-2*a*d+c^2+b^2+a^2))
//側傫偠傖偙傟丒丒丒


// 媴偲僺儔儈僢僪乮幬柺偲偺嫍棧偱敾掕偡傞斖埻乯
//    (1) (a, b, c) 偑暯柺偺朄慄儀僋僩儖偱偡丅
//
//    (2) |d|/|(a, b, c)| 偑 "暯柺偲尨揰偺嫍棧" 偵側傝傑偡丅偮傑傝丄尨揰偐傜暯柺偵悅慄傪崀傠偟偨帪偺丄悅慄偺挿偝偱偡丅
//    丂扐偟丄|(a, b, c)| = 併(a^2+b^2+c^2) (朄慄儀僋僩儖偺挿偝) 偱偡丅
//    丂朄慄儀僋僩儖 (a,b,c) 偑婛偵婯奿壔偝傟偰偄傞応崌 (|(a,b,c)|=1 偺応崌) 偼丄扨偵 |d| 偑 "暯柺偲尨揰偺嫍棧" 偱偡丅
//
//    (3) d 偺晞崋偼丄尨揰偑暯柺偺昞懁偵偁傞偐棤懁偵偁傞偐偵懳墳偟偰偄傑偡丅
//    丂d 偑惓偺帪偼丄尨揰偼暯柺偺昞懁(暯柺偐傜尒偰朄慄儀僋僩儖偺曽岦)偵偁傝傑偡丅
//    丂d 偑晧偺帪偼丄尨揰偼暯柺偺棤懁(朄慄儀僋僩儖偲媡偺曽岦)偵偁傝傑偡丅
//    a仺=(ax,ay,az),
//    b仺=(bx,by,bz)
//
//    撪愊
//    撪愊-1乯丗僗僇儔乕抣 |a仺||b仺|cos兤 偺偙偲
//    乮撪愊-2乯丗僗僇儔乕抣 ax bx + ay by + az bz 偺偙偲丅
//
//    奜愊
//    挿偝偑 |a仺||b仺|sin兤 偱 a仺 偲 b仺 偵悅捈側儀僋僩儖偺偙偲
//    乮奜愊-2乯丗(ay bz - az by, az bx - ax bz, ax by - ay bx)偲偄偆惉暘偱昞偝傟傞儀僋僩儖偺偙偲丅
//
//
//    尨揰偵嶰捈妏捀揰傪偍偒丄A(ex,0,0), B(0,ey,0), C(0,0,ez) 偺嶰捈妏嶰妏悕傪峫偊 (ex>0, ey>0, ez>0)
//    幬柺傪掙柺偲偟偨嶰妏拰乮崅偝柍尷乯偺斖埻傪峫偊傞
//
//    幬柺偺曽掱幃
//    AB仺 = (-ex, ey, 0 )
//    AC仺 = (-ex, 0 , ez)
//    AB仺倶AC仺 = (a,b,c)
//
//    a = ey*ez
//    b = ex*ez
//    c = ey*ex
//
//    ey ez x + ex ez y + ey ex z + d = 0
//    偙傟偑丄A(ex,0,0)傪偲偍傞偺偱丄
//
//    d = -ex*ey*ez
//
//    幬柺偺曽掱幃
//    (ey*ez)*x + (ex*ez)*y + (ey*ex)*z - ex*ey*ez = 0
//    朄慄 (ey*ez, ex*ez, ey*ex)
//
//    ----------------------------------------------------------
//    A(ex,0,0), B(0,ey,0) 傪娷傓幬柺偵悅捈側柺傪媮傔傞
//
//    媮傔傞柺傪
//    va*x + vb*y + vc*z + vd = 0 偲偡傞
//    ---------------------------------
//    亙奜愊偱媮傔傞亜
//
//    媮傔傞柺偺朄慄偼(va, vb, vc)
//    媮傔傞柺偺朄慄偼 (ey*ez, ex*ez, ey*ex)偵悅捈偱偐偮丄AB仺(-ex, ey, 0 )偲傕悅捈側偺偱
//    (ey*ez, ex*ez, ey*ex) 倶 (-ex, ey, 0 ) = (va, vb, vc)
//
//    (va, vb, vc) =
//    ( - (ey*ex)* ey, (ey*ex)*(-ex) , (ey*ez)*ey - (ex*ez)*(-ex))
//    ( -ex*ey^2, -ex^2*ey , (ey^2+ex^2)*ez)
//
//    -------------
//
//    亙撪愊偑0偱媮傔傞亜
//
//    媮傔傞柺偺朄慄偼 (ey*ez, ex*ez, ey*ex)偵悅捈側偺偱
//    (ey*ez, ex*ez, ey*ex)丒(va, vb, vc) = 0
//    ey*ez*va + ex*ez*vb + ey*ex*vc = 0        丒丒丒嘆
//
//    媮傔傞柺偺朄慄偼AB仺(-ex, ey, 0 )偲傕悅捈側偺偱
//    (-ex, ey, 0 )丒(va, vb, vc) = 0
//    -ex*va + ey*vb = 0 丒丒丒嘇
//
//    偙偙偱 朄慄儀僋僩儖(va, vb, vc) z惉暘 vc=1 乮z惉暘朄慄偼偣偄偲偄偆偺偑恾傛傝傢偐偭偨偺偱乯偲偡傞偲
//
//    ey*ez*va + ex*ez*vb + ey*ex = 0  丒丒丒嘆乫
//    -ex*va + ey*vb = 0               丒丒丒嘇
//
//    va=(ey*vb)/ex 傪嘆乫傊
//
//    ey*ez*((ey*vb)/ex) + ex*ez*vb + ey*ex = 0
//
//    vb=-(ex^2*ey)/((ey^2+ex^2)*ez)
//    嘇傊戙擖
//
//    -ex*va + ey*(-(ex^2*ey)/((ey^2+ex^2)*ez)) = 0
//    va=-(ex*ey^2)/((ey^2+ex^2)*ez)
//
//    傛偭偰朄慄(va, vb, vc) =
//     (-(ex*ey^2)/((ey^2+ex^2)*ez), -(ex^2*ey)/((ey^2+ex^2)*ez), 1)
//
//    ((ey^2+ex^2)*ez)傪妡偗偰惍棟
//    (-ex*ey^2, -ex^2*ey, (ey^2+ex^2)*ez)
//
//
//    -----------------------------------------------------
//
//    (-ex*ey^2)*x + (-ex^2*ey)*y + ((ey^2+ex^2)*ez)*z + vd = 0
//    偑 A(ex,0,0) 傪捠傞偺偱
//    (-ex*ey^2)*ex + vd = 0
//    vd=ex^2*ey^2
//
//    傛偭偰媮傔偨偄暯柺偼
//    (-ex*ey^2)*x + (-ex^2*ey)*y + ((ey^2+ex^2)*ez)*z + (ex^2*ey^2) = 0
//

//    摨條偵偟偰丄
//
//    B(0,ey,0) C(0,0,ez) 傪娷傓幬柺偵悅捈側柺傪媮傔傞
//
//    媮傔傞柺傪
//    va*x + vb*y + vc*z + vd = 0 偲偡傞
//
//    媮傔傞柺偺朄慄偼 (ey*ez, ex*ez, ey*ex)偵悅捈側偺偱
//    (ey*ez, ex*ez, ey*ex)丒(va, vb, vc) = 0
//    ey*ez*va + ex*ez*vb + ey*ex*vc = 0        丒丒丒嘆
//
//
//    媮傔傞柺偺朄慄偼BC仺(0, -ey, ez)偲傕悅捈側偺偱
//    (0, -ey, ez)丒(va, vb, vc) = 0
//    -ey*vb + ez*vc = 0 丒丒丒嘇
//
//    偙偙偱 朄慄儀僋僩儖(va, vb, vc) x惉暘 va=1 乮x惉暘朄慄偼惓偲偄偆偺偑恾傛傝傢偐偭偨偺偱乯偲偡傞偲
//
//    ey*ez + ex*ez*vb + ey*ex*vc = 0     丒丒丒嘆乫
//    -ey*vb + ez*vc = 0                  丒丒丒嘇乫
//
//    vb=(ez*vc)/ey 傪 嘆乫傊戙擖
//
//    ey*ez + ex*ez*((ez*vc)/ey) + ey*ex*vc = 0
//
//    vc=-(ey^2*ez)/(ex*ez^2+ex*ey^2)
//    嘇乫傊戙擖
//    -ey*vb + ez*(-(ey^2*ez)/(ex*ez^2+ex*ey^2)) = 0
//
//    vb=-(ey*ez^2)/(ex*ez^2+ex*ey^2)
//
//    傛偭偰朄慄(va, vb, vc) =
//    (1, -(ey*ez^2)/(ex*ez^2+ex*ey^2), -(ey^2*ez)/(ex*ez^2+ex*ey^2))
//
//    (ex*ez^2+ex*ey^2) 傪妡偗偰惍棟
//
//    (ex*(ez^2+ey^2), -ey*ez^2, -ey^2*ez)
//    -----------------------------------------------------
//
//    (ex*(ez^2+ey^2))*x + (-ey*ez^2)*y + (-ey^2*ez)*z + vd = 0
//    偑B(0,ey,0) 傪捠傞偺偱丄
//    (-ey*ez^2)*ey + vd = 0
//    vd=ey^2*ez^2
//
//    傛偭偰媮傔偨偄暯柺偼
//
//    (ex*(ez^2+ey^2))*x + (-ey*ez^2)*y + (-ey^2*ez)*z + (ey^2*ez^2) = 0


//    摨條偵偟偰
//    C(0,0,ez) A(ex,0,0) 傪娷傓幬柺偵悅捈側柺傪媮傔傞
//
//    媮傔傞柺傪
//    va*x + vb*y + vc*z + vd = 0 偲偡傞
//
//    媮傔傞柺偺朄慄偼 (ey*ez, ex*ez, ey*ex)偵悅捈側偺偱
//    (ey*ez, ex*ez, ey*ex)丒(va, vb, vc) = 0
//    ey*ez*va + ex*ez*vb + ey*ex*vc = 0        丒丒丒嘆
//
//    媮傔傞柺偺朄慄偼CA仺(ex, 0, -ez)偲傕悅捈側偺偱
//    (ex, 0, -ez)丒(va, vb, vc) = 0
//    ex*va - ez*vc = 0 丒丒丒嘇
//
//    偙偙偱 朄慄儀僋僩儖(va, vb, vc) y惉暘 vb=1 乮y惉暘朄慄偼惓偲偄偆偺偑恾傛傝傢偐偭偨偺偱乯偲偡傞偲
//
//    ey*ez*va + ex*ez + ey*ex*vc = 0        丒丒丒嘆乫
//    ex*va - ez*vc = 0                      丒丒丒嘇
//
//    va=(ez*vc)/ex  傪嘆乫傊戙擖
//
//    ey*ez*((ez*vc)/ex) + ex*ez + ey*ex*vc = 0
//    vc=-(ex^2*ez)/(ey*ez^2+ex^2*ey)
//    嘇傊戙擖
//    ex*va - ez*(-(ex^2*ez)/(ey*ez^2+ex^2*ey)) = 0
//    va=-(ex*ez^2)/(ey*ez^2+ex^2*ey)
//
//
//    傛偭偰朄慄(va, vb, vc) =
//    (-(ex*ez^2)/(ey*ez^2+ex^2*ey), 1, -(ex^2*ez)/(ey*ez^2+ex^2*ey))
//
//    (ey*ez^2+ex^2*ey) 傪妡偗偰惍棟
//
//    (-ex*ez^2, ey*(ez^2+ex^2), -ex^2*ez)
//
//    -----------------------------------------------------
//    (-ex*ez^2)*x + (ey*(ez^2+ex^2))*y + (-ex^2*ez)*z + vd = 0
//    偑 C(0,0,ez) 傪捠傞偺偱丄
//    (-ex^2*ez)*ez + vd = 0
//    vd=ex^2*ez^2
//
//    傛偭偰媮傔偨偄暯柺偼
//
//    (-ex*ez^2)*x + (ey*(ez^2+ex^2))*y + (-ex^2*ez)*z + ex^2*ez^2 = 0
//   傛偭偰幬柺傪掙柺偲偟偨嶰妏拰乮崅偝柍尷乯偺斖埻偼
//    (ey*ez)*x + (ex*ez)*y + (ey*ex)*z - ex*ey*ez > 0      幬柺
//    (-ex*ey^2)*x       + (-ex^2*ey)*y       + (ez*(ex^2+ey^2))*z + (ex^2*ey^2) > 0
//    (ex*(ey^2+ez^2))*x + (-ey*ez^2)*y       + (ey^2*ez)*z        + (ey^2*ez^2) > 0
//    (-ez^2*ex)*x       + (ey*(ez^2+ex^2))*y + (-ez*ex^2)*z       + (ez^2*ex^2) > 0

//媴偲僺儔儈僢僪乽捀揰偲曈偺嫬奅柺乿
//    乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕乕
//        尨揰偵嶰捈妏捀揰傪偍偒丄A(ex,0,0), B(0,ey,0), C(0,0,ez) 偺嶰捈妏嶰妏悕傪峫偊 (ex>0, ey>0, ez>0)
//        A(ex,0,0), B(0,ey,0) 傪娷傓xy暯柺偵悅捈側柺傪媮傔傞
//        媮傔傞柺傪
//        va*x + vb*y + vc*z + vd = 0 偲偡傞
//
//        朄慄(va, vb, vc) = (-ey, -ex, 0)  側偺偱
//        -ey*x -ex*y + vd = 0   偲側傝丄偙傟偑A(ex,0,0)傪捠傞偺偱
//        -ey*ex + vd = 0
//        vd = ex*ey
//
//        傛偭偰媮傔傞柺偼
//        -ey*x - ex*y + ex*ey = 0
//
//    -----------
//        B(0,ey,0), C(0,0,ez) 傪娷傓yz暯柺偵悅捈側柺傪媮傔傞
//        va*x + vb*y + vc*z + vd = 0 偲偡傞
//
//        朄慄(va, vb, vc) = (0, -ez, -ey)  側偺偱
//        -ez*y - ey*z + vd = 0   偲側傝丄偙傟偑B(0,ey,0)傪捠傞偺偱
//        -ez*ey + vd = 0
//        vd = ey*ez
//
//        傛偭偰媮傔傞柺偼
//        -ez*y - ey*z + ey*ez = 0
//
//    ------------------------
//        C(0,0,ez), A(ex,0,0) 傪娷傓zx暯柺偵悅捈側柺傪媮傔傞
//        va*x + vb*y + vc*z + vd = 0 偲偡傞
//
//        朄慄(va, vb, vc) = (-ez, 0, -ex)  側偺偱
//        -ez*x - ex*z + vd = 0 偲側傝丄偙傟偑C(0,0,ez)傪捠傞偺偱
//        -ex*ez + vd = 0
//        vd=ez*ex
//
//        傛偭偰媮傔傞柺偼
//       -ez*x - ex*z + ez*ex = 0
//    ------------------------

//奜愊儊儌
//     a仺=(ax,ay,az),
//     b仺=(bx,by,bz)
//    (ay*bz - az*by, az*bx - ax*bz, ax*by - ay*bx)

//    A(ex,0,0), B(0,ey,0), C(0,0,ez)
//
//    亙揰B偲曈BA偺嫬奅柺亜
//    幬柺偺曽掱幃
//    (ey*ez)*x + (ex*ez)*y + (ey*ex)*z - ex*ey*ez = 0
//    傛傝丄
//
//    B(0,ey,0)傪捠傝幬柺朄慄 (ey*ez, ex*ez, ey*ex) 偵暯峴側慄偱偁傞偺偱丄
//    (x,y,z) = (0,ey,0) + t(ey*ez, ex*ez, ey*ex)  丒丒丒嘆
//
//    A(ex,0,0)傪捠傝柺zx 偵暯峴側乮嫬奅偺乯慄偦偺侾偼
//    (x,y,z) = (0,ey,0) + t(0, 0, -1)  丒丒丒嘇
//
//    嘆嘇傪娷傓柺傪媮傔傞
//    偙偺柺偺朄慄傪(a,b,c) 偲偡傞偲
//    奜愊偼悅捈傛傝
//    (ey*ez, ex*ez, ey*ex)倶(0, 0, -1) = (-ex*ez, ey*ez, 0)
//
//    -ex*ez * x + ey*ez * y + d = 0
//    偙傟偑揰B(0,ey,0)傪捠傞偺偱
//    d = -ey^2*ez
//
//    媮傔傞柺偼
//    -ex*ez * x + ey*ez * y - ey^2*ez = 0    丒丒丒揰B偲曈BA偺嫬奅柺
//    ------------------------------------------------
//    亙揰B偲曈BC偺嫬奅柺亜
//    (x,y,z) = (ex,0,0) + t(ey*ez, ex*ez, ey*ex)  丒丒丒嘆
//    B(0,ey,0)傪捠傝柺zx 偵暯峴側乮嫬奅偺乯慄偦偺俀偼
//    (x,y,z) = (ex,0,0) + t(-1, 0, 0)  丒丒丒嘇
//    嘆嘇傪娷傓柺傪媮傔傞
//    偙偺柺偺朄慄傪(a,b,c) 偲偡傞偲
//    奜愊偼悅捈傛傝
//    (-1, 0, 0)倶(ey*ez, ex*ez, ey*ex) = (0, ey*ex, -ex*ez)
//
//    ey*ex * y - ex*ez * z + d = 0
//
//    偙傟偑揰B(0,ey,0)傪捠傞偺偱
//    d = -ey^2*ex
//
//    媮傔傞柺偼
//    ey*ex * y - ex*ez * z - ey^2*ex = 0   丒丒丒揰B偲曈BC偺嫬奅柺
//
//
//    ------------------------------------------------
//    亙揰A偲曈AB偺嫬奅柺亜
//    奜愊偼悅捈傛傝偙偺柺偺朄慄儀僋僩儖偼
//    (0, 0, -1)倶(ey*ez, ex*ez, ey*ex) =  (ex*ez, -ey*ez, 0)
//
//    ex*ez * x - ey*ez * y + d = 0
//    偙傟偑揰A(ex,0,0)傪捠傞偺偱
//    d = -ex^2*ez
//
//    媮傔傞柺偼
//    ex*ez * x - ey*ez * y - ex^2*ez = 0   丒丒丒揰A偲曈AB偺嫬奅柺
//    ------------------------------------------------
//    亙揰A偲曈AC偺嫬奅柺亜
//    奜愊偼悅捈傛傝偙偺柺偺朄慄儀僋僩儖偼
//    (ey*ez, ex*ez, ey*ex)倶(0, -1, 0) = (ey*ex, 0, -ey*ez)
//
//    ey*ex * x - ey*ez * z + d = 0
//    偙傟偑揰A(ex,0,0)傪捠傞偺偱
//    d = -ey*ex^2
//
//    媮傔傞柺偼
//    ey*ex * x - ey*ez * z - ey*ex^2 = 0   丒丒丒揰A偲曈AC偺嫬奅柺
//
//
//    ------------------------------------------------
//    亙揰C偲曈CA偺嫬奅柺亜
//    奜愊偼悅捈傛傝偙偺柺偺朄慄儀僋僩儖偼
//    (0, -1, 0)倶(ey*ez, ex*ez, ey*ex) = (-ey*ex, 0, ey*ez)
//    -ey*ex * x + ey*ez * z + d = 0
//    偙傟偑揰 C(0,0,ez) 傪捠傞偺偱
//    d = -ey*ez^2
//    媮傔傞柺偼
//    -ey*ex * x + ey*ez * z -ey*ez^2 = 0  丒丒丒揰C偲曈CA偺嫬奅柺
//    ------------------------------------------------
//    亙揰C偲曈CB偺嫬奅柺亜
//    奜愊偼悅捈傛傝偙偺柺偺朄慄儀僋僩儖偼
//    (ey*ez, ex*ez, ey*ex)倶(-1, 0, 0) = (0, -ey*ex, ex*ez)
//    -ey*ex * y + ex*ez * z + d = 0
//    偙傟偑揰 C(0,0,ez) 傪捠傞偺偱
//    d = -ex*ez^2
//    媮傔傞柺偼
//    -ey*ex * y + ex*ez * z - ex*ez^2 = 0    丒丒丒揰C偲曈CB偺嫬奅柺
//
//    ex*ez * x - ey*ez * y             - ex^2*ez = 0   丒丒丒揰A偲曈AB偺嫬奅柺
//    ey*ex * x             - ey*ez * z - ey*ex^2 = 0   丒丒丒揰A偲曈AC偺嫬奅柺
//
//   -ex*ez * x + ey*ez * y             - ey^2*ez = 0    丒丒丒揰B偲曈BA偺嫬奅柺
//                ey*ex * y - ex*ez * z - ey^2*ex = 0    丒丒丒揰B偲曈BC偺嫬奅柺
//
//   -ey*ex * x             + ey*ez * z - ey*ez^2 = 0    丒丒丒揰C偲曈CA偺嫬奅柺
//               -ey*ex * y + ex*ez * z - ex*ez^2 = 0    丒丒丒揰C偲曈CB偺嫬奅柺
