BH算法(计算机图形学)

一:实验目的:

模仿第一象限椭圆弧段扫描转换的BH算法,用中点Bresenham算法原理推导抛物线100x=y^2的绘制算法

二:实验原理:

三:实验步骤及源码

实验步骤:

1.输入抛物线公式中的a,以及x的边界值x_broder。

2.计算初始值d=a*x-y*y-2*y-1+0.5*a、x=0、y=0

3.绘制点(x,y)及其第四象限上的另外一个对称点。

4.判断d的符号。若d≤0,则先将d更新为d+a-2*y-3,再将(x,y)更新为(x+1,y+1);否则先将d更新为d-2*y-3,再将(x,y)更新为(x,y-1)。

5.当x<a/4时,重复步骤3和4。否则转到步骤6。

6.用上半部分计算的最后点(x,y)来计算下半部分中d的初值:

d=a-0.5*0.5-y

7.绘制点(x,y)及其在第四象限上的另外一个对称点。

8.判断d的符号。若d≤0,则先将d更新为d+a,再将(x,y)更新为(x+1,y);否则先将d更新为d+3*a-2*y+0.5*0.5-1.5*1.5,再将(x,y)更新为(x+1,y+1)。

9.当x<x_broder时,重复步骤7和8。否则结束。

#define GLUT_DISABLE_ATEXIT_HACK
#include <windows.h>
#include <GL/glut.h>
#include <cmath>
#include<GL/GL.h>
using namespace std;
//适用于F(x,y)=a*x-y*y;
const float grid_size = 0.01f;//

void midpoint_bresenham(float a, int x_border)
{
    float divide = a/4;//分界点
    int x = 0, y = 0;
    float d_pre = 0.5*a - 1;//前半段初始d
    glPointSize(3.0f);//栅格化点的直径  点的属性大小
    glBegin(GL_POINTS);//绘制什么图形的接口  绘制模式:单个顶点集
    while (x <= x_border) 
    {
        glVertex2f(x * grid_size, y * grid_size);//定义二维坐标
        glVertex2f(x * grid_size, -y * grid_size);
        if (x < divide) 
        {   //前半部分
            float incre =-2*y-3;
            
            if (d_pre < 0)
            {
                x++;
                d_pre += incre +a;
            }
            else
            {
                d_pre += incre;
            }
            y++;
        }
        
        else 
        {//后半部分
            
            float d_post = a - 0.5 * 0.5 - y;
            if (d_post >= 0)
            {
                d_post +=  a;
                y++;
            }
            else 
            {
                
                d_post +=  a - 2 * y + 0.5 * 0.5 - 1.5 * 1.5;
            }
            x++;
        }
    }
    glEnd();
}

void reDisplay() 
{
    glClear(GL_COLOR_BUFFER_BIT);//用当前背景色填充窗口   清屏
    glColor3f(1.0f, 1.0f, 0.0f);//设置当前绘图颜色为黄色  
    //初始化绘图场景
    //glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
   // glMatrixMode(GL_PROJECTION);
    midpoint_bresenham(100, 70); //调用上面的函数  上下顺序也不能颠倒,画前要把属性都设置好
    glFlush();//处理所有的OPENGL程序
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);//初始化窗口
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置窗口显示模式  单缓冲
    glutInitWindowSize(400, 300);//设置窗口大小
    glutInitWindowPosition(100, 100);//设置窗口位置
    glutCreateWindow("抛物线");//创建窗口  窗口标题
    glutDisplayFunc(&reDisplay);//设置绘制回调函数  传入绘制的函数
    glutMainLoop();
}

四:实验结果及分析

通过图片我们能看出,这条抛物线是呈锯齿状,符合我们的画图原理,并且可以看出前面部分是y一直增长一,后半部分x一直增长一。

猜你喜欢

转载自blog.csdn.net/weixin_52732185/article/details/129134026