V(TgVEC) V(tgGM_Support_Point_CY)( V(CPCU_TgTUBE) ptgCY0, V(CPCU_TgVEC) ptvDirN )
{
const TYPE tyUAX_N = V(F_DOT_VV)( ptvDirN, &ptgCY0->m.m.vU_HAX );
V(TgVEC) tvResult;
TYPE fTest;
TgASSERT( F(tgCM_NR1)( V(F_LSQ)( ptvDirN ) ) && V(F_Is_Vector_Valid)( ptvDirN ) );
if (tyUAX_N > F(KTgEPS))
{
tvResult = V(F_ADD_VV)( &ptgCY0->m.m.vOrigin, &ptgCY0->m_vHAX );
}
else if (tyUAX_N < -F(KTgEPS))
{
tvResult = V(F_SUB_VV)( &ptgCY0->m.m.vOrigin, &ptgCY0->m_vHAX );
}
else
{
tvResult = ptgCY0->m.m.vOrigin;
}
{
V(C_TgVEC) tvX0 = V(F_MUL_SV)( tyUAX_N, &ptgCY0->m.m.vU_HAX );
V(C_TgVEC) tvX1 = V(F_SUB_VV)( ptvDirN, &tvX0 );
V(C_TgVEC) tvRadial = V(F_NORM_LEN)( &fTest, &tvX1 );
if (fTest > F(KTgEPS))
{
tvResult = V(F_MAD_SVV)( ptgCY0->m_fRadius, &tvRadial, &tvResult );
};
}
return (tvResult);
}
TgBOOL V(tgGM_Is_Cap_Contained_CY)(
V(PCU_TgELLIPSE) ptgEL0, V(CPCU_TgTUBE) ptgCY0, const TYPE tyDS_C0A, V(CPCU_TgTUBE) ptgCY1, const TYPE tyDS_C1A
) {
V(C_TgVEC) tvX0 = V(F_MUL_SV)( ptgCY0->m.m.vU_HAX.m.x, &ptgCY0->m.m.vU_HAX );
V(C_TgVEC) tvX1 = V(F_MUL_SV)( ptgCY0->m.m.vU_HAX.m.y, &ptgCY0->m.m.vU_HAX );
V(C_TgVEC) tvX2 = V(F_MUL_SV)( ptgCY0->m.m.vU_HAX.m.z, &ptgCY0->m.m.vU_HAX );
V(C_TgVEC) tvXF0 = V(F_SUB_VV)( &(V(KTgV_UNIT_X)), &tvX0 );
V(C_TgVEC) tvXF1 = V(F_SUB_VV)( &(V(KTgV_UNIT_Y)), &tvX1 );
V(C_TgVEC) tvXF2 = V(F_SUB_VV)( &(V(KTgV_UNIT_Z)), &tvX2 );
V(C_TgVEC) tvB0 = V(F_MUL_SV)( F(tgPM_FSEL)(tyDS_C0A, MKL(1.0), MKL(-1.0)), &ptgCY0->m_vHAX );
V(C_TgVEC) tvB1 = V(F_MUL_SV)( F(tgPM_FSEL)(tyDS_C1A, MKL(-1.0), MKL(1.0)), &ptgCY1->m_vHAX );
V(C_TgVEC) tvW0 = V(F_ADD_VV)( &ptgCY0->m.m.vOrigin, &tvB0 );
V(C_TgVEC) tvW1 = V(F_ADD_VV)( &ptgCY1->m.m.vOrigin, &tvB1 );
const TYPE tyA0 = V(F_DOT_VV)( &tvXF0, &tvW0 );
const TYPE tyA1 = V(F_DOT_VV)( &tvXF1, &tvW0 );
const TYPE tyA2 = V(F_DOT_VV)( &tvXF2, &tvW0 );
const TYPE tyB0 = V(F_DOT_VV)( &tvXF0, &tvW1 );
const TYPE tyB1 = V(F_DOT_VV)( &tvXF1, &tvW1 );
const TYPE tyB2 = V(F_DOT_VV)( &tvXF2, &tvW1 );
V(C_TgVEC) tvW2 = V(F_SETP_ELEM)( tyA0, tyA1, tyA2 );
V(C_TgVEC) tvW3 = V(F_SETP_ELEM)( tyB0, tyB1, tyB2 );
const TYPE tyU0 = V(F_DOT_VV)( &tvXF0, &ptgCY1->m.m.vU_HAX );
const TYPE tyU1 = V(F_DOT_VV)( &tvXF1, &ptgCY1->m.m.vU_HAX );
const TYPE tyU2 = V(F_DOT_VV)( &tvXF2, &ptgCY1->m.m.vU_HAX );
V(TgVEC) tvA0, tvA1;
V(TgVEC) tvAxis;
TYPE tyRadiusRatio;
tvAxis = V(F_SETV_ELEM)( tyU0, tyU1, tyU2 );
if (V(F_LSQ)( &tvAxis ) > F(KTgEPS))
{
tvA0 = V(F_UCX)( &tvAxis, &ptgCY0->m.m.vU_HAX );
tvAxis = V(F_CX)( &ptgCY1->m.m.vU_HAX, &tvA0 );
tvA1 = V(F_SETV_ELEM)( V(F_DOT_VV)(&tvXF0, &tvAxis), V(F_DOT_VV)(&tvXF1, &tvAxis), V(F_DOT_VV)(&tvXF2, &tvAxis) );
}
else
{
tvA0 = ptgCY0->m.m.vU_Basis0;
tvA1 = ptgCY0->m.m.vU_Basis1;
};
tvA1 = V(F_NORM_LEN)( &tyRadiusRatio, &tvA1 );
{
const TYPE tyMajRad = tyRadiusRatio*ptgCY1->m_fRadius;
const TYPE tyA00 = V(F_DOT_VV)( &tvA0, &ptgCY0->m.m.vU_Basis0 );
const TYPE tyA01 = V(F_DOT_VV)( &tvA0, &ptgCY0->m.m.vU_Basis1 );
const TYPE tyA10 = V(F_DOT_VV)( &tvA1, &ptgCY0->m.m.vU_Basis0 );
const TYPE tyA11 = V(F_DOT_VV)( &tvA1, &ptgCY0->m.m.vU_Basis1 );
const TYPE tyR00 = tyA00 * ptgCY1->m_fRadius;
const TYPE tyR01 = tyA01 * ptgCY1->m_fRadius;
const TYPE tyR10 = tyA10 * tyMajRad;
const TYPE tyR11 = tyA11 * tyMajRad;
V(C_TgVEC) tvW32 = V(F_SUB_VV)( &tvW3, &tvW2 );
const TYPE tyWC0 = V(F_DOT_VV)( &tvW32, &ptgCY0->m.m.vU_Basis0 );
const TYPE tyWC1 = V(F_DOT_VV)( &tvW32, &ptgCY0->m.m.vU_Basis1 );
V(tgGM_Set_Origin_EL)( ptgEL0, &tvW3 );
V(tgGM_Set_Minor_Unit_EL)( ptgEL0, &tvA0 );
V(tgGM_Set_Normal_EL)( ptgEL0, &ptgCY0->m.m.vU_HAX );
V(tgGM_Set_Major_Unit_EL)( ptgEL0, &tvA1 );
V(tgGM_Set_Minor_Radius_EL)( ptgEL0, ptgCY1->m_fRadius );
V(tgGM_Set_Major_Radius_EL)( ptgEL0, tyMajRad );
if (
(tyWC0 + tyR00)*(tyWC0 + tyR00) + (tyWC1 + tyR01)*(tyWC1 + tyR01) > ptgCY0->m_fRadiusSq ||
(tyWC0 - tyR00)*(tyWC0 - tyR00) + (tyWC1 - tyR01)*(tyWC1 - tyR01) > ptgCY0->m_fRadiusSq ||
(tyWC0 + tyR10)*(tyWC0 + tyR10) + (tyWC1 + tyR11)*(tyWC1 + tyR11) > ptgCY0->m_fRadiusSq ||
(tyWC0 - tyR10)*(tyWC0 - tyR10) + (tyWC1 - tyR11)*(tyWC1 - tyR11) > ptgCY0->m_fRadiusSq
) {
return (TgFALSE);
};
};
return (TgTRUE);
}