bresenham算法的FPGA的实现1

接着上一篇的 计算实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点。http://www.cnblogs.com/sepeng/p/4042464.html 这种直接算法的确是被鄙视了

强大的度娘告诉我们还有专用的算法叫bresenham算法。调用我大脑中所有的数学知识残留借用网上资料,费尽了吃奶的力气才把这个算法推导了一遍,高手们不要笑话

            

            

后来觉得这个时候讨论的是 0<k<1.那么把pi换一换就是 -1<k<0.仿真后发现自己又脑残了一次,对算法知之甚少,组合了好几次都没有组合成功,最后不得不把-1<k<0的算法拿出来讨论

        

这次才知道-1<k<0的时候 pi,xi 长啥样子,我的大脑还是猜不出来的,老老实实的推导算法吧。

算法推导出来了,这下好了就开始写FPGA的实现了

  1 /*
  2 date:2014/10/22
  3 version : QuartusII + de1-soc cyclone V
  4 designer : pengxiaoen
  5 funtion :  实现bresenham 算法在象限对直线的计算
  6             |k| <1 任意方向都满足
  7 */
  8
  9 module bresenham (
 10             clock ,
 11             reset ,
 12             xs_in ,        //输入的X 点的起始坐标
 13             ys_in ,        // 输入的Y 点的起始坐标
 14             xe_in ,        //输入X点的终止坐标
 15             ye_in ,        //输入Y 点的终止坐标
 16             in_en ,        //当前输入信号有效标志    1:有效    0:无效
 17
 18             x_ou,         //输出的X 点的坐标
 19             y_ou,         // 输出的Y 点的坐标
 20             fini_flag     //计算完成标志位
 21             );
 22   input         clock ,reset  ;
 23   input         in_en ;
 24   input [9:0]     xs_in  ,xe_in ;
 25   input [8:0]     ys_in  ,ye_in ;
 26
 27   output reg [9:0]    x_ou ;
 28   output reg [8:0]    y_ou ;
 29   output reg        fini_flag ;
 30
 31   wire          [15:0] dx  ;     // X方向上的变化量
 32   wire          [15:0] dy  ;     //Y方向上的变化量
 33   reg  signed     [15:0] pi ;
 34   wire                   x_dir ;
 35   wire                 y_dir ;
 36
 37   wire       [9:0] Xmin ;
 38   wire       [9:0] Xmax ;
 39   wire       [8:0] Ymin ;
 40   wire       [8:0] Ymax ;
 41 //
 42   assign x_dir= (xs_in<xe_in)? 1‘d0  : 1‘d1 ;
 43   assign y_dir= (ys_in<ye_in)? 1‘d0  : 1‘d1 ;
 44   assign Xmin = (xs_in<xe_in)? xs_in : xe_in ;
 45   assign Xmax = (xs_in<xe_in)? xe_in : xs_in ;
 46   assign Ymin = (ys_in<ye_in)? ys_in : ye_in ;
 47   assign Ymax = (ys_in<ye_in)? ye_in : ys_in ;
 48
 49   assign dx = Xmax-Xmin;  //得出X方向上的差值
 50   assign dy = Ymax-Ymin;  //得出Y方向上的差值
 51
 52 reg signed [9:0] x_cnt ;        // X 坐标计数 有符号运算
 53 //**********************************************************
 54 always @ (posedge clock )
 55     if(!reset)
 56             begin
 57                     x_cnt     <= 10‘d0 ;
 58                     fini_flag <= 1‘d0 ;
 59             end
 60     else if(in_en) //数据装载
 61             begin
 62                     x_cnt     <= xs_in ;
 63                     fini_flag <= 1‘d0 ;
 64             end
 65     else if (x_cnt==xe_in) // 运算完毕
 66             begin
 67                     //x_cnt     <= 10‘d0 ;
 68                     fini_flag <= 1‘d1 ;
 69             end
 70     else                 //运算进行中
 71             begin
 72                     x_cnt <= x_cnt + {{9{x_dir}},1‘d1};
 73                     fini_flag <= 1‘d0 ;
 74             end
 75
 76
 77 always @(posedge clock )
 78     if(!reset)
 79             begin
 80                     y_ou    <= 9‘d0 ;
 81                     x_ou    <= 10‘d0 ;
 82             end
 83     else if ((!fini_flag) && (!in_en)) //运算标志正在运算,并且装载数据完成
 84             begin
 85                     if(pi[15])
 86                             begin
 87                                     pi        <= pi+(dy<<1) ;
 88                                     x_ou    <= x_cnt ;
 89                             end
 90                     else
 91                             begin
 92                                     pi        <= pi + (dy<<1) - (dx<<1) ;
 93                                     y_ou    <= y_ou + {{8{y_dir}},1‘d1};
 94                                     x_ou    <= x_cnt ;
 95                             end
 96             end
 97     else
 98             begin
 99                     pi        <=  (dy<<1)-dx ;
100                     y_ou    <=  ys_in ;
101                     x_ou    <=  xs_in ;
102             end
103
104 endmodule 

附上测试代码

 1 `timescale 1ns/1ps
 2
 3
 4 module bresenham_tb ;
 5
 6 reg clock ,reset ;
 7 reg in_en ;
 8 reg [9:0] xs_in ,xe_in ;
 9 reg [8:0] ys_in ,ye_in ;
10
11 wire [9:0] x_ou ;
12 wire [8:0] y_ou ;
13 wire       fini_flag ;
14
15
16 bresenham U1_bresenham(
17             .clock (clock),
18             .reset (reset),
19             .xs_in (xs_in),
20             .ys_in (ys_in),
21             .xe_in (xe_in),
22             .ye_in (ye_in),
23             .in_en (in_en),
24
25             .x_ou (x_ou),
26             .y_ou (y_ou),
27             .fini_flag (fini_flag)
28             );
29
30
31 always  #10 clock = ~clock ;
32
33 initial
34     begin
35             clock = 1‘d0 ; reset =1‘d0 ; in_en = 1‘d0 ;
36             xs_in = 10‘d0 ; xe_in = 10‘d0 ;
37             ys_in = 9‘d0  ; ye_in = 9‘d0 ;
38
39             #40 reset = 1 ;
40                 in_en = 1 ;
41                 xs_in = 100 ; xe_in = 200 ;
42                 ys_in = 100 ; ye_in = 150 ;
43             #80 in_en = 0 ;
44             #3000 ;   //  k = 1/2 验证 正方向
45
46                 in_en = 1 ;
47                 xs_in = 200 ; xe_in =  100;
48                 ys_in = 150 ; ye_in =  100;
49             #80 in_en = 0 ;
50             #3000 ;   //  k = 1/2 验证 反方向
51
52             in_en = 1 ;
53             xs_in = 100 ; xe_in= 200 ;
54             ys_in = 100 ; ye_in= 50 ;
55             #80 in_en = 0 ;   //  k = -1/2 验证 正方向
56             #3000
57
58             in_en = 1 ;
59             xs_in = 200 ; xe_in=  100;
60             ys_in = 50 ;  ye_in=  100 ;
61             #80 in_en = 0 ;   //  k = -1/2 验证 反方向
62             #3000
63
64
65             $stop ;
66
67     end
68
69 endmodule 
时间: 2024-10-08 16:26:09

bresenham算法的FPGA的实现1的相关文章

bresenham算法的FPGA的实现2

在上一篇里http://www.cnblogs.com/sepeng/p/4045593.html <bresenham算法的FPGA的实现1>已经做了一个整体框架的布局,但是那个程序只是支持|k|<1.要想全屏支持,就还需要对这个程序做修改,觉得自己的修改方式很繁琐,期望大家的指点,有高质量的code出现.算法的原理部分在上一篇中已经给出 1 /* 2 date:2014/10/23 3 version : QuartusII + de1-soc cyclone V 4 designe

OpenGL光栅化作业:【bresenham算法】GL_POINTS为基础画线段

首先来看一下题目要求: 2.2 Draw a Line Implement your line rasterization algorithm in OpenGL. You can only use integer arithmetic in your code. Input: 2 2D points, that makes 4 integers, as a start point and an end point Output: A straight line in a window You

Bresenham算法画填充圆及SDL代码实现

画圆是计算机图形操作中一个非常重要的需求.普通的画圆算法需要大量的浮点数参与运算,而众所周知,浮点数的运算速度远低于整形数.而最终屏幕上影射的像素的坐标均为整形,不可能是连续的线,所以浮点数运算其实纯属浪费.下面介绍的Bresenham算法就是根据上文的原理设计.该算法原应用于直线的绘制,但由于圆的八分对称性,该算法也适用与圆(曲线图形)的绘制. 该算法主要是这样的原理:找出一个1/8的圆弧,用快速的增量计算找出下一个点.同时利用圆的八分对称性,找出8个点(包括该点),进行绘制. 这里给出示例的

Bresenham算法

1 /************************************************************* 2 pb-图形学题2 3 Bresenham算法 4 用Bresenham算法画出0<k<1区间的直线,再对称到其它所有k 5 斜率的直线 6 7 *************************************************************/ 8 9 10 #include <GL/glut.h> 11 #include&l

中点Bresenham算法光栅化画直线(个人总结精简版)代码超短!速度极快!

中点Bresenham算法光栅化画直线,每次只位移一个像素,精度高!此源码借助直线 y=x 做了一些转换,简化了主位移的处理,每次移动只需要 加减操作, 不需要乘除!速度极快!! 原理在最后,下面先贴上核心代码~ void Bresenham_LineTo(CDC *pDC, int x1, int y1, int x2, int y2) //中点Bresenham算法光栅化画直线 { float k = 1.0*(y2 - y1) / (x2 - x1); //斜率 int flag = 0;

「图形学」直线扫描——Bresenham算法改进了中点Bresenham算法?

前言 博主目前在学习<计算机图形学基础>这本书,使用的是第二版. 此书第五章开始讲解基本图形生成算法. 在5.1.3 Bresenham算法中,如是写到: 虽然中点Bresenham算法是一种效率非常高的算法,但也还有改进的余地. 而后,开始介绍Bresenham算法. 思考 然而通过学习和理解,博主发现这两种算法的原理完全相同: 每次在最大位移方向上走一步,而另一个方向上走步还是不走步取决于误差项的判别. 于是博主产生了疑问: Bresenham算法真的改进了中点Bresenham算法吗?

Assignment 3 在OpenGL中使用Bresenham算法画圆

一.      任务目标 利用OpenGL,实现Bresenham算法画圆. 二.      任务要求 使用整数来确定点的位置. 标出圆心.(不太明白show的含义,于是我在圆心处画了一个点来表示.) 使用至少16个点表示一个圆. 三.      使用平台 Windows 8.1 Visual Studio 2012 四.      实现简述 与Bresenham直线算法类似,采用的是中点画圆算法. 定义圆的一个函数 可根据f(x, y)符号判断点(x, y)的位置: 于是假设点pi(xi, y

《图形学》实验七:中点Bresenham算法画椭圆

开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画椭圆. 实验结果: 代码: 1 #include <gl/glut.h> 2 3 #define WIDTH 500 4 #define HEIGHT 500 5 #define OFFSET 15 //偏移量,偏移到原点 6 #define A 6 7 #define B 5 8 9 void Init() //其它初始化 10 { 11 glClearColor(1.0f,1.0f,1.0f,1.0f);

《图形学》实验六:中点Bresenham算法画圆

开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画圆. 实验结果: 代码: 1 #include <gl/glut.h> 2 3 #define WIDTH 500 4 #define HEIGHT 500 5 #define OFFSET 15 6 #define R 8 7 8 void Init() //其它初始化 9 { 10 glClearColor(1.0f,1.0f,1.0f,1.0f); //设置背景颜色,完全不透明 11 glColor3f