版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40755094/article/details/84146529
1.中点画圆算法简介:(以第一象限内靠近Y轴的1/8圆为例)
- 由于圆的对称性,只需要考虑的圆上的点。举例:
- 引入构造函数:。 分别表示点在圆外,圆上,圆内。
- 如图3-8所示:.M是P1和P2中点。
- 当F(M)<0时,说明M在圆内,进而得知P1离圆弧更近;否则P2离圆弧更近(相等的情况,P1,P2都可以).
- 构造判别式:d=F(M).(详细内容可参考图片)
2.源码展示:
#include<iostream>
#include<graphics.h>
#include <iomanip>
#include<conio.h>
using namespace std;
#define x0 400
#define y0 300 //定义全局变量x0,y0:坐标轴中心(x0,y0)
void Middle_point_draw_circle(int x1, int y1, int r) {
int d0, x = 0, y = r;
d0 = 1 - r;
cout << "*初始点为: (" << x << "," << y << ")" << endl; //输出初始点坐标(x,y)
cout << "******P(k) (X(k+1),Y(k+1))" << endl;
Sleep(50);
while(x<y) {
if (d0 >= 0) {
cout << noshowpos << fixed << setw(10) << setfill('*') << d0<< " ";
//加上头文件iomanip.输出格式调整:非负数不显示正号,输出宽度为10字符,宽度不足则右边用填充字符填充
d0 = d0 + 2 * (x - y) + 5; //d0一定要先比x,y更新
x = x + 1; //因为d0表达式中的x,y是上一个点
y = y-1;
/*
cout << "(" << (x + x1) << "," << (y + y1) << ")" << "(" << (-x + x1) << "," << (y + y1) << ")";
cout << "(" << (y + x1) << "," << (x + y1) << ")" << "(" << (-y + x1) << "," << (x + y1) << ")";
cout << "(" << (x + x1) << "," << (-y + y1) << ")" << "(" << (-x + x1) << "," << (-y + y1) << ")";
cout << "(" << (y + x1) << "," << (-x + y1) << ")" << "(" << (-y + x1) << "," << (-x + y1) << ")"<<endl;
*/
putpixel(((x + x1) + x0), (y0-(y + y1)),RED); //(x,y)
putpixel(((-x + x1) + x0), (y0 - (y + y1)), RED); //(-x,y)
putpixel(((y + x1) + x0), (y0 - (x + y1)), RED); //(y,x)
putpixel(((-y + x1) + x0), (y0 - (x + y1)), RED); //(-y,x)
putpixel(((x + x1) + x0), (y0 - (-y + y1)), RED); //(x,-y)
putpixel(((-x + x1) + x0), (y0 - (-y + y1)), RED); //(-x,-y)
putpixel(((y + x1) + x0), (y0 - (-x + y1)), RED); //(y,-y)
putpixel(((-y + x1) + x0), (y0 - (-x + y1)), RED); //(-y,-x)
Sleep(150);
}
else {
cout << noshowpos << fixed << setw(10) << setfill('*') << d0 << " ";
d0 = d0 + 2 * x + 3;
x = x + 1;
y = y ;
/*
cout << "(" << (x + x1) << "," << (y + y1) << ")" << "(" << (-x + x1) << "," << (y + y1) << ")" ;
cout << "(" << (y + x1) << "," << (x + y1) << ")" << "(" << (-y + x1) << "," << (x + y1) << ")";
cout << "(" << (x + x1) << "," << (-y + y1) << ")" << "(" << (-x + x1) << "," << (-y + y1) << ")";
cout << "(" << (y + x1) << "," << (-x + y1) << ")" << "(" << (-y + x1) << "," << (-x + y1) << ")"<<endl;
*/
putpixel(((x + x1) + x0), (y0 - (y + y1)), RED); //(x,y)
putpixel(((-x + x1) + x0), (y0 - (y + y1)), RED); //(-x,y)
putpixel(((y + x1) + x0), (y0 - (x + y1)), RED); //(y,x)
putpixel(((-y + x1) + x0), (y0 - (x + y1)), RED); //(-y,x)
putpixel(((x + x1) + x0), (y0 - (-y + y1)), RED); //(x,-y)
putpixel(((-x + x1) + x0), (y0 - (-y + y1)), RED); //(-x,-y)
putpixel(((y + x1) + x0), (y0 - (-x + y1)), RED); //(y,-y)
putpixel(((-y + x1) + x0), (y0 - (-x + y1)), RED); //(-y,-x)
Sleep(150);
}
}
}
int main() {
int x1, y1, r;
cout << "请输入中点画圆算法圆心坐标(x1,y1)和圆的半径r" << endl;
cin >> x1 >> y1 >> r;
initgraph(x0 * 2, y0 * 2); //坐标轴X
line(x0, 0, x0, y0 * 2); //初始化图形窗口大小
line(0, y0, x0 * 2, y0); //坐标轴Y
Middle_point_draw_circle(x1, y1, r); //中点画圆算法
_getch(); //等待一个任意输入结束
closegraph(); //关闭图形窗口
//Middle_point_draw_circle(x1, y1, r);
//_getch();
return 0;
}
3.结果展示:
1)这个是测试输出的结果(代码里注释掉了)
2)画图结果:(由于给定坐标太小,画圆也较小)
4.代码心得:
1) 加入头文件#include <iomanip.h>,实现使用操作运算子来控制输出格式。
2) 计算初始的pk时,p0=1.25-r,为简化运算,改为p0=1-r,不影响结果正确性。
3) 注意pk的正负号影响的是(x(k+1,)y(k+1)),而不是(x(k),y(k)).
4) 循环终止条件时x==y时,用while循环比较好。
扫描二维码关注公众号,回复:
4137343 查看本文章
5)画圆的时候是八个方向同时进行,挺有趣的。
6) 水平有限,代码以及讲述有误之处,欢迎指正。