Point2F BiQuadToSqr::transform( const Point2F &p ) const { Point2F kA = m_kP00 - p; F32 fAB = mDotPerp( kA, m_kB ); F32 fAC = mDotPerp( kA, m_kC); // 0 = ac*bc+(bc^2+ac*bd-ab*cd)*s+bc*bd*s^2 = k0 + k1*s + k2*s^2 F32 fK0 = fAC*m_fBC; F32 fK1 = m_fBC*m_fBC + fAC*m_fBD - fAB*m_fCD; F32 fK2 = m_fBC*m_fBD; if (mFabs(fK2) > POINT_EPSILON) { // s-equation is quadratic F32 fInv = 0.5f/fK2; F32 fDiscr = fK1*fK1 - 4.0f*fK0*fK2; F32 fRoot = mSqrt( mFabs(fDiscr) ); Point2F kResult0( 0, 0 ); kResult0.x = (-fK1 - fRoot)*fInv; kResult0.y = fAB/(m_fBC + m_fBD*kResult0.x); F32 fDeviation0 = deviation(kResult0); if ( fDeviation0 == 0.0f ) return kResult0; Point2F kResult1( 0, 0 ); kResult1.x = (-fK1 + fRoot)*fInv; kResult1.y = fAB/(m_fBC + m_fBD*kResult1.x); F32 fDeviation1 = deviation(kResult1); if ( fDeviation1 == 0.0f ) return kResult1; if (fDeviation0 <= fDeviation1) { if ( fDeviation0 < POINT_EPSILON ) return kResult0; } else { if ( fDeviation1 < POINT_EPSILON ) return kResult1; } } else { // s-equation is linear Point2F kResult( 0, 0 ); kResult.x = -fK0/fK1; kResult.y = fAB/(m_fBC + m_fBD*kResult.x); F32 fDeviation = deviation(kResult); if ( fDeviation < POINT_EPSILON ) return kResult; } // point is outside the quadrilateral, return invalid return Point2F(F32_MAX,F32_MAX); }
BiQuadToSqr::BiQuadToSqr( const Point2F &p00, const Point2F &p10, const Point2F &p11, const Point2F &p01 ) : m_kP00( p00 ) { m_kB = p10 - p00; // width m_kC = p01 - p00; // height m_kD = p11 + p00 - p10 - p01; // diagonal dist m_fBC = mDotPerp( m_kB, m_kC ); m_fBD = mDotPerp( m_kB, m_kD ); m_fCD = mDotPerp( m_kC, m_kD ); }
BiQuadToSqr::BiQuadToSqr( const Point2F &p00, const Point2F &p10, const Point2F &p11, const Point2F &p01 ) : m_kP00( p00 ) { m_kB = p10 - p00 ; // width m_kC = p01 - p00; // height m_kD = p11 + p00 - p10 - p01; // diagonal dist if(mFabs(m_kD.x) < POINT_EPSILON) m_kD.x = 0.f; if(mFabs(m_kD.y) < POINT_EPSILON) m_kD.y = 0.f; m_fBC = mDotPerp( m_kB, m_kC ); m_fBD = mDotPerp( m_kB, m_kD ); m_fCD = mDotPerp( m_kC, m_kD ); }