画线算法 中点画线 Bresenham DDA

画线算法 中点画线 Bresenham DDA

  • Reshape 在模板那里介绍
#include<GL/glut.h>
#include<math.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//DDA画法(依据斜率)
void DDA(int x1, int y1, int x2, int y2)
{
    int k, i;
    float x, y, dx, dy;
    if (abs(x2 - x1) < abs(y2 - y1)) //斜率的绝对值大于1,每次沿y方向加减一个单位 //以大的为准,应该是精度高呗
        k = abs(y2 - y1);
    else k = abs(x2 - x1);
    dx = float(x2 - x1) / k;
    dy = float(y2 - y1) / k; //〒_〒,这点写错了,float是必须的,要不整除会变成0,纠结我好长时间
    x = float(x1);
    y = float(y1);
    glColor3f(1.0f, 1.0f, 0.0f);
    glPointSize(5);
    for (i = 0; i < k; i++)
    {
        glBegin(GL_POINTS);
        glVertex2i((int)(x + 0.5), (int)(y + 0.5));
        glEnd();
        x += dx;
        y += dy;
    }
}
//中点画线算法(模拟/逐点比较)
void MidPointLine(int x1, int y1, int x2, int y2)
{
    int a, b, dt1, dt2, d, x, y;
    a = y1 - y2;
    b = x2 - x1;
    d = a + a + b;  //为了避免小数,这里取2倍
    dt1 = a + b + a + b;
    dt2 = a + a;
    x = x1;
    y = y1;
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_POINTS);
    glVertex2i(x, y);
    glEnd();
    while (x < x2)
    {
        if (d < 0)
        {
            x++;
            y++;
            d += dt1;
        }
        else
        {
            x++;
            d += dt2;
        }
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
    }
}
//Bresenham画线算法(插值法)
void Bresenham(int x1, int y1, int x2, int y2)
{
    int x, y, dx, dy, d, d1, d2, inc, temp;
    dx = x2 - x1;
    dy = y2 - y1;
    if (dx * dy >= 0)
        inc = 1;
    else
        inc = -1;
    glColor3f(0.0f, 1.0f, 0.0f);
    if (abs(dx) > abs(dy))
    {
        if (dx < 0)  //将2a,3a区域的直线变换到1a,4a区域
        {
            temp = x1;  x1 = x2;    x2 = temp;
            temp = y1;  y1 = y2;    y2 = temp;
            dx = -dx;   dy = -dy;
        }
        d = 2 * dy - dx;
        d1 = 2 * dy;
        d2 = 2 * (dy - dx);
        x = x1;
        y = y1;
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
        while (x < x2)
        {
            x++;
            if (d < 0)
                d += d1;
            else
            {
                y += inc;
                d += d2;
            }
            glBegin(GL_POINTS);
            glVertex2i(x, y);
            glEnd();
        }
    }
    else
    {
        if (dy < 0)  //将3b,4b区域的直线变换到1b,2b区域
        {
            temp = x1;  x1 = x2;    x2 = temp;
            temp = y1;  y1 = y2;    y2 = temp;
            dx = -dx;   dy = -dy;
        }
        d = 2 * dx - dy;
        d1 = 2 * dx;
        d2 = 2 * (dx - dy);
        x = x1;
        y = y1;
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
        while (y < y2)
        {
            y++;
            if (d < 0)
                d += d1;
            else
            {
                x += inc;
                d += d2;
            }
            glBegin(GL_POINTS);
            glVertex2i(x, y);
            glEnd();
        }
    }
}
void myDisplay(void)
{
    glShadeModel(GL_FLAT);
    glClearColor(0, 1, 1, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    DDA(300, 100, 0, 0); //调用DDA函数画线,黄色的
    MidPointLine(0, 0, 400, 200); //红色的
    Bresenham(0, 0, 100, 300); //绿色的
    glFlush();
}
void Reshape(int w, int h)
{
    glViewport(0, 0, w, h); //设置窗口值
    glMatrixMode(GL_PROJECTION); //这三个函数调整绘图坐标,使左下角位置为(0,0),右上角位置为(w,h)
    glLoadIdentity();
    gluOrtho2D(0.0, w, 0.0, h); //设置坐标系值, 这个要放在Reshape中,否则窗口右上角的坐标一直都是初始的w和h
}
int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(300, 100);
    glutInitWindowSize(450, 450);
    glutCreateWindow("DRAWLINE in different ways");
    glutDisplayFunc(myDisplay);
    glutReshapeFunc(Reshape); //窗口初次创建是被调用
    glutMainLoop();
    return 0;
}

图形学实验2作业

  • 实现多边形逼近圆 DDA 中点画线 中点画圆
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "glut32.lib")//Windows VC6.0环用
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#define aa (y0 - y1)
#define bb (x1 - x0)
#define cc (x0 * y1 - x1 * y0) //用不到
using namespace std;
float root2 = sqrt(2);
float PI = acos(-1.0);
void MidpointLine1(int x0, int y0, int x1, int y1, float rc, float gc, float bc)
{   //0<=m<=1
    int d = aa + aa + bb;
    int d1 = aa + aa;
    int d2 = (aa + bb) + (aa + bb);
    int x = x0, y = y0;
    glColor3f(rc, gc, bc);
    for (int i = x0; i <= x1; i++)
    {
        if (d > 0) d += d1;
        else
        {
            y++;
            d += d2;
        }
        x++;
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
    }
}
void MidpointLine2(int x0, int y0, int x1, int y1, float rc, float gc, float bc)
{   //m >1
    int d = aa + 2 * bb;
    int d1 = 2 * aa + 2 * bb;
    int d2 = 2 * bb;
    int x = x0, y = y0;
    glColor3f(rc, gc, bc);
    for (int i = y0; i <= y1; i++)
    {
        if (d > 0)
        {
            x++;
            d += d1;
        }
        else d += d2;
        y++;
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
    }
}
void MidpointLine3(int x0, int y0, int x1, int y1, float rc, float gc, float bc)
{   // -1 <= m <= 0
    int d = 2 * aa  -  bb;
    int d1 = 2 * aa  - 2 * bb;
    int d2 = 2 * aa;
    int x = x0, y = y0;
    glColor3f(rc, gc, bc);
    for (int i = x0; i <= x1; i++)
    {
        if (d > 0)
        {
            y--;
            d += d1;
        }
        else d += d2;
        x++;
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
    }
}
void MidpointLine4(int x0, int y0, int x1, int y1, float rc, float gc, float bc)
{   //m<-1
    int d = aa - 2 * bb;
    int d1 = - 2 * bb;
    int d2 = 2 * aa - 2 * bb;
    int x = x0, y = y0;
    glColor3f(rc, gc, bc);
    for (int i = y0 - 1; i >= y1; i--)
    {
        if (d < 0)
        {
            x++;
            d += d2;
        }
        else d += d1;
        y--;
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
    }
}
void MidpointLine(int x0, int y0, int x1, int y1, float rc, float gc, float bc)
{
    float dx = x1 - x0, dy = y1 - y0;
    float m = 0;
    if (dx != 0) m = dy / dx;
    else return; //横坐标相同的没有画
    if (m >= 0 && m <= 1) {
        if (x0 > x1)
        {
            int t = x1; x1 = x0; x0 = t;
            t = y1; y1 = y0; y0 = t;
        }
        MidpointLine1(x0, y0, x1, y1, rc, gc, bc);
    }
    else if (m > 1) {
        if (x0 > x1)
        {
            int t = x1; x1 = x0; x0 = t;
            t = y1; y1 = y0; y0 = t;
        }
        MidpointLine2(x0, y0, x1, y1, rc, gc, bc);
    }
    else if (m >= -1 && m <= 0) {
        if (x0 > x1)
        {
            int t = x1; x1 = x0; x0 = t;
            t = y1; y1 = y0; y0 = t;
        }
        MidpointLine3(x0, y0, x1, y1, rc, gc, bc);
    }
    else if (m < -1) {
        if (x0 > x1)
        {
            int t = x1; x1 = x0; x0 = t;
            t = y1; y1 = y0; y0 = t;
        }
        MidpointLine4(x0, y0, x1, y1, rc, gc, bc);
    }
    //请写出其他3种情况
}
void MidCircle(int x0, int y0, int rc, float r, float g, float b)
{   //圆弧的中点算法,参考图形学第三章课件上的算法
    glColor3f(r, g, b);
    int h = 5 - 4 * rc;
    int e = 12;
    int se = 20 - 8 * rc;
    int x = 0, y = rc;
    // glLoadIdentity();
    for (int i = -1; i <= (int)(root2 * rc / 2); i++)
    {
        if (h > 0)
        {
            h += se;
            e += 8;
            se += 16;
            y--;
        }
        else
        {
            h += e;
            e += 8;
            se += 8;
        }
        x++;
        glBegin(GL_POINTS);
        glVertex2i(x0 + x, y0 + y);
        glVertex2i(x0 + x, y0 - y);
        glVertex2i(x0 - x, y0 + y);
        glVertex2i(x0 - x, y0 - y);
        glVertex2i(x0 + y, y0 + x);
        glVertex2i(x0 + y, y0 - x);
        glVertex2i(x0 - y, y0 + x);
        glVertex2i(x0 - y, y0 - x);
        glEnd();
    }
}
void PloyAppCircle(int x0, int y0, int R, int r, int g, int b, int theta, int err)
{   //误差控制的多边形逼近圆弧
    glColor3f(r, g, b);
    glBegin(GL_LINE_LOOP);
    double Alp = 2 * acos((R * 1.0 - err) / R);
    // int n = (int)(2 * PI / Alp + 0.5);
    double nn = ceil(2 * PI / Alp);
    int n = (int)(nn);
    double sAlp = sin(Alp);
    double cAlp = cos(Alp);
    double xx = R * cos(Alp / 2);
    double yy = R * sin(Alp / 2);
    glVertex2i((int)xx + x0, (int)yy + y0);
    // cout << n << endl;
    for(int i = 1; i < n; i++)
    {
        double x = cAlp * xx - sAlp * yy;
        double y = sAlp * xx + cAlp * yy;
        glVertex2i((int)x + x0, (int)y + y0);
        // cout << (int)x << " " << (int)y << endl;
        xx = x; yy = y;
    }
    // cout << "hello" << endl;
    glEnd();
}
void DDA(int x1, int y1, int x2, int y2, float r, float g, float b)
{
    int k, i;
    float x, y, dx, dy;
    if (abs(x2 - x1) < abs(y2 - y1)) //斜率的绝对值大于1,每次沿y方向加减一个单位 //以大的为准,应该是精度高呗
        k = abs(y2 - y1);
    else k = abs(x2 - x1);
    dx = float(x2 - x1) / k;
    dy = float(y2 - y1) / k; //这点写错了,float是必须的,要不整除会变成0,纠结我好长时间
    x = float(x1);
    y = float(y1);
    glColor3f(r, g, b);
    // glPointSize(5);
    for (i = 0; i < k; i++)
    {
        glBegin(GL_POINTS);
        glVertex2i((int)(x + 0.5), (int)(y + 0.5));
        glEnd();
        x += dx;
        y += dy;
    }
}
void draw()
{
    glClear(GL_COLOR_BUFFER_BIT);
    float R = 100;
    MidCircle(300, 300, R, 1, 0, 0); //中点画圆
    PloyAppCircle(300, 300, R, 1, 0, 1, 30, 1); //多边形逼近圆
    DDA(40, 30, 120, 60, 1, 0, 0); //DDA画线
    MidpointLine(30, 30, 110, 60, 1, 1, 0); //x0, y0, x1, y1
    MidpointLine(30, 30, 110, 160, 1, 1, 0);
    MidpointLine(30, 30, 110, -30, 1, 0, 0);
    MidpointLine(30, 30, 110, -160, 1, 0, 1);
    MidpointLine(210, 60, 130, 30, 1, 1, 0);
    MidpointLine(210, 160, 130, 30, 1, 1, 0);
    MidpointLine(210, -30, 130, 30, 1, 0, 0);
    MidpointLine(210, -160, 130, 30, 1, 0, 1);
    // 使用OpenGL的划线函数,与中点算法对比
    glColor3f(0, 1, 0);
    glBegin(GL_LINES);
    glVertex2i(220, 160);
    glVertex2i(140, 30);
    glEnd();
    glFlush();//强制之前的绘图函数执行
}
int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(300, 300);
    glutInitWindowSize(500, 500);
    glutCreateWindow("coder352");
    gluOrtho2D(0, 500, 0, 500);
    // glClearColor(0.5, 1.0, 0.0, 1.0);
    glutDisplayFunc(draw);
    // glutReshapeFunc(Reshape);
    glutMainLoop();
    return 0;
}
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值