110,539
社区成员
发帖
与我相关
我的任务
分享
typedef unsigned char uchar;
#define ICV_HLINE( ptr, xl, xr, color, pix_size ) \
{ \
uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size); \
uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size); \
\
for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size)) \
{ \
int hline_j; \
for( hline_j = 0; hline_j < (pix_size); hline_j++ ) \
{ \
hline_ptr[hline_j] = ((uchar*)color)[hline_j]; \
} \
} \
}
#define ICV_PUT_POINT( ptr, x ) \
memcpy( ptr + (x)*pix_size, color, pix_size );
typedef struct _Point2D
{
int x, y;
}Point2D;
typedef struct _Size2D
{
int width, height;
}Size2D;
static void
draw_circle( uchar* ptr, Size2D size, int pix_size, size_t step,
Point2D center, int radius, const void* color, int fill )
{
int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
int inside = center.x >= radius && center.x < size.width - radius &&
center.y >= radius && center.y < size.height - radius;
while( dx >= dy )
{
int mask;
int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
if( inside )
{
uchar *tptr0 = ptr + y11 * step;
uchar *tptr1 = ptr + y12 * step;
if( !fill )
{
ICV_PUT_POINT( tptr0, x11 );
ICV_PUT_POINT( tptr1, x11 );
ICV_PUT_POINT( tptr0, x12 );
ICV_PUT_POINT( tptr1, x12 );
}
else
{
ICV_HLINE( tptr0, x11, x12, color, pix_size );
ICV_HLINE( tptr1, x11, x12, color, pix_size );
}
tptr0 = ptr + y21 * step;
tptr1 = ptr + y22 * step;
if( !fill )
{
ICV_PUT_POINT( tptr0, x21 );
ICV_PUT_POINT( tptr1, x21 );
ICV_PUT_POINT( tptr0, x22 );
ICV_PUT_POINT( tptr1, x22 );
}
else
{
ICV_HLINE( tptr0, x21, x22, color, pix_size );
ICV_HLINE( tptr1, x21, x22, color, pix_size );
}
}
else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
{
if( fill )
{
x11 = std::max( x11, 0 );
x12 = MIN( x12, size.width - 1 );
}
if( (unsigned)y11 < (unsigned)size.height )
{
uchar *tptr = ptr + y11 * step;
if( !fill )
{
if( x11 >= 0 )
ICV_PUT_POINT( tptr, x11 );
if( x12 < size.width )
ICV_PUT_POINT( tptr, x12 );
}
else
ICV_HLINE( tptr, x11, x12, color, pix_size );
}
if( (unsigned)y12 < (unsigned)size.height )
{
uchar *tptr = ptr + y12 * step;
if( !fill )
{
if( x11 >= 0 )
ICV_PUT_POINT( tptr, x11 );
if( x12 < size.width )
ICV_PUT_POINT( tptr, x12 );
}
else
ICV_HLINE( tptr, x11, x12, color, pix_size );
}
if( x21 < size.width && x22 >= 0 )
{
if( fill )
{
x21 = std::max( x21, 0 );
x22 = MIN( x22, size.width - 1 );
}
if( (unsigned)y21 < (unsigned)size.height )
{
uchar *tptr = ptr + y21 * step;
if( !fill )
{
if( x21 >= 0 )
ICV_PUT_POINT( tptr, x21 );
if( x22 < size.width )
ICV_PUT_POINT( tptr, x22 );
}
else
ICV_HLINE( tptr, x21, x22, color, pix_size );
}
if( (unsigned)y22 < (unsigned)size.height )
{
uchar *tptr = ptr + y22 * step;
if( !fill )
{
if( x21 >= 0 )
ICV_PUT_POINT( tptr, x21 );
if( x22 < size.width )
ICV_PUT_POINT( tptr, x22 );
}
else
ICV_HLINE( tptr, x21, x22, color, pix_size );
}
}
}
dy++;
err += plus;
plus += 2;
mask = (err <= 0) - 1;
err -= minus & mask;
dx += mask;
minus -= mask & 2;
}
}