You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
521 lines
11 KiB
521 lines
11 KiB
/******************************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;
|