• 计算机图形学DDA画线法+中点画线法+Bresenham画线法


    #include <cstdio>
    #include <cstring>
    #include <conio.h>
    #include <graphics.h>
    void line1(){
        line(100, 100, 200, 400);
        line(100, 400, 200, 100);
        line(0, 200, 300, 300);
        line(0, 300, 300, 200);
    }
    
    void lineDDA(int x0, int y0, int x1, int y1, int color){
        int x;
        float dy, dx, y, m;
        dx = x1 - x0;
        dy = y1 - y0;
        m = dy / dx;
        y = y0;
        for (x = x0; x <= x1; x++){
            putpixel(x, (int)(y + 0.5), color);
            y += m;
        }
    }
    
    void lineDDA(){
        lineDDA(100, 100, 200, 400, RED);
        lineDDA(100, 400, 200, 100, RED);
        lineDDA(0, 200, 300, 300, RED);
        lineDDA(0, 300, 300, 200, RED);
    }
    
    void lineMidPoint(int x0, int y0, int x1, int y1, int color){
        int x = x0, y = y0;
        int a = y0 - y1, b = x1 - x0;
        int cx = (b >= 0 ? 1 : (b = -b, -1));
        int cy = (a <= 0 ? 1 : (a = -a, -1));
    
        putpixel(x, y, color);
    
        int d, d1, d2;
        if (-a <= b)     // 斜率绝对值 <= 1  
        {
            d = 2 * a + b;
            d1 = 2 * a;
            d2 = 2 * (a + b);
            while (x != x1)
            {
                if (d < 0)
                    y += cy, d += d2;
                else
                    d += d1;
                x += cx;
                putpixel(x, y, color);
            }
        }
        else                // 斜率绝对值 > 1  
        {
            d = 2 * b + a;
            d1 = 2 * b;
            d2 = 2 * (a + b);
            while (y != y1)
            {
                if (d < 0)
                    d += d1;
                else
                    x += cx, d += d2;
                y += cy;
                putpixel(x, y, color);
            }
        }
    }
    
    void lineMidPoint(){
        lineMidPoint(100, 100, 200, 400, GREEN);
        lineMidPoint(100, 400, 200, 100, GREEN);
        lineMidPoint(0, 200, 300, 300, GREEN);
        lineMidPoint(0, 300, 300, 200, GREEN);
    }
    
    void lineBresenham(int x0, int y0, int x1, int y1, int color)
    {
        int dx = x1 - x0;
        int dy = y1 - y0;
        int ux = dx >0 ? 1 : -1;//x伸展方向  
        int uy = dy >0 ? 1 : -1;//y伸展方向  
        int dx2 = dx << 1;//x偏移量乘2  
        int dy2 = dy << 1;//y偏移量乘2  
        if (abs(dx)>abs(dy))
        {//以x为增量方向计算  
            int e = -dx; //e = -0.5 * 2 * dx,把e 用2 * dx* e替换  
            int x = x0;
            int y = y0;//起点y坐标  
            for (x = x0; x < x1; x += ux)
            {
                putpixel(x, y, color);
                e = e + dy2;//来自 2*e*dx= 2*e*dx + 2dy  (原来是 e = e + k)  
                if (e > 0)//e是整数且大于0时表示要取右上的点(否则是右下的点)   
                {
                    y += uy;
                    e = e - dx2;//2*e*dx = 2*e*dx - 2*dx  (原来是 e = e -1)  
                }
            }
        }
        else
        {//以y为增量方向计算  
            int e = -dy; //e = -0.5 * 2 * dy,把e 用2 * dy* e替换  
            int x = x0;
            int y = y0;
            for (y = y0; y < y1; y += uy)
            {
                putpixel(x, y, color);
                e = e + dx2;//来自 2*e*dy= 2*e*dy + 2dy  (原来是 e = e + k)  
                if (e > 0)//e是整数且大于0时表示要取右上的点(否则是右下的点)   
                {
                    x += ux;
                    e = e - dy2;//2*e*dy = 2*e*dy - 2*dy  (原来是 e = e -1)  
                }
            }
        }
    }
    
    void lineBresenham1(int x0, int y0, int x1, int y1, long color)
    {
        int dx = abs(x1 - x0);
        int dy = abs(y1 - y0);
        int x = x0;
        int y = y0;
        int stepX = 1;
        int stepY = 1;
        if (x0 > x1)  //从右向左画  
            stepX = -1;
        if (y0 > y1)
            stepY = -1;
    
        if (dx > dy)  //沿着最长的那个轴前进  
        {
            int e = dy * 2 - dx;
            for (int i = 0; i <= dx; i++)
            {
                putpixel(x, y, color);
                x += stepX;
                e += dy;
                if (e >= 0)
                {
                    y += stepY;
                    e -= dx;
                }
            }
        }
        else
        {
            int e = 2 * dx - dy;
            for (int i = 0; i <= dy; i++)
            {
                putpixel(x, y, color);
                y += stepY;
                e += dx;
                if (e >= 0)
                {
                    x += stepX;
                    e -= dy;
                }
            }
        }
    }
    
    void lineBresenham(){
        lineBresenham1(100, 100, 200, 400, YELLOW);
        lineBresenham1(100, 400, 200, 100, YELLOW);
        lineBresenham1(0, 200, 300, 300, YELLOW);
        lineBresenham1(0, 300, 300, 200, YELLOW);
    }
    
    
    
    
    void showWord(int code){
        outtextxy(200, 30, "单击右键退出");
        switch (code){
        case 1://原画
            outtextxy(200, 10, "easyX系统画线算法");
            break;
        case 2://DDA算法
            outtextxy(200, 10, "DDA算法");
            break;
        case 3://中点画线算法
            outtextxy(200, 10, "中点画线算法");
            break;
        case 4://Bresenham算法
            outtextxy(200, 10, "Bresenham算法");
            break;
        default:
            line1();
            break;
        }
    }
    
    void drawLine(int code){
        switch (code){
        case 1://原画
            line1();
            break;
        case 2://DDA算法
            lineDDA();
            break;
        case 3://中点画线算法
            lineMidPoint();
            break;
        case 4://Bresenham算法
            lineBresenham();
            break;
        default:
            line1();
            break;
        }
    }
    
    void drawLine(int x0,int y0,int x1,int y1,int code){
        showWord(code);
        switch (code){
        case 1://原画
            line(x0,y0,x1,y1);
            break;
        case 2://DDA算法
            lineDDA(x0, y0, x1, y1,WHITE);
            break;
        case 3://中点画线算法
            lineMidPoint(x0, y0, x1, y1, WHITE);
            break;
        case 4://Bresenham算法
            lineBresenham1(x0, y0, x1, y1, WHITE);
            break;
        default:
            line1();
            break;
        }
    }
    
    
    void showWORDXY(int x, int y, int showX, int showY,int flag){
        char dintX[5] = { 0 };
        char dintY[5] = { 0 };
        _itoa_s(showX, dintX, 10);//把整数showX转成字符串dintX
        _itoa_s(showY, dintY, 10);//把整数showY转成字符串dintY
        char str1[100] = "第一个点的坐标:(";//此时数组没有定义长度   元素的个数应该为strlen +1  因为字符串末尾有 ''结束 
        char str2[100] = "第二个点的坐标:(";
        if (flag == 1){
            // _countof(dintX)能够获取到数组中元素的个数 含‘’
            strcat_s(str1, strlen(str1) + strlen(dintX)+1, dintX);
            strcat_s(str1, strlen(str1) + strlen(",")+1, ",");
            strcat_s(str1, strlen(str1) + strlen(dintY)+1, dintY);
            strcat_s(str1, strlen(str1) + strlen(")")+1, ")");
            outtextxy(x, y, str1);
        }
        else if (flag == 2){
            strcat_s(str2, strlen(str2) + strlen(dintX)+1, dintX);
            strcat_s(str2, strlen(str2) + strlen(",")+1, ",");
            strcat_s(str2, strlen(str2) + strlen(dintY)+1, dintY);
            strcat_s(str2, strlen(str2) + strlen(")")+1, ")");
            outtextxy(x, y, str2);
        }
    }
    
    //调用easyX
    void easyX(int code){
        initgraph(640, 480);       //初始化
        showWord(code);
        MOUSEMSG m; // 定义鼠标消息
        int n=0;//读取两个点
        int exit = false;
        int x0=0, y0=0,x1=0,y1=0;
        while (n<2 && !exit)
        {
            m = GetMouseMsg();
            switch (m.uMsg)
            {
            case WM_RBUTTONDOWN:
                outtextxy(200, 300, "再次点击键退出");
                exit = true;
                break;    // 按鼠标右键退出程序
            }
            while (m.uMsg != WM_LBUTTONDOWN){
                m = GetMouseMsg();
                switch (m.uMsg)
                {
                case WM_RBUTTONDOWN:
                    outtextxy(200, 300, "再次点击键退出");
                    exit = true;
                    break;    // 按鼠标右键退出程序
                }
    
            }
            while (m.uMsg != WM_LBUTTONUP){
                m = GetMouseMsg();
    
                cleardevice();
                showWord(code);
                if (n == 0){
                    showWORDXY(200, 430, x0, y0,1);
                    x0 = m.x;
                    y0 = m.y;
                }
                else{
                    showWORDXY(200, 430, x0, y0, 1);
                    showWORDXY(200, 450, x1, y1, 2);
                    x1 = m.x;
                    y1 = m.y;
                }
            }
            n++;
            if (n == 2){
                //画线
                drawLine(x0, y0, x1, y1, code);
                //重置
                n = 0;
            }
        }
        //_getch();                  //等待用户操作
        closegraph();             //关闭图形
    }
    
    int main(){
        int n = 1;
        printf("请选择画线算法画线:
    ");
        printf("1.easyX系统画线函数.
    ");
        printf("2.DDA画线算法函数.
    ");
        printf("3.中点画线算法函数.
    ");
        printf("4.Bresenham画线算法函数.
    ");
        printf("0.退出.
    ");
        while (n != 0){
            scanf_s("%d", &n);
            if (n == 0){
                exit(0);
            }
            easyX(n);
        }
        return 0;
    }
    效果图:



  • 相关阅读:
    通知
    KVO详解
    KVC详解
    KVC/KVO总结
    结构体Struct
    检测文件(夹)大小
    NSFileHandle&&NSFileManage
    ***NSFileManager
    获取文件扩展名
    MySql数据库_03
  • 原文地址:https://www.cnblogs.com/sufferingStriver/p/8778266.html
Copyright © 2020-2023  润新知