直线生成算法
⑴ dda法生成直线的基本原理是什么为什么说Bersenham画圆的算法效率较高
DDA算法主要是根据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。算法的具体思路如下:
1. 输入直线的起点、终点;
2. 计算x方向的间距:△X和y方向的间距:△Y。
3. 确定单位步进,取MaxSteps = max(△X,△Y); 若△X>=△Y,则X方向的步进为单位步进,X方向步进一个单位,Y方向步进△Y/MaxSteps;否则相反。
4. 设置第一个点的像素值
5. 令循环初始值为1,循环次数为MaxSteps,定义变量x,y,执行以下计算:
a. x增加一个单位步进,y增加一个单位步进
b. 设置位置为(x,y)的像素值
Bresenham算法是DDA算法画线算法的一种改进算法。本质上它也是采取了步进的思想。不过它比DDA算法作了优化,避免了步进时浮点数运算,同时为选取符合直线方程的点提供了一个好思路。首先通过直线的斜率确定了在x方向进行单位步进还是y方向进行单位步进:当斜率k的绝对值|k|<1时,在x方向进行单位步进;当斜率k的绝对值|k|>1时,在y方向进行单位步进。
1. 输入线段的起点和终点。
2. 判断线段的斜率是否存在(即起点和终点的x坐标是否相同),若相同,即斜率不存在,
只需计算y方向的单位步进(△Y+1次),x方向的坐标保持不变即可绘制直线。
3. 计算线段的斜率k,分为下面几种情况处理
a. k等于0,即线段平行于x轴,即程序只需计算x方向的单位步进,y方向的值不变
b. |k|等于1,即线段的x方向的单位步进和y方向的单位步进一样,皆为1。直接循环△X次计算x和y坐标。
4. 根据输入的起点和终点的x、y坐标值的大小决定x方向和y方向的单位步进是1还是-1
6. 画出第一个点。
7. 若|k| <1,设m =0,计算P0,如果Pm>0,下一个要绘制的点为(Xm+单位步进,Ym),
Pm+1 = Pm -2*△Y;
否则要绘制的点为(Xm+单位步进,Ym+单位步进)
Pm+1 = Pm+2*△X-2*△Y;
8. 重复执行第七步△X-1次;
9. 若|k| <1,设m =0,计算Q0,如果Qm>0,下一个要绘制的点为(Xm,Ym+单位步进),
Pm+1 = Pm -2*△X;
否则要绘制的点为(Xm+单位步进,Ym+单位步进)
Pm+1 = Pm+2*△Y-2*△X;
10. 重复执行第9步△Y-1次;
⑵ 有偿有偿。利用直线生成算法(DDA算法或Bresenham算法)绘制直线,分别处理斜率k的两种情况
private static int[] insertSort(int[]arr){
if(arr == null || arr.length < 2){
return arr;
}
for(inti=1;i<arr.length;i++){
for(intj=i;j>0;j--){
if(arr[j]<arr[j-1]){
//TODO:
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}else{
//接下来是无用功
break;
}
}
}
return arr;
}
⑶ 为什么说直线生成算法是二维图形生成技术的基础
这很好理解呀,不管画什么图形都是以线为基础,连填充也是。
能画出线,还画不出几何图形吗。
⑷ 计算机图形学直线生成算法
我连画圆的一块给你吧
需要橡皮筋
椭圆
树什么的可以和我说
我是用
c#写的
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Text;
using
System.Windows.Forms;
namespace
line
{
public
partial
class
Form1
:
Form
{
Graphics
g;
public
Form1()
{
InitializeComponent();
g
=
pictureBox1.CreateGraphics();
}
private
void
button1_Click_1(object
sender,
EventArgs
e)
{
//
g.TranslateTransform(-300,-300);
g.Clear(BackColor);
double
x1,
x2,
y1,
y2;
double
x,
y;
x1
=
System.Convert.ToSingle(textBox1.Text);
y1
=
System.Convert.ToSingle(textBox2.Text);
x2
=
System.Convert.ToSingle(textBox3.Text);
y2
=
System.Convert.ToSingle(textBox4.Text);
x
=
x1;
double
k
=
(y1
-
y2)
/
(x1
-
x2);
Color
color1
=
Color.FromArgb(255,
0,
0);
//定义颜色
Brush
bru1
=
new
SolidBrush(color1);//定义笔
Color
color2
=
Color.FromArgb(0,
255,
0);
//定义颜色
Brush
bru2
=
new
SolidBrush(color2);//定义笔
Pen
pen1
=
new
Pen(bru1,
1);
Pen
pen2
=
new
Pen(bru2,
1);
while
(x
<
x2)
{
//
textBox3.Text
=
System.Convert.ToString(k);
y
=
(double)k
*
(x
-
x1)
+
y1;
double
a;
a=y%1;
float
xx
=
Convert.ToSingle(x);
float
yy
=
Convert.ToSingle(y);
if
(a
>
0.5)
{
g.DrawLine(pen1,
xx,
yy,
xx,yy+1);
}
else
{
g.DrawLine(pen2,
xx,
yy,
xx,
yy+1);
}
x++;
}
//g.DrawLine(p,10,10,100,100);
}
private
void
button2_Click(object
sender,
EventArgs
e)
{
g.TranslateTransform(300,
300);
g.Clear(BackColor);
float
r;//r为圆的圆心
r
=System.Convert.ToSingle(textBox6.Text);
Color
color1
=
Color.FromArgb(255,
0,
0);
//定义颜色
Brush
bru1
=
new
SolidBrush(color1);//定义笔
Color
color2
=
Color.FromArgb(0,
255,
0);
//定义颜色
Brush
bru2
=
new
SolidBrush(color2);//定义笔
Pen
pen1
=
new
Pen(bru1,1);
Pen
pen2
=
new
Pen(bru2,
1);
float
x
=
0;
float
y
=
r;
while
(x
<r+3)
{
y
=
(float)System.Math.Sqrt(r
*
r
-
x
*
x);
float
a;
a
=
y
%
1;
y
=
y
-
a;
if
(a
>
0.5)
{
g.DrawLine(pen1,
x,
y,
x,
y+1);
g.DrawLine(pen1,
-x,
y,
-x,
y
+
1);
g.DrawLine(pen1,
x,
-y,
x,
-y
+
1);
g.DrawLine(pen1,
-x,
-y,
-x,
-y
+
1);
}
else
{
g.DrawLine(pen2,
x,
y,
x,
y+1);
g.DrawLine(pen2,
-x,
y,
-x,
y
+
1);
g.DrawLine(pen2,
x,-
y,
x,-
y
+
1);
g.DrawLine(pen2,
-x,
-y,-
x,
-y
+
1);
}
x++;
}
g.TranslateTransform(-300,
-300);
}
private
void
button3_Click(object
sender,
EventArgs
e)
{
}
private
void
comboBox1_SelectedIndexChanged(object
sender,
EventArgs
e)
{
switch
(comboBox1.Text)
{
case
"画圆":
{
textBox1.Visible
=
false;
textBox2.Visible
=
false;
textBox3.Visible
=
false;
textBox4.Visible
=
false;
textBox5.Visible
=
true;
textBox6.Visible
=
true;
textBox7.Visible
=
false;
textBox8.Visible
=
false;
label1.Visible
=
false;
label2.Visible
=
false;
label3.Visible
=
false;
label4.Visible
=
false;
label5.Visible
=
true;
label6.Visible
=
true;
label7.Visible
=
false;
label8.Visible
=
false;
label9.Visible
=
true;
button1.Visible
=
false;
button2.Visible
=
true;
button3.Visible
=
false;
break;
}
case"画线":
{
textBox1.Visible
=
true;
textBox2.Visible
=
true;
textBox3.Visible
=
true;
textBox4.Visible
=
true;
textBox5.Visible
=
false;
textBox6.Visible
=
false;
textBox7.Visible
=
false;
textBox8.Visible
=
false;
label1.Visible
=
true;
label2.Visible
=
true;
label3.Visible
=
true;
label4.Visible
=
true;
label5.Visible
=
false;
label6.Visible
=
false;
label7.Visible
=
false;
label8.Visible
=
false;
label9.Visible
=
false;
button1.Visible
=
true;
button2.Visible
=
false;
button3.Visible
=
false;
break;
}
case"画椭圆":
{
textBox1.Visible
=
false;
textBox2.Visible
=
false;
textBox3.Visible
=
false;
textBox4.Visible
=
false;
textBox5.Visible
=
false;
textBox6.Visible
=
false;
textBox7.Visible
=
true;
textBox8.Visible
=
true;
label1.Visible
=
false;
label2.Visible
=
false;
label3.Visible
=
false;
label4.Visible
=
false;
label5.Visible
=
false;
label6.Visible
=
false;
label7.Visible
=
true;
label8.Visible
=
true;
label9.Visible
=
false;
button1.Visible
=
false;
button2.Visible
=
false;
button3.Visible
=
true;
break;
}
}
}
}
}
⑸ 计算机图形学中直线的生成算法
/* DDA算法 */
#include "Conio.h"
#include "graphics.h"
#define closegr closegraph
void initgr(void) /* BGI初始化 */
{int gd=DETECT,gm=0; /* 和gd=VGA,gm=VGAHI是同样效果 */
registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */
initgraph(&gd,&gm,"");
}
void DDALine(int x0,int y0,int x1,int y1,int color)
{
int x;
float dx,dy,y,k;
dx=x1-x0 ;
dy=y1-y0;
k=dy/dx;
y=y0;
for(x=x0;x<=x1;x++)
{
putpixel(x,(int)(y+0.5),color);
y=y+k;
}
}
main()
{initgr(); /* BGI初始化 */
DDALine(100,100,200,200,6) ;
getch(); /* 暂停一下,看看前面绘图代码的运行结果 */
closegr(); /* 恢复TEXT屏幕模式 */
}
⑹ 描述Bresenham直线生成算法,并导出其在第一象限内的递推公式。
看看 那本计算机图形学 和清芳的
介绍的很清楚
⑺ 直线和圆的生成算法
直线和圆的像素级生成算法2008-05-31 16:42直线的像素级生成算法:
光栅扫描显示器,其显示屏是由许多被称为像素的点组成。显示器显示的图形或图像就是通过这些像素的亮与不亮(或颜色不同)的各种组合而形成的。
像素级生成方法:如果要生成一条曲线,逐点地选择那些距离曲线最近的像素并将其点亮,这就是像素级(或点)生成算法。
优点:1. 生成的曲线误差小,精度高。一般所显示的像素与实际曲线之间的距离一般不大于二分之一个像素单位。
2. 算法只使用整数运算(至少在主循环内只使用整数运算),因而执行速度快。
bresenham算法:
伪代码:
在(x1,y1)到(x2,y2)之间画一条直线
dx 是x到终点横坐标的距离
dy 是y到终点纵坐标的距离
ix 是dx的绝对值
iy 是dy的绝对值
inc是dx和dy中较大的那个
plot是是否要画一个点的标志位,boolean变量
plotx 是当前点所在的横坐标
ploty 是当前点所在的纵坐标
plotx = x1
ploty = y1
x = 0
y = 0
在 plotx,ploty画一个点——起点
for i = 0 to inc 增量1
x += ix
y += iy
plot = false
if x > inc then
plot = true
x -= inc
if dx > 0 then plotx ++
if dx < 0 then plotx --
if y > inc then
plot = true
y -= inc
if dy > 0 then ploty ++
if dy < 0 then ploty --
if plot == true then 在(plotx,ploty)处画点
c代码:
void draw_line1(pnt s, pnt e)
{
int plotx, ploty; //当前点横纵坐标
plotx = s.x;
ploty = s.y;
int x, y;
x = 0;
y = 0;
int dx, dy; //x,y到终点横、纵坐标的距离
dx = e.x - s.x;
dy = e.y - s.y;
int ix, iy; //dx,dy的绝对值
ix = abs(dx);
iy = abs(dy);
int inc = (dx > dy ? dx : dy);
char plot = FALSE;
for(int i=0; i<inc; ++i)
{
x += ix;
y += iy;
plot = FALSE;
if(x > inc)
{
plot = TRUE;
x -= inc;
if (dx > 0)
plotx++; //当前点加1
if (dx < 0)
plotx--;
}
if(y > inc)
{
plot = TRUE;
y -= inc;
if(dy > 0)
ploty++;
if(dy < 0)
ploty--;
}
if(plot == TRUE)
{
int i = ploty*WIDTH + 3*plotx;
image[i] = 0;
image[i+1] = 0;
image[i+2] = 0;
}
}
LCD_SetFrameBufferAddress(image);
}
最快的像素级圆生成算法:
形式描述:
x = 0; y = R;
d = -R/2;
if R is even then goto EvNoIt;
setpixel(x, y);
LOOP: x = x + 1;
if d<0 then d=d+x;
else {
y=y-1;
d=d+x-y;
if x>y then stop;
}
setpixel(x, y);
EvNoIt: x=x+1;
if d<0 then d=d+x+1;
else {
y=y-1;
d=d+x-y+1;
if x>y then stop;
}
setpixel(x, y);
goto LOOP;
C代码:
void draw_circle(pnt c, int r)
{
int x,y,d;
x = 0;
y = r;
d = -r/2;
while(x<y)
{
if(r%2 == 0)
//第一象限
setpixel(c.x+x, c.y+y);
setpixel(c.y+y, c.x+x);
//第二象限
setpixel(c.x+x, c.y-y);
setpixel(c.y+y, c.x-x);
//
setpixel(c.x-x, c.y+y);
setpixel(c.y-y, c.x+x);
//
setpixel(c.x-x, c.y-y);
setpixel(c.y-y, c.x-x);
if(r%2 == 1)
{
x += 1;
if(d < 0)
d += x + 1;
else
{
y -= 1;
d += x - y + 1;
}
//第一象限
setpixel(c.y+y, c.x+x);
setpixel(c.x+x, c.y+y);
//第二象限
setpixel(c.x+x, c.y-y);
setpixel(c.y+y, c.x-x);
//
setpixel(c.x-x, c.y+y);
setpixel(c.y-y, c.x+x);
//
setpixel(c.x-x, c.y-y);
setpixel(c.y-y, c.x-x);
}
x += 1;
if(d < 0)
d += x;
else
{
y -= 1;
d += x - y;
}
//第一象限
setpixel(c.y+y, c.x+x);
setpixel(c.x+x, c.y+y);
//第二象限
setpixel(c.x+x, c.y-y);
setpixel(c.y+y, c.x-x);
//
setpixel(c.x-x, c.y+y);
setpixel(c.y-y, c.x+x);
//
setpixel(c.x-x, c.y-y);
setpixel(c.y-y, c.x-x);
}
LCD_SetFrameBufferAddress(image);
}
⑻ WIN-TC 直线生成算法问题
WIN-TC下运行通过
http://hi..com/_586/blog/item/de80dfce15f1310092457ee8.html