搜索
bottom↓
回复: 21

有没有好一点的画线算法...任意方向都可以画的.

[复制链接]

出0入0汤圆

发表于 2009-5-18 09:36:47 | 显示全部楼层 |阅读模式
如题...

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入22汤圆

发表于 2009-5-18 09:38:01 | 显示全部楼层
貌似可以尝试用线段凑出来。

出0入0汤圆

发表于 2009-5-18 09:52:25 | 显示全部楼层
bresenham画线算法

出0入0汤圆

发表于 2009-5-18 09:53:52 | 显示全部楼层
看ZLGGUI

出0入0汤圆

发表于 2009-5-18 12:12:30 | 显示全部楼层
void LCD_BufferDrawLine(u8 x1, u8 y1, u8 x2, u8 y2, DrawMode mode)
{
        u8 x, y, t;
        int dx, dy, d, incrE, incrNE;
        if( y1 > y2)
        {
                t = x1, x1 = x2, x2 = t;
                t = y1, y1 = y2, y2 = t;
        }
        dx = x2 - x1;
        dy = y2 - y1;
        x = x1, y = y1;
        if( 0 == dx )
        {
                        LCD_BufferDrawYLine(x1, y1, dy, mode);
        }
        else if( 0 == dy )
        {
                        if( x1 > x2 )
                                LCD_BufferDrawXLine(x2, y2, dx, mode);
                        else
                                LCD_BufferDrawXLine(x1, y1, dx, mode);
        }
        else
        {
                // Bresenham Midpoint Line
                if( abs(dx) > abs(dy) )
                {       
                        if( x2 > x1)
                        {
                                // 0 < k < 1
                                d = 2 * dy - dx;
                                incrE = 2 * dy;
                                incrNE = 2 * (dy - dx);
                                while( x < x2 )
                                {
                                        LCD_BufferDrawPixel(x, y, mode);
                                        x++;
                                        if( d > 0 )
                                        {
                                                y++;
                                                d += incrNE;
                                        }
                                        else
                                                d += incrE;
                                }
                                LCD_BufferDrawPixel(x, y, mode);
                        }
                        else
                        {
                                // -1 < k < 0
                                d = -2 * dy - dx;
                                incrE = -2 * dy;
                                incrNE = -2 * (dy + dx);
                                while( x > x2)
                                {
                                        LCD_BufferDrawPixel(x, y, mode);
                                        x--;
                                        if( d < 0 )
                                        {
                                                y++;
                                                d += incrNE;
                                        }
                                        else
                                                d += incrE;
                                }
                                LCD_BufferDrawPixel(x, y, mode);                       
                        }
                }
                else
                {       
                        if( x2 > x1)
                        {
                                // k > 1
                                d = dy - 2 * dx;
                                incrE = -2 * dx;
                                incrNE = 2 * (dy - dx);
                                while( y < y2 )
                                {
                                        LCD_BufferDrawPixel(x, y, mode);
                                        y++;
                                        if( d < 0 )       
                                        {
                                                x++;
                                                d += incrNE;
                                        }
                                        else
                                                d += incrE;
                                }
                                LCD_BufferDrawPixel(x, y, mode);
                        }
                        else
                        {
                                // k < -1
                                d = -dy - 2 * dx;
                                incrE = -2 * dx;
                                incrNE = -2 * (dy + dx);
                                while( y < y2 )
                                {
                                        LCD_BufferDrawPixel(x, y, mode);
                                        y++;
                                        if( d > 0 )
                                        {
                                                x--;
                                                d += incrNE;
                                        }
                                        else
                                                d += incrE;
                                }
                                LCD_BufferDrawPixel(x, y, mode);
                        }
                }
        }
    dirty = 1;
}

出0入0汤圆

 楼主| 发表于 2009-5-18 12:23:11 | 显示全部楼层
谢谢..试试..

出0入0汤圆

发表于 2009-5-18 14:01:02 | 显示全部楼层
试试这个
/************************************************/
/*画线。任意方向的斜线,直线数学方程 aX+bY=1        */
/************************************************/
void Linexy(uchar x0,uchar y0,uchar xt,uchar yt,uchar s)
{
        register uchar t;
        int xerr=0,yerr=0,delta_x,delta_y,distance;
        int incx,incy,uRow,uCol;

        delta_x = xt-x0;                                //计算坐标增量
        delta_y = yt-y0;
        uRow = x0;
        uCol = y0;
        if(delta_x>0) incx=1;                                //设置单步方向
        else if( delta_x==0 ) incx=0;                        //垂直线
                else {incx=-1;delta_x=-delta_x;}

        if(delta_y>0) incy=1;
        else if( delta_y==0 ) incy=0;                        //水平线
                else {incy=-1;delta_y=-delta_y;}

        if( delta_x > delta_y )        distance=delta_x;        //选取基本增量坐标轴
        else distance=delta_y;

        for( t=0;t <= distance+1; t++ )
                {                                        //画线输出
                point(uRow,uCol,s);                        //画点
                xerr +=        delta_x        ;
                yerr +=        delta_y        ;
               
                if( xerr > distance )
                        {
                        xerr-=distance;
                        uRow+=incx;
                        }
                if( yerr > distance )
                        {
                        yerr-=distance;
                        uCol+=incy;
                        }
                }
}

出0入0汤圆

发表于 2009-5-18 14:36:20 | 显示全部楼层
建议楼主去书店买本《计算机图形学》

比在这里问强多了

PS:4楼的程序其实不怎样……虽然写得很工整……

出0入0汤圆

 楼主| 发表于 2009-5-18 14:39:29 | 显示全部楼层
我其实已经买了一本《计算机图形学》 了..看来是要多看看书.

出0入0汤圆

发表于 2009-5-18 14:42:36 | 显示全部楼层
尝试下

出0入0汤圆

发表于 2009-5-18 14:47:35 | 显示全部楼层
计算机图形学,很好的东西。
看你画线的目的,其实很多应用是不需要斜线的,只是画画横线和竖线。

出0入0汤圆

发表于 2009-5-18 18:28:13 | 显示全部楼层
to watercat
真心请教下,如何改进。要考虑不同的斜率,写得可能是有点笨。

出0入0汤圆

发表于 2009-5-18 18:41:42 | 显示全部楼层
void LCD_DrawLine(unsigned int x1, unsigned  int y1, unsigned  int x2, unsigned  int y2,unsigned  int color)
{
        unsigned  int x, y, t;
        if((x1 == x2) && (y1 == y2))
                LCD_DrawPoint(x1, y1,color);
        else if( (abs(y2 - y1))> (abs(x2 - x1)))
        {
                if(y1 > y2)
                {
                        t = y1;
                        y1 = y2;
                        y2 = t;
                        t = x1;
                        x1 = x2;
                        x2 = t;
                }
                for(y = y1; y <= y2; y ++)
                {
                        x = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
                        LCD_DrawPoint(x, y,color);
                }
        }
        else
        {
                if(x1 > x2)
                {
                        t = y1;
                        y1 = y2;
                        y2 = t;
                        t = x1;
                        x1 = x2;
                        x2 = t;
                }
                for(x = x1; x <= x2; x ++)
                {
                        y = (x - x1) * (y2 - y1) / (x2 - x1) + y1;
                        LCD_DrawPoint(x, y,color);
                }
               
        }
}

以前网上找的

出0入0汤圆

发表于 2009-5-18 19:00:50 | 显示全部楼层
楼上的算法采用y=kx+c来画线,没有bresenham画线算法好。

出0入0汤圆

发表于 2009-5-18 19:48:10 | 显示全部楼层
to 【12楼】 ppa2001

函数有bug啊
        else if( (abs(y2 - y1))> (abs(x2 - x1)))
        {
                if(y1 > y2)
                {
                        t = y1;
                        y1 = y2;
                        y2 = t;
                        t = x1;
                        x1 = x2;
                        x2 = t;
                }
                for(y = y1; y <= y2; y ++)
                {
                        x = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
                        LCD_DrawPoint(x, y,color);
                }
        }

x = (y - y1) * (x2 - x1) / (y2 - y1) + x1; 这里会丢失不少x

出0入0汤圆

发表于 2009-5-18 19:50:35 | 显示全部楼层
我是来学习的

出0入0汤圆

发表于 2009-5-18 20:25:50 | 显示全部楼层
【6楼】 cqfeiyu
效果还行的

出0入0汤圆

发表于 2009-5-18 23:11:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-29 02:59:50 | 显示全部楼层
我是来学习的

出0入0汤圆

发表于 2012-1-29 12:12:37 | 显示全部楼层
看在什么平台上了,Qt里有专门的DrawLine API,还有DrawRect等等
头像被屏蔽

出0入0汤圆

发表于 2012-5-21 09:35:17 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-4-25 23:42:27 | 显示全部楼层
simond 发表于 2009-5-18 19:48
to 【12楼】 ppa2001

函数有bug啊

为什么会丢失x,求解释
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表