📄 algo2d.h
字号:
template<typename PixelFunction> inline
void Clear( PixelFunction& F, PHAL::Surface& buffer, Pixel color )
{
Pixel* pDest = buffer.GetPixels();
int width = buffer.GetWidth();
for ( int y = buffer.GetHeight(); y; --y )
{
transform( pDest, pDest + width, pDest, bind1st( F, color ) );
pDest = (Pixel*)((uint8_t*)pDest + buffer.GetPitch());
}
}
template<typename PixelFunction> inline
void FillRect( PixelFunction& F, PHAL::Surface& buffer, const Rect& r, Pixel color )
{
Pixel* pDest = buffer.GetPixels( r.left, r.top );
int width = r.GetWidth();
for ( int y = r.top; y != r.bottom; ++y )
{
transform( pDest, pDest + width, pDest, bind1st( F, color ) );
pDest = (Pixel*)((uint8_t*)pDest + buffer.GetPitch());
}
}
template<typename PixelFunction> inline
void HLine( PixelFunction& F, PHAL::Surface& buffer, const Point& P, int length, Pixel color )
{
Pixel* pDest = buffer.GetPixels( P.x, P.y );
transform( pDest, pDest + length, pDest, bind1st( F, color ) );
}
template<typename PixelFunction> inline
void Line( PixelFunction& F, PHAL::Surface& buffer, const Point& A, const Point& B, Pixel color )
{
// Determine increments
int xincr = 1;
int dx = B.x - A.x;
if (dx < 0)
{
dx = -dx;
xincr = -xincr;
}
int yincr = buffer.GetPitch() / 2;
int dy = B.y - A.y;
if (dy < 0)
{
dy = -dy;
yincr = -yincr;
}
int xyincr = xincr + yincr;
// Find the frame buffer address for each point
Pixel* pA = buffer.GetPixels( A.x, A.y );
Pixel* pB = buffer.GetPixels( B.x, B.y );
// Draw the line
if (dx < dy)
{
int dpr = 2 * dx;
int p = -dy;
int dpru = -2 * dy;
dx = dy >> 1;
for ( ; dx > 0; --dx )
{
*pA = F( color, *pA );
*pB = F( color, *pB );
p += dpr;
if (p > 0)
{
p += dpru;
pA += xyincr;
pB -= xyincr;
}
else
{
pA += yincr;
pB -= yincr;
}
}
*pA = F( color, *pA );
if (dy & 1)
*pB = F( color, *pB );
}
else
{
int dpr = 2 * dy;
int p = -dx;
int dpru = -2 * dx;
dy = dx >> 1;
for ( ; dy > 0; --dy )
{
*pA = F( color, *pA );
*pB = F( color, *pB );
p += dpr;
if (p > 0)
{
p += dpru;
pA += xyincr;
pB -= xyincr;
}
else
{
pA += xincr;
pB -= xincr;
}
}
*pA = F( color, *pA );
if (dx & 1)
*pB = F( color, *pB );
}
}
template<typename PixelFunction> inline
void SetPixel( PixelFunction& F, PHAL::Surface& buffer, const Point& P, Pixel color )
{
Pixel* pDest = buffer.GetPixels( P.x, P.y );
*pDest = F( color, *pDest );
}
template<typename PixelFunction> inline
void SetPixelClip( PixelFunction& F, PHAL::Surface& buffer, const Point& P, Pixel color, const Rect& clipper )
{
if (P.x >= clipper.left && P.y >= clipper.top && P.x < clipper.right && P.y < clipper.bottom)
{
SetPixel( F, buffer, P, color );
}
}
// Function modified 5/9/2003 by Frank W. Zammett
// Changed the line
// while (length-- > 0)
// to
// while (length-- > -1)
// This fixed the problem of rectangles missing the bottom right-hand corner
// pixel, and also vertical lines being one pixel too short.
template<typename PixelFunction> inline
void VLine( PixelFunction& F, PHAL::Surface& buffer, const Point& P, int length, Pixel color )
{
Pixel* pDest = buffer.GetPixels( P.x, P.y );
while (length-- > -1)
{
*pDest = F( color, *pDest );
pDest = (Pixel*)((BYTE*)pDest + buffer.GetPitch());
}
}
template<typename PixelFunction> inline
void Circle( PixelFunction& F, PHAL::Surface& buffer, const Point& P, int radius, Pixel color )
{
int x = 0;
int y = radius;
int d = 3 - 2 * radius;
for ( ; x < y; ++x)
{
SetPixel( F, buffer, Point( P.x - x, P.y - y ), color );
SetPixel( F, buffer, Point( P.x + x, P.y - y ), color );
SetPixel( F, buffer, Point( P.x - x, P.y + y ), color );
SetPixel( F, buffer, Point( P.x + x, P.y + y ), color );
SetPixel( F, buffer, Point( P.x - y, P.y - x ), color );
SetPixel( F, buffer, Point( P.x + y, P.y - x ), color );
SetPixel( F, buffer, Point( P.x - y, P.y + x ), color );
SetPixel( F, buffer, Point( P.x + y, P.y + x ), color );
if (d < 0)
{
d += 4 * x + 6;
}
else
{
d += 4 * (x-y) + 10;
--y;
}
}
if (x==y)
{
SetPixel( F, buffer, Point( P.x - x, P.y - y ), color );
SetPixel( F, buffer, Point( P.x + x, P.y - y ), color );
SetPixel( F, buffer, Point( P.x - x, P.y + y ), color );
SetPixel( F, buffer, Point( P.x + x, P.y + y ), color );
}
}
//fixme: it doesn't make sense to have two circle algorithms
template<typename PixelFunction> inline
void Circle( PixelFunction& F, PHAL::Surface& buffer, const Point& P, int radius, Pixel color, const Rect& clipper )
{
int x = 0;
int y = radius;
int d = 3 - 2 * radius;
for ( ; x < y; ++x)
{
SetPixelClip( F, buffer, Point( P.x - x, P.y - y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x + x, P.y - y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x - x, P.y + y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x + x, P.y + y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x - y, P.y - x ), color, clipper );
SetPixelClip( F, buffer, Point( P.x + y, P.y - x ), color, clipper );
SetPixelClip( F, buffer, Point( P.x - y, P.y + x ), color, clipper );
SetPixelClip( F, buffer, Point( P.x + y, P.y + x ), color, clipper );
if (d < 0)
{
d += 4 * x + 6;
}
else
{
d += 4 * (x-y) + 10;
--y;
}
}
if (x==y)
{
SetPixelClip( F, buffer, Point( P.x - x, P.y - y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x + x, P.y - y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x - x, P.y + y ), color, clipper );
SetPixelClip( F, buffer, Point( P.x + x, P.y + y ), color, clipper );
}
}
} // end of namespace Algo2D
} // end of namespace Internal
} // end of namespace Frog
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -