一、中点画圆法
1、算法分析
利用圆的对称性,只须讨论1/8圆。
开局一张图:smile:
P为当前点亮象素,那么,下一个点亮的象素可能是P1(Xi+1,Yi)或P2(Xi +1,Yi -1)。
构造函数:
F(X,Y)=X2 + Y2 - R2 ;则
F(X,Y)= 0 (X,Y)在圆上;
F(X,Y)< 0 (X,Y)在圆内;
F(X,Y)> 0 (X,Y)在圆外。
设M为P1、P2间的中点,M=(Xi+1,Yi-1/2)
有如下结论:
F(M)< 0 → M在圆内 取P1
F(M)>= 0 → M在圆外 取P2
为此,可采用如下判别式:
di = F(M) = F (xi + 1,yi – 1/2)
=(xi + 1)2 + (yi - 1/2) 2 - R2
若d<0, 则P1 为下一个象素,那么再下一个象素的判别式为:
di+1 = F (xi + 2, yi – 1/2)
= (xi + 2)2 + (yi - 1/2) 2 - R2
= di + 2xi +3
即di 的增量为 2xi +3.
若d>=0, 则P2 为下一个象素,那么再下一个象素的判别式为:
di = F (xi + 2, yi – 3/2)
= (xi + 2)2 + (yi – 3/2) 2 - R2
= di + (2xi + 3)+(-2 yi + 2)
即di的增量为 2 (xi - yi) +5.
di的初值:
d0 = F(1, R-1/2)
= 1 + (R-1/2)2 - R2
= 1/4 - R
2、算法实现C#
①代码结构
:star:②算法部分:star:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DDABresenham
{
public partial class MainForm : Form
{
public void Circle(int x0,int y0,int r,Color color)
{
int x, y, p;//x、y为动态坐标,p为判别式
x = 0;
y = r;//初始化
p = 1 / 4 - r;//2的整数次幂,对计算机来说很“简单”,1/4不足道也
drawponits(x0, y0, x, y, color);
while (x<=y)//当为True,为b系
{
x++;
if (p<0)//真正圆上的点处于中点上方,y无增量
{
p+=2*x + 3;
}
else //真正圆上的点处于中点下方,y-1
{
p+=2*(x - y) + 5;
y--;
}
drawponits(x0, y0, x, y, color);
}
}
public void drawponits(int x0,int y0,int x,int y,Color color)
{
#region 同时画八个象限的点
bitmap.SetPixel(x0 + x, y0 + y, color);//1b
bitmap.SetPixel(x0 + y, y0 + x, color);//1a
bitmap.SetPixel(x0 - y, y0 + x, color);//2a
bitmap.SetPixel(x0 - x, y0 + y, color);//2b
bitmap.SetPixel(x0 - x, y0 - y, color);//3b
bitmap.SetPixel(x0 - y, y0 - x, color);//3a
bitmap.SetPixel(x0 + x, y0 - y, color);//4b
bitmap.SetPixel(x0 + y, y0 - x, color);//4a
#endregion
}
}
}
③实现部分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DDABresenham
{
public partial class MainForm : Form
{
Graphics graphics;
Bitmap bitmap;
public MainForm()
{
InitializeComponent();
graphics = panel1.CreateGraphics();
bitmap = new Bitmap(panel1.Width,panel1.Height);
}
private void buttonDDA_Click(object sender, EventArgs e)
{
DDA(300, 300, 800, 400, Color.Blue);//1a
graphics.DrawImage(bitmap,0,0,panel1.Width,panel1.Height);
}
private void buttonBresenham_Click(object sender, EventArgs e)
{
Bresenham(300, 300, 500, 500, Color.Red);//一象限对角线
Bresenham(300, 300, 100, 500, Color.Blue);//二象限对角线
Bresenham(300, 300, 100, 100, Color.Black);//三象限对角线
Bresenham(300, 300, 500, 100, Color.DarkOrange);//四象限对角线
Bresenham(300, 300, 300, 600, Color.Red);//向下
Bresenham(300, 300, 300, 100, Color.Blue);//2a
Bresenham(300, 300, 100, 300, Color.Black);//3a
Bresenham(300, 300, 500, 300, Color.Yellow);//4a
Bresenham(300, 300, 400, 500, Color.Green);//1b
Bresenham(300, 300, 250, 500, Color.Blue);//2b
Bresenham(300, 300, 250, 100, Color.Black);//3b
Bresenham(300, 300, 350, 100, Color.DarkBlue);//4b
Bresenham(300, 300, 500, 400, Color.Red);//1a
Bresenham(300, 300, 0, 400, Color.Blue);//2a
Bresenham(300, 300, 100, 250, Color.Black);//3a
Bresenham(300, 300, 500, 200, Color.Yellow);//4a
graphics.DrawImage(bitmap, 0, 0, panel1.Width, panel1.Height);
}
private void buttonExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void buttoncircle_Click(object sender, EventArgs e)
{
Circle(300, 300, 200, Color.Red);
graphics.DrawImage(bitmap, 0, 0, panel1.Width, panel1.Height);
}
}
}