Skip to content

Instantly share code, notes, and snippets.

@gabonator
Created July 3, 2012 12:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gabonator/3039348 to your computer and use it in GitHub Desktop.
Save gabonator/3039348 to your computer and use it in GitHub Desktop.
Line to rectangle clipping
//http://stackoverflow.com/questions/99353/how-to-test-if-a-line-segment-intersects-an-axis-aligned-rectange-in-2d
enum {
OUT_LEFT = 1,
OUT_TOP = 2,
OUT_RIGHT = 4,
OUT_BOTTOM = 8
};
INT _ThroughCode(LONGPOSITION pt)
{
INT out = 0;
if (pt.lX < m_rcBound.lLeft) {
out |= OUT_LEFT;
} else if (pt.lX > m_rcBound.lRight) {
out |= OUT_RIGHT;
}
if (pt.lY > m_rcBound.lTop) {
out |= OUT_TOP;
} else if (pt.lY < m_rcBound.lBottom) {
out |= OUT_BOTTOM;
}
return out;
}
BOOL32 _Through( const LONGPOSITION& ptA, const LONGPOSITION& ptB, LONGPOSITION& ptResultP, LONGPOSITION& ptResultQ )
{
_ASSERT( m_rcBound.GetWidth() > 0 );
_ASSERT( m_rcBound.GetHeight() > 0 );
INT out1, out2;
if ( (out2 = _ThroughCode( ptB ) ) == 0 )
{
// je vovnutri - neni splnena podmienka
_ASSERT( 0 );
return FALSE;
}
ptResultQ = ptB;
ptResultP = ptA;
while ( (out1 = _ThroughCode( ptResultP ) ) != 0 )
{
if ( out1 & out2 )
return FALSE;
if ( out1 & (OUT_LEFT | OUT_RIGHT) )
{
LONG x = (out1 & OUT_RIGHT) ? m_rcBound.lRight : m_rcBound.lLeft;
ptResultP.lY = SMULDIV( ptResultP.lY, (x - ptResultP.lX), (ptResultQ.lY - ptResultP.lY), (ptResultQ.lX - ptResultP.lX) );
ptResultP.lX = x;
} else
{
LONG y = (out1 & OUT_BOTTOM) ? m_rcBound.lBottom : m_rcBound.lTop;
ptResultP.lX = SMULDIV( ptResultP.lX, (y - ptResultP.lY), (ptResultQ.lX - ptResultP.lX), (ptResultQ.lY - ptResultP.lY) );
ptResultP.lY = y;
}
}
// ptA (ptResultP) aligned
while ( (out2 = _ThroughCode( ptResultQ ) ) != 0 )
{
if ( out2 & (OUT_LEFT | OUT_RIGHT) )
{
LONG x = (out2 & OUT_RIGHT) ? m_rcBound.lRight : m_rcBound.lLeft;
ptResultQ.lY = SMULDIV( ptResultQ.lY, (x - ptResultQ.lX), (ptResultP.lY - ptResultQ.lY), (ptResultP.lX - ptResultQ.lX) );
ptResultQ.lX = x;
} else
{
LONG y = (out2 & OUT_BOTTOM) ? m_rcBound.lBottom : m_rcBound.lTop;
ptResultQ.lX = SMULDIV( ptResultQ.lX, (y - ptResultQ.lY), (ptResultP.lX - ptResultQ.lX), (ptResultP.lY - ptResultQ.lY) );
ptResultQ.lY = y;
}
}
// ptB (ptResultQ) aligned
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment