怎么绘制一个圆形啊

风吹腚腚凉 2012-06-25 04:05:46
有没有用C#写的绘制一个圆的算法啊~
或者资料
谢谢啦就还有100分了。。都给您
...全文
1532 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
风吹腚腚凉 2012-07-02
  • 打赏
  • 举报
回复
[Quote=引用 55 楼 的回复:]
LZ高中数学都没毕业吧。。
[/Quote]
呵呵没上过高中啊,跟别说毕业了,初中数学还凑合
meichen8050753 2012-07-02
  • 打赏
  • 举报
回复
LZ高中数学都没毕业吧。。
baiqukqdp 2012-07-02
  • 打赏
  • 举报
回复
这是的数学问题,不停地COS或SIN就行了,至于多少个点,理论上是无限个,事实上是你觉得已经圆了就行。
用点画圆说白了就是画顶点非常多的多边形,我写过个画多边形的程序。你有兴趣可以下去参考,算法是一样的。

地址:http://download.csdn.net/detail/baiqukqdp/3767116
xingzhiyun 2012-07-02
  • 打赏
  • 举报
回复
知道圆的方程就可以了.
x=r*cos(θ)
y=r*sin(θ)
BillAtChina 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 50 楼 的回复:]

引用 49 楼 的回复:
只需画4分之一个圆的弧线。然后用将图像映象两次;或者将图像旋转两次都能

按照你的说法我感觉画完第一个点就可以旋转角度了。。
1*2*2*2.。。那画4分之一圆的速度岂不更快?
[/Quote]
旋转90度的算法比较简单,旋转45度就难了
rstrego 2012-06-28
  • 打赏
  • 举报
回复
只需画4分之一个圆的弧线。然后用将图像映象两次;或者将图像旋转两次都能
风吹腚腚凉 2012-06-28
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 的回复:]
只需画4分之一个圆的弧线。然后用将图像映象两次;或者将图像旋转两次都能
[/Quote]
按照你的说法我感觉画完第一个点就可以旋转角度了。。
1*2*2*2.。。那画4分之一圆的速度岂不更快?
wuzhiwenk3001 2012-06-26
  • 打赏
  • 举报
回复
用圆规
风吹腚腚凉 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 47 楼 的回复:]
C/C++ code

typedef unsigned char uchar;

#define ICV_HLINE( ptr, xl, xr, color, pix_size ) \
{ \
……
[/Quote]
谢谢你,c++虽然不咋地,但是大体思路我还能猜到
duke3030 2012-06-26
  • 打赏
  • 举报
回复

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;
}
}



从OpenCV中摘出来的,貌似是改进后的Bresenham算法绘制的圆
风吹腚腚凉 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 的回复:]
你要记住,你画的永远是一个近似圆
在电脑上画圆,你的X和Y坐标永远都是整数
那么我么可以遍历X坐标,从0到半径值遍历一遍,算出Y坐标的值,就可以了。

public void drawAt(int x, int y)
{
//在屏幕坐标的(X,Y)画点
......
}

public void drawCircleAt(int x, int y, int r)
{
……
[/Quote]
..好像效率更高
tuchongda 2012-06-26
  • 打赏
  • 举报
回复
你要记住,你画的永远是一个近似圆
在电脑上画圆,你的X和Y坐标永远都是整数
那么我么可以遍历X坐标,从0到半径值遍历一遍,算出Y坐标的值,就可以了。

public void drawAt(int x, int y)
{
//在屏幕坐标的(X,Y)画点
......
}

public void drawCircleAt(int x, int y, int r)
{
for (int i = 0; i <= r; i++)
{
int j = Convert.ToInt16(Math.Round(Math.Sqrt(r * r - i * i)));
if (j < i)
break;
drawAt(x + i, y + j);
drawAt(x + i, y - j);
drawAt(x - i, y + j);
drawAt(x - i, y - j);
drawAt(x + j, y + i);
drawAt(x + j, y - i);
drawAt(x - j, y + i);
drawAt(x - j, y - i);
}
}
风吹腚腚凉 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 的回复:]
如果要求效率的话,楼主查阅计算机图形学,用三角函数什么的画线圆弧效率太低了
[/Quote]
哦好
zhangning111 2012-06-26
  • 打赏
  • 举报
回复
如果要求效率的话,楼主查阅计算机图形学,用三角函数什么的画线圆弧效率太低了
风吹腚腚凉 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 的回复:]
引用 40 楼 的回复:

引用 39 楼 的回复:
引用 38 楼 的回复:

找一个圆心,再找一个半径
可以确定一个以圆心为中心的正方形;
还可以确定一个在这个正方形中最大的菱形,或者说立着的正方形;
便利这个菱形以外、大正方形以内所有点,点到圆心的距离等于半径就画个出来

这个菱形以外、大正方形以内的区域可以分成4块,遍历一块,另外三块就不用遍历可以计算出来了

按照……
[/Quote]
嗯,但是我有点不太理解,这个点临边的点是怎么计算出来的,我是不明白这个。。。
HandanXiaoliang 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 的回复:]

引用 39 楼 的回复:
引用 38 楼 的回复:

找一个圆心,再找一个半径
可以确定一个以圆心为中心的正方形;
还可以确定一个在这个正方形中最大的菱形,或者说立着的正方形;
便利这个菱形以外、大正方形以内所有点,点到圆心的距离等于半径就画个出来

这个菱形以外、大正方形以内的区域可以分成4块,遍历一块,另外三块就不用遍历可以计算出来了

按照你的说法,我感觉只要算出一个……
[/Quote]

比如说遍历左上角的区域,遍历出一个点后,得到这个点的坐标
这时如果把圆心放在一个十字坐标的(0,0)点上,可以得到另外三个点,以x轴对称的,以y轴对称的,以(0,0)坐标对称的三个点
风吹腚腚凉 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 的回复:]
引用 38 楼 的回复:

找一个圆心,再找一个半径
可以确定一个以圆心为中心的正方形;
还可以确定一个在这个正方形中最大的菱形,或者说立着的正方形;
便利这个菱形以外、大正方形以内所有点,点到圆心的距离等于半径就画个出来

这个菱形以外、大正方形以内的区域可以分成4块,遍历一块,另外三块就不用遍历可以计算出来了
[/Quote]
按照你的说法,我感觉只要算出一个就能遍历出所有的了啊,都是边缘到圆心以半径为长度的线,只是角度不同而已,我理解的对不对?
HandanXiaoliang 2012-06-26
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 的回复:]

找一个圆心,再找一个半径
可以确定一个以圆心为中心的正方形;
还可以确定一个在这个正方形中最大的菱形,或者说立着的正方形;
便利这个菱形以外、大正方形以内所有点,点到圆心的距离等于半径就画个出来
[/Quote]
这个菱形以外、大正方形以内的区域可以分成4块,遍历一块,另外三块就不用遍历可以计算出来了
HandanXiaoliang 2012-06-26
  • 打赏
  • 举报
回复
找一个圆心,再找一个半径
可以确定一个以圆心为中心的正方形;
还可以确定一个在这个正方形中最大的菱形,或者说立着的正方形;
便利这个菱形以外、大正方形以内所有点,点到圆心的距离等于半径就画个出来
加载更多回复(34)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧