/******************************Module*Header*******************************\ * Module Name: epointfl.hxx * * * * Energized point consisting of two floats. * * * * Created: 11-Jan-1991 13:30:27 * * Author: Bodin Dresevic [BodinD] * * * * Dependencies: * * * * Must include efloat.hxx for this file to compile. * * * * Copyright (c) 1990-1999 Microsoft Corporation * \**************************************************************************/ /*********************************Class************************************\ * class POINTFL * * point given with the floating point precision * * * History: * 11-Jan-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ class POINTFL { public: EFLOAT x; EFLOAT y; }; typedef POINTFL *PPOINTFL; class VECTORFL : public POINTFL {}; typedef VECTORFL *PVECTORFL; /*********************************Class************************************\ * class EPOINTFL :public POINTFL * * energized version of POINTFL, allows for subtracion, addition etc; * * * History: * 11-Jan-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ class EPOINTFL; EFLOAT efDet(EPOINTFL& eptfl1,EPOINTFL& eptfl2); // determinant class EPOINTFL : public POINTFL // eptfl { public: // Constructor -- This one is to allow EPOINTFL inside other classes. EPOINTFL() {} // Several constructors -- Initializes EPOINTFL in various ways, // the assignment operator for EFLOAT is used EPOINTFL(LONG x1,LONG y1) { x = x1; y = y1; } // Constructor -- initializes EPOINTFL using two FLOAT's which is an // external (to the engine) type, (as oppossed to EFLOAT, which is // an internal type) EPOINTFL(FLOATL x1,FLOATL y1) { x = x1; y = y1; } // Constructor -- with internal type EFLOAT EPOINTFL(const EFLOAT& x1,const EFLOAT& y1) { x = x1; y = y1; } // Destructor -- Does nothing. ~EPOINTFL() {} // Operator= -- Create from a POINTL VOID operator=(POINTL& ptl) { x = ptl.x; y = ptl.y; } // Operator= -- Create from a POINTFIX VOID operator=(POINTFIX& ptfx) { x.vFxToEf(ptfx.x); y.vFxToEf(ptfx.y); } // Operator= -- Create from POINTE VOID operator=(POINTE& pte) { x = pte.x; y = pte.y; } // Operator+= -- Add in another EPOINTFL. VOID operator+=(EPOINTFL& eptfl) { x += eptfl.x; y += eptfl.y; } // Operator-= -- subtract another EPOINTFL. VOID operator-=(EPOINTFL& eptfl) { x -= eptfl.x; y -= eptfl.y; } // Operator*= -- multiply vector by a LONG number VOID operator*=(LONG l) { EFLOAT ef; ef = l; x *= ef; y *= ef; } // Operator*= -- multiply vector by an EFLOAT VOID operator*=(EFLOAT ef) { x *= ef; y *= ef; } // Multiply by a LONG. EPOINTFL& eqMul(EPOINTFL& ptfl,LONG l) { EFLOAT ef; ef = l; x.eqMul(ptfl.x,ef); y.eqMul(ptfl.y,ef); return(*this); } // Multiply by an EFLOAT. EPOINTFL& eqMul(EPOINTFL& ptfl,EFLOAT& ef) { x.eqMul(ptfl.x,ef); y.eqMul(ptfl.y,ef); return(*this); } // Divide by an EFLOAT. EPOINTFL& eqDiv(EPOINTFL& ptfl,EFLOAT& ef) { x.eqDiv(ptfl.x,ef); y.eqDiv(ptfl.y,ef); return(*this); } VOID operator/=(EFLOAT ef) { x /= ef; y /= ef; } // Divide by a LONG. EPOINTFL& eqDiv(EPOINTFL& ptfl,LONG l) { EFLOAT ef; ef = l; x.eqDiv(ptfl.x,ef); y.eqDiv(ptfl.y,ef); return(*this); } // bToPOINTL -- rounds the position to the "nearest" position on // the integer grid BOOL bToPOINTL(POINTL& ptl) { return(x.bEfToL(ptl.x) && y.bEfToL(ptl.y)); } // bToPOINTFIX -- converts to the "nearest" position on // the FIX grid BOOL bToPOINTFIX(POINTFIX& ptfx) { return(x.bEfToFx(ptfx.x) && y.bEfToFx(ptfx.y)); } // bIsZero() -- checks if This is a null vector BOOL bIsZero() { return(x.bIsZero() && y.bIsZero()); } // bBetween(eptfl1,eptfl2) -- checks whether this vector is between // eptfl1 and eptfl2. The caller must ensure // that det(eptfl2,eptfl1) >= 0, i.e. if the // vectors (1,2) are not collinear, they must form // a basis with right handed orientation. // Note: In windows we use left handed coords, so that det required to be // non-negative is det(2,1) rather than det(1,2) /* BOOL bBetween(EPOINTFL& eptfl1,EPOINTFL& eptfl2) { ASSERTGDI(!bIsZero(), "EPOINTFL::bBetween: this == (0,0)\n"); ASSERTGDI(!eptfl1.bIsZero(), "EPOINTFL::bBetween: eptfl1 == (0,0)\n"); ASSERTGDI(!eptfl2.bIsZero(), "EPOINTFL::bBetween: eptfl2 == (0,0)\n"); EFLOAT efDet21 = efDet(eptfl2, eptfl1); EFLOAT efDet2This = efDet(eptfl2, *this); ASSERTGDI(!efDet21.bIsNegative(), "EPOINTFL::bBetween: orientation\n"); if (efDet21.bIsZero() && !(eptfl1 * eptfl2).bIsNegative()) { // vectors 1 and 2 are colinear AND point in the same direction if (efDet2This.bIsZero() && !((*this) * eptfl2).bIsNegative()) { // This is also colinear with 1 and 2 and points in // the SAME direction as 1 and 2 return(TRUE); // ------->1 , -------->2, -------> this } else { // This is either NOT colinear with 1 and 2, OR // This is colinear with 1 and 2 but points opposite from 1 and 2 return(FALSE); // ------->1 , -------->2, <------- this } } else { // vectors 1 and 2 are either NOT colinear OR // are colinear and point in OPPOSITE directions EFLOAT efDetThis1 = efDet(*this,eptfl1); // must compute it now if (!efDet2This.bIsNegative() && !efDetThis1.bIsNegative()) return(TRUE); // This lies between 1 and 2 else return(FALSE); } } */ // vSetToZero -- make the null vetor VOID vSetToZero() { x.vSetToZero(); y.vSetToZero(); } }; typedef EPOINTFL *PEPOINTFL; /*********************************Class************************************\ * class EVECTORFL : public EPOINTFL * * Energized class for VECTORFL. * * History: * 27-Jan-1992 -by- Wendy Wu [wendywu] * Wrote it. \**************************************************************************/ class EVECTORFL : public EPOINTFL { public: // Constructor -- This one is to allow EVECTORFL inside other classes. EVECTORFL() {} // Several constructors -- Initializes EVECTORFL in various ways, // the assignment operator for EFLOAT is used EVECTORFL(EVECTORFL& evfl) { x = evfl.x; y = evfl.y; } EVECTORFL(LONG x1,LONG y1) { x = x1; y = y1; } EVECTORFL(EPOINTFL& eptfl) { x = eptfl.x; y = eptfl.y; } VOID operator=(POINTL& ptl) { x = ptl.x; y = ptl.y; } VOID operator=(POINTE& pte) { x = pte.x; y = pte.y; } VOID operator=(EPOINTFL& eptfl) { x = eptfl.x; y = eptfl.y; } VOID operator=(EVECTORFL& evfl) { x = evfl.x; y = evfl.y; } VOID operator=(VECTORFL& vfl) { x = vfl.x; y = vfl.y; } }; /*********************************Class************************************\ * class RECTFL * * similar to RECTL, rectangle given with EFLOAT precision * * History: * 04-Mar-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ class RECTFL { public: EFLOAT xLeft; EFLOAT yTop; EFLOAT xRight; EFLOAT yBottom; }; typedef RECTFL *PRECTFL; /*********************************Class************************************\ * class ERECTFL:public RECTFL * * similar to ERECTL, code stolen, based on EFLOAT * * History: * 04-Mar-1991 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ class ERECTFL:public RECTFL // ercfl { public: // Constructor -- Allows ERECTFLs inside other classes. ERECTFL() {} // Constructor -- Initialize the rectangle. ERECTFL(LONG x1,LONG y1,LONG x2,LONG y2) { xLeft = x1; yTop = y1; xRight = x2; yBottom = y2; } // Constructor -- Initialize the rectangle. ERECTFL(EFLOAT& x1,EFLOAT& y1,EFLOAT& x2,EFLOAT& y2) { xLeft = x1; yTop = y1; xRight = x2; yBottom = y2; } // Destructor -- Does nothing. ~ERECTFL() {} /* // Constructor -- energize given rectangle so that it can be manipulated ERECTFL(RECTFL& rcfl) { xLeft = rcfl.xLeft ; yTop = rcfl.yTop ; xRight = rcfl.xRight ; yBottom = rcfl.yBottom ; } */ // Operator+= -- Offset the ERECTFL. VOID operator+=(POINTFL& ptfl) { xLeft += ptfl.x; xRight += ptfl.x; yTop += ptfl.y; yBottom += ptfl.y; } // Operator-= -- Offset the ERECTFL. VOID operator-=(POINTFL& ptfl) { xLeft -= ptfl.x; xRight -= ptfl.x; yTop -= ptfl.y; yBottom -= ptfl.y; } // Operator+= -- Add another RECTFL. Only the destination may be empty. VOID operator+=(RECTFL& rcfl) { if ((xLeft == xRight) || (yTop == yBottom)) *((RECTFL *) this) = rcfl; else { if (rcfl.xLeft <= xLeft) xLeft = rcfl.xLeft; if (rcfl.yTop <= yTop) yTop = rcfl.yTop; if (rcfl.xRight > xRight) xRight = rcfl.xRight; if (rcfl.yBottom > yBottom) yBottom = rcfl.yBottom; } } // Operator*= -- Intersect another RECTFL. The result may be empty. ERECTFL& operator*= (RECTFL& rcfl) { { if (rcfl.xLeft > xLeft) xLeft = rcfl.xLeft; if (rcfl.yTop > yTop) yTop = rcfl.yTop; if (rcfl.xRight <= xRight) xRight = rcfl.xRight; if (rcfl.yBottom <= yBottom) yBottom = rcfl.yBottom; if (xRight <= xLeft) xLeft = xRight; // Only need to collapse one pair else if (yBottom <= yTop) yTop = yBottom; } return(*this); } // vOrder -- Make the rectangle well ordered. VOID vOrder() { EFLOAT ef; if (xLeft > xRight) { ef = xLeft; xLeft = xRight; xRight = ef; } if (yTop > yBottom) { ef = yTop; yTop = yBottom; yBottom = ef; } } }; typedef ERECTFL *PERECTFL;