C语言生成圆弧的Bresenham算法

合集下载

画圆环算法c程序

画圆环算法c程序

画圆环算法c程序全文共四篇示例,供读者参考第一篇示例:画圆环是计算机图形学中常见的基本图形之一,常用于游戏开发、动画制作等领域。

在计算机中,画圆环的算法有多种,其中最常用的是中点画圆算法。

本文将介绍使用C语言实现中点画圆算法的程序,并进行详细分析和讲解。

1. 算法原理中点画圆算法是一种简单而高效的算法,其基本原理是通过逐渐逼近圆形的方法,利用对称性和中点的位置进行迭代计算。

具体步骤如下:(1)给定圆的半径r和圆心坐标(x0, y0),设置初始点P(0, r)作为起点,并计算判别式d=1-r。

(2)在每次迭代中,分别取直线y=x和y=-x两侧的中点,分别计算两种情况下的判别式值,并根据判别式值的大小决定下一个中点的位置。

(3)重复进行上述步骤,直到计算完整个圆的一周。

2. C程序实现下面是使用C语言实现中点画圆算法的程序代码:```c#include <stdio.h>#include <graphics.h>void plot_circle_points(int x0, int y0, int x, int y) { // 绘制圆的八个对称点putpixel(x0 + x, y0 + y, WHITE);putpixel(x0 - x, y0 + y, WHITE);putpixel(x0 + x, y0 - y, WHITE);putpixel(x0 - x, y0 - y, WHITE);putpixel(x0 + y, y0 + x, WHITE);putpixel(x0 - y, y0 + x, WHITE);putpixel(x0 + y, y0 - x, WHITE);putpixel(x0 - y, y0 - x, WHITE);}void midpoint_circle(int x0, int y0, int r) { int x = 0, y = r;int d = 1 - r;plot_circle_points(x0, y0, x, y); while (x < y) {if (d < 0) {d = d + 2 * x + 3;x++;} else {d = d + 2 * (x - y) + 5;x++;y--;}plot_circle_points(x0, y0, x, y);}}delay(5000);closegraph();return 0;}```以上是一个简单的使用C语言实现中点画圆算法的程序代码。

Bresenham画圆算法图形学讲义教学课件

Bresenham画圆算法图形学讲义教学课件

共享顶点的两条边分别位于扫描线的两边,交点算一个。 共享顶点的两条边都位于扫描线的下边,交点算零个。 共享顶点的两条边都位于扫描线的上边,交点算二个。
右、上边界的象素不予填充。 左、下边界的象素予以填充。
算法的实现
求交
所有的边和扫描线求交,效率很低。因为一条扫描线往往只 和少数几条边相交。
如何判断多边形的一条边与扫描线是否相交?(ymin,ymax)
=(x+1)2 + (y-1)2 -R2 - 2(y-1) + 1 = D - 2(y-1) + 1
有了上述 D的递推计算公式,还需计算出D的初值。 ∵ 圆弧的起点为(0,R) ∴ D的初值为:
D = (0+1)2 +(R-1)2-R2 = 2 (1-R)
BresenhamCircle(r, color)
填充。
王选。
TrueType技术
Windows的字库
二次Bezier曲线描述轮廓, 控制点按顺时针方向编号。
使用时先生成轮廓,再在内部填充形成点阵 信息,显示或输出。
例子
H的TrueType字库控制信息 X方向 Y方向
标准字符集
• ASCII
• 共127个。 • 0-31 不可见,控制字符。 • 32-127可见(大小写字母,数字,运算
象素入栈多次,栈要很大的空间。
扫描线填充算法
沿扫描线,在扫描线与多边形的相交区间内填充。
只取一个种子象素。
种子象素入栈;当栈非空时执行以下四步操作:
1 栈顶元素出栈;
2 沿扫描线对出栈象素的左右象素进行填充,直至遇到边 界象素为止。即对每个出栈象素,对包含该象素的整个区 间进行填充。
}/*end of switch*/ }/*end of while*/ }/*end of BresenhamCircle*/

圆中点Bresenham算法

圆中点Bresenham算法

第5章本案例知识要点●掌握八分法中点Bresenham 算法绘制圆的原理 ●设计八分法绘制圆的中点Bresenham 算法 ●编写八分法绘制圆的CirclePoint(x,y) 子函数 ● 编写绘制整圆的Mbcircle()子函数一、案例需求1.案例描述使用中点Bresenham 算法绘制圆心位于屏幕客户区中心的圆。

2.案例效果图案例输入对话框及效果如图3-1所示。

(a )输入对话框 (b )效果图3-1 圆中点Bresenham 算法效果图 3.功能说明(1)要求使用对话框输入圆的半径。

(2)圆的颜色为蓝色。

三、算法设计1. 输入圆的半径R 。

2. 定义圆当前点坐标x ,y 、定义中点偏差判别式d 、定义像素点颜色rgb 。

3. 计算R d -=25.1,x=0,y=R ,rgb =RGB(0,0,255)。

案例三 圆中点Bresenham 算法4.绘制点(x,y)及其在八分圆中的另外7个对称点。

5.判断d的符号。

若d<0,则(x,y)更新为(x+1,y),d更新为d+2x+3;否则(x,y)更新为(x+1,y-1),d更新为d+2(x-y)+5。

6.当x小于等于y,重复步骤⑷和⑸,否则结束。

四、案例实现1.CTestView.h文件// TestView.h : interface of the CTestView class/////////////////////////////////////////////////////////////////////////////#if !defined(AFX_TESTVIEW_H__A75FDCFB_621C_4E38_A154_C344803E6372__INCLUDED_)#define AFX_TESTVIEW_H__A75FDCFB_621C_4E38_A154_C344803E6372__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "InputDlg.h"//包含对话框头文件class CTestView : public CView{protected: // create from serialization onlyCTestView();DECLARE_DYNCREATE(CTestView)// Attributespublic:CTestDoc* GetDocument();// Operationspublic:void GetMaxY();//获得屏幕的最大x值函数void GetMaxX();//获得屏幕的最大y值函数void CirclePoint(double x,double y);//八分法画圆子函数void Mbcircle();//圆中点Bresenham算法// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CTestView)public:virtual void OnDraw(CDC* pDC); // overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected:virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);//}}AFX_VIRTUAL// Implementationpublic:virtual ~CTestView();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:int MaxX,MaxY; //屏幕x和y的最大坐标double R; //圆的半径// Generated message map functionsprotected://{{AFX_MSG(CTestView)afx_msg void OnMENUMbcircle();//}}AFX_MSGDECLARE_MESSAGE_MAP()};#ifndef _DEBUG // debug version in TestView.cppinline CTestDoc* CTestView::GetDocument(){ return (CTestDoc*)m_pDocument; }#endif///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_TESTVIEW_H__A75FDCFB_621C_4E38_A154_C344803E6372__INCLUDED_) 2.CTestView. cpp文件// TestView.cpp : implementation of the CTestView class#include "stdafx.h"#include "Test.h"#include "TestDoc.h"#include "TestView.h"#define ROUND(a) int(a+0.5) //四舍五入#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////// // CTestViewIMPLEMENT_DYNCREATE(CTestView, CView)BEGIN_MESSAGE_MAP(CTestView, CView)//{{AFX_MSG_MAP(CTestView)ON_COMMAND(ID_MENU_Mbcircle, OnMENUMbcircle)//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CTestView construction/destructionCTestView::CTestView(){// TODO: add construction code here}CTestView::~CTestView(){}BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}///////////////////////////////////////////////////////////////////////////// // CTestView drawingvoid CTestView::OnDraw(CDC* pDC){CTestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data here}///////////////////////////////////////////////////////////////////////////// // CTestView printingBOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}///////////////////////////////////////////////////////////////////////////// // CTestView diagnostics#ifdef _DEBUGvoid CTestView::AssertValid() const{CView::AssertValid();}void CTestView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CTestDoc* CTestView::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc)));return (CTestDoc*)m_pDocument;}#endif //_DEBUG///////////////////////////////////////////////////////////////////////////// // CTestView message handlersvoid CTestView::GetMaxX()//得到客户区的最大横坐标{CRect Rect;GetClientRect(&Rect);MaxX=Rect.right;}void CTestView::GetMaxY()//得到客户区最大纵坐标{R=dlg.m_R;}AfxGetMainWnd()->SetWindowText("基本图形扫描转换:Mbcircle");RedrawWindow();GetMaxX();GetMaxY();Mbcircle();}五、案例说明因为设备坐标系的原点在屏幕左上角,所以为了在屏幕中心绘制圆,定义了GetMaxX()和GetMaxY()函数来获得屏幕的MaxX和MaxY,参见案例1的实现部分。

计算机图形学——圆的扫描转换(基本光栅图形算法)

计算机图形学——圆的扫描转换(基本光栅图形算法)

计算机图形学——圆的扫描转换(基本光栅图形算法)与直线的⽣成类似,圆弧⽣成算法的好坏直接影响到绘图的效率。

本篇博客将讨论圆弧⽣成的3个主要算法,正负法、Bresenham 法和圆的多边形迫近法,在介绍算法时,只考虑圆⼼在原点,半径为R的情况。

⼀、正负法1、基本原理假设已选取Pi-1为第i-1个像素,则如果Pi-1在圆内,就要向圆外⽅向⾛⼀步;若已在圆外就要向圆内⾛⼀步。

总之,尽量贴近圆的轮廓线。

2、正负法的具体实现1)圆的表⽰:设圆的圆⼼为(0,0),半径为R,则圆的⽅程为:F(x,y)=x2+y2–R2=0当点(x,y)在圆内时,F(x,y)<0。

当点(x,y)在圆外时,F(x,y)>0。

2)实现步骤第1步:x0=0,y0=R第2步:求得Pi(x i,y i)后找点P i+1的原则为:当P i在圆内时(F(xi,yi)≤0),要向右⾛⼀步得P i+1,这是向圆外⽅向⾛去。

取x i+1= x i+1, y i+1= y i当P i在圆外时(F(xi,yi)>0),要向下⾛⼀步得P i+1,这是向圆内⽅向⾛去,取x i+1= x i, y i+1= y i-1⽤来表⽰圆弧的点均在圆弧附近且 F(xi, yi)时正时负假设已经得到点(x i, y i),则容易算出F(x i, y i),即确定了下⼀个点(x i+1, y i+1),则如何计算F(x i+1, y i+1),以确定下下个点(x i+2, y i+2)?分为两种情况:右⾛⼀步后:x i+1=x i+1,y i+1=y i,此时:F(x i+1, y i+1)=x i+12+y i2-R2=x i2+y i2-R2+2x i+1 = F(x i, y i)+2x i+1下⾛⼀步后:x i+1=x i,y i+1=y i-1, 此时:F(x i+1, y i+1)=x i2+(y i-1)2-R2= F(x i, y i)-2y i+1由此可得:确定了F(xi+1, yi+1)之后,即可决定下⼀个点(xi+2, yi+2),选择道理同上。

画圆形(Bresenham算法)

画圆形(Bresenham算法)

画圆形(Bresenham算法)下⾯先简要介绍常⽤的画圆算法(Bresenham算法),然后再具体阐述笔者对该算法的改进。

⼀个圆,如果画出了圆上的某⼀点,那么可以利⽤对称性计算余下的七段圆弧:Plot(x,y),Plot(y,x),Plot(y,-x),Plot(x,-y),Plot(-x,-y),Plot(-y,-x),Plot(-y,x),Plot(-x,y)。

1、Bresenham 画圆算法。

Bresenham算法的主要思想是:以坐标原点(0,0)为圆⼼的圆可以通过0度到45°的弧计算得到,即x从0增加到半径,然后利⽤对称性计算余下的七段圆弧。

当x从0增加到时,y从R递减到。

设圆的半径为R,则圆的⽅程为:f(x,y)=(x+1)2+y2-R2=0 (1)假设当前列(x=xi列)中最接近圆弧的像素已经取为P(xi,yi),根据第⼆卦限1/8圆的⾛向,下⼀列(x=xi+1列)中最接近圆弧的像素只能在P的正右⽅点H(xi+1,yi)或右下⽅点L(xi+1,yi-1)中选择,如图1所⽰。

Bresenham画圆算法采⽤点T(x,y)到圆⼼的距离平⽅与半径平⽅之差D(T)作为选择标准,即D(T)=(x+1)2+y2-R2 (2)通过⽐较H、L两点各⾃对实圆弧上点的距离⼤⼩,即根据误差⼤⼩来选取,具有最⼩误差的点为绘制点。

根据公式(2)得:对H(xi+1,yi)点有:D(H)=(xi+1)2+yi2-R2;对L(xi+1,yi-1)点有:D(L)=(xi+1)2+(yi-1)2-R2;根据Bresenham画圆算法,则选择的标准是:如果|D(H)|<|D(L)|,那么下⼀点选取H(xi+1,yi);如果|D(H)|>|D(L)|,那么下⼀点选取L(xi+1,yi-1);如果|D(H)|=|D(L)|,那么下⼀点可以取L(xi+1,yi-1),也可以选取H(xi+1,yi),我们约定选取H(xi+1,yi)。

C语言生成圆弧的Bresenham算法

C语言生成圆弧的Bresenham算法

生成圆弧的Bresenham算法1. 算法思想如果我们构造函数F(x,y)=x2+y2-R2,则对于圆上的点有F(x,y)=0,对于圆外的点有F(x,y)>0,对于圆内的点F(x,y)<0 。

与中点画线法一样,构造判别式:d=F(M)=F(x p+1,y p-0.5)=(x p+1)2+(y p-0.5)2-R2若d<0,则应取P1为下一象素,而且再下一象素的判别式为:d=F(x p+2,y p-0.5)=(x p+2)2+(y p-0.5)2-R2=d+2x p+3若d≥0,则应取P2为下一象素,而且下一象素的判别式为d=F(x p+2,y p-1.5)=(x p+2)2+(y p-1.5)2-R2=d+2(x p-y p)+5我们这里讨论的第一个象素是(0,R),判别式d的初始值为:d0=F(1,R-0.5)=1.25-R为了进一步提高算法的效率,将上面的算法中的浮点数改写成整数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。

2. C源程序#include<stdio.h>#include<graphics.h>int Center_x,Center_y,radius,color;/**********显示圆弧的八个对称点**********/void CirclePoints(int Center_x,int Center_y,int x,int y,int color){putpixel(x+Center_x,y+Center_y,color);putpixel(x+Center_x,-y+Center_y,color);putpixel(y+Center_x,x+Center_y,color);putpixel(y+Center_x,-x+Center_y,color);putpixel(-x+Center_x,-y+Center_y,color);putpixel(-x+Center_x,y+Center_y,color);putpixel(-y+Center_x,-x+Center_y,color);putpixel(-y+Center_x,x+Center_y,color);}/**********消除的乘法的中点算法**********/void MidPointCircle(int Center_x,int Center_y,int radius,int color) {int x,y;int d;int DeltaE,DeltaSE;x=0;y=radius;d=5-4*radius;DeltaE=12;DeltaSE=20-8*radius;putpixel(Center_x,Center_y,color);CirclePoints(Center_x,Center_y,x,y,color);while(y>x){if(d<=0){d+=DeltaE;DeltaSE+=8;}else{d+=DeltaSE;DeltaSE+=16;y--;}DeltaE+=8;x++;CirclePoints(Center_x,Center_y,x,y,color);}}/**********主函数**********/void main( ){int graphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,"\\tc");printf("************************************************************\n"); printf("* Middle-Point Algorithm for Circling *\n");printf("* Creator:Zhang Zujin *\n");printf("* *\n");printf("* Input: Center and Radius of Circle and Color Index *\n");printf("* Output: The Circle Related to Input *\n");printf("************************************************************\n\n"); printf("Please Input Center Coordinate(x,y):");scanf("%d%d",&Center_x,&Center_y);printf("Please Input Radius:");scanf("%d",&radius);printf("Input Color Index[0,15]:");scanf("%d",&color);MidPointCircle(Center_x,Center_y,radius,color); getch( );closegraph( );}。

整数bresenham算法c语言

整数bresenham算法c语言

整数bresenham算法c语言整数Bresenham算法是一种用于绘制直线的算法,它可以在不使用浮点数的情况下,从一个点到另一个点绘制一条直线。

在C语言中,整数Bresenham算法可以通过以下代码实现:```c#include <stdio.h>#include <stdlib.h>void drawLine(int x1, int y1, int x2, int y2) {int dx = abs(x2 - x1);int dy = abs(y2 - y1);int sx = (x1 < x2) ? 1 : -1;int sy = (y1 < y2) ? 1 : -1;int err = dx - dy;while (x1 != x2 || y1 != y2) {printf('(%d, %d)', x1, y1);int e2 = err * 2;if (e2 > -dy) {err -= dy;x1 += sx;}if (e2 < dx) {err += dx;y1 += sy;}}printf('(%d, %d)', x2, y2);}int main() {drawLine(0, 0, 10, 5);return 0;}```在这个例子中,我们绘制了从点(0, 0)到点(10, 5)的直线。

首先,我们计算了x和y方向的步长(dx和dy)。

然后,我们确定了x 和y方向的符号(sx和sy),以便正确地移动到下一个点。

接下来,我们计算了误差(err),以便能够在需要时调整步长。

最后,我们通过循环移动到下一个点并在每个点上打印其坐标。

Bresenham画圆算法

Bresenham画圆算法

计算机图形学编程实习一之Bresenham画圆算法
实习报告
学号2014301750057 姓名李帅旗一、实习目的
1.熟悉Visual C++开发环境,能够自己搭建OpenGL图形开发框架,并用C/C+语言实现Bresenham画圆算法。

2.初步了解图元生成算法的实现过程、验证方法,通过实现Bresenham画圆算法,理解图元的参数表示法、光栅扫描、显示输出的概念。

二、实习内容与过程
1. 熟悉Visual C++开发环境;
2.了解Win32控制台开发框架;
3.完成Bresenham画圆算法程序的输入、编译和运行;
4.掌握程序调试的方法。

三、遇到的问题
Bresenman画圆算法和中点画圆算法非常相似,参考着老师提供的中点画圆法的代码,在理解其要义的基础上,再写Bresenman画圆的代码就很简单了。

唯一的疑难点是教材上的Bresenman算法的推导过程有些问题,它省略了重要的步骤,在老师的提示下方才理解明白。

四、实习总结
本次实习还是比较简单的,重点是理解Bresenman画圆算法的过程,在此基础上才可能写出正确的代码。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

生成圆弧的Bresenham算法
1. 算法思想
如果我们构造函数F(x,y)=x2+y2-R2,则对于圆上的点有F(x,y)=0,对于圆外的点有F(x,y)>0,对于圆内的点F(x,y)<0 。

与中点画线法一样,构造判别式:
d=F(M)=F(x p+1,y p-0.5)=(x p+1)2+(y p-0.5)2-R2
若d<0,则应取P1为下一象素,而且再下一象素的判别式为:
d=F(x p+2,y p-0.5)=(x p+2)2+(y p-0.5)2-R2=d+2x p+3
若d≥0,则应取P2为下一象素,而且下一象素的判别式为
d=F(x p+2,y p-1.5)=(x p+2)2+(y p-1.5)2-R2=d+2(x p-y p)+5
我们这里讨论的第一个象素是(0,R),判别式d的初始值为:
d0=F(1,R-0.5)=1.25-R
为了进一步提高算法的效率,将上面的算法中的浮点数改写成整数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。

2. C源程序
#include<stdio.h>
#include<graphics.h>
int Center_x,Center_y,radius,color;
/**********显示圆弧的八个对称点**********/
void CirclePoints(int Center_x,int Center_y,int x,int y,int color)
{
putpixel(x+Center_x,y+Center_y,color);
putpixel(x+Center_x,-y+Center_y,color);
putpixel(y+Center_x,x+Center_y,color);
putpixel(y+Center_x,-x+Center_y,color);
putpixel(-x+Center_x,-y+Center_y,color);
putpixel(-x+Center_x,y+Center_y,color);
putpixel(-y+Center_x,-x+Center_y,color);
putpixel(-y+Center_x,x+Center_y,color);
}
/**********消除的乘法的中点算法**********/
void MidPointCircle(int Center_x,int Center_y,int radius,int color) {
int x,y;
int d;
int DeltaE,DeltaSE;
x=0;
y=radius;
d=5-4*radius;
DeltaE=12;
DeltaSE=20-8*radius;
putpixel(Center_x,Center_y,color);
CirclePoints(Center_x,Center_y,x,y,color);
while(y>x)
{
if(d<=0)
{
d+=DeltaE;
DeltaSE+=8;
}
else
{
d+=DeltaSE;
DeltaSE+=16;
y--;
}
DeltaE+=8;
x++;
CirclePoints(Center_x,Center_y,x,y,color);
}
}
/**********主函数**********/
void main( )
{
int graphdriver=DETECT,graphmode;
initgraph(&graphdriver,&graphmode,"\\tc");
printf("************************************************************\n"); printf("* Middle-Point Algorithm for Circling *\n");
printf("* Creator:Zhang Zujin *\n");
printf("* *\n");
printf("* Input: Center and Radius of Circle and Color Index *\n");
printf("* Output: The Circle Related to Input *\n");
printf("************************************************************\n\n"); printf("Please Input Center Coordinate(x,y):");
scanf("%d%d",&Center_x,&Center_y);
printf("Please Input Radius:");
scanf("%d",&radius);
printf("Input Color Index[0,15]:");
scanf("%d",&color);
MidPointCircle(Center_x,Center_y,radius,color); getch( );
closegraph( );
}。

相关文档
最新文档