BH Algorithm (Computer Graphics)

One: The purpose of the experiment:

Imitate the BH algorithm of the scan conversion of the first quadrant ellipse arc, and use the midpoint Bresenham algorithm to derive the drawing algorithm of the parabola 100x=y^2

Two: Experimental principle:

Three: Experimental steps and source code

Experimental steps:

1. Enter a in the parabola formula, and the boundary value x_broder of x.

2. Calculate the initial value d=a*xy*y-2*y-1+0.5*a, x=0, y=0

3. Draw the point (x,y) and another symmetrical point on the fourth quadrant.

4. Judge the sign of d. If d≤0, first update d to d+a-2*y-3, and then update (x,y) to (x+1,y+1); otherwise, first update d to d-2* y-3, and then update (x,y) to (x,y-1).

5. When x<a/4, repeat steps 3 and 4. Otherwise go to step 6.

6. Use the last point (x, y) calculated in the first half to calculate the initial value of d in the second half:

d=a-0.5*0.5-y

7. Draw the point (x,y) and its other symmetrical point on the fourth quadrant.

8. Judge the sign of d. If d≤0, first update d to d+a, and then update (x,y) to (x+1,y); otherwise, first update d to d+3*a-2*y+0.5* 0.5-1.5*1.5, and then update (x,y) to (x+1,y+1).

9. When x<x_broder, repeat steps 7 and 8. Otherwise end.

#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();
}

Four: Experimental results and analysis

We can see from the picture that this parabola is zigzag, which is in line with our drawing principle, and we can see that the front part is that y keeps increasing by one, and the second half of x keeps increasing by one.

Guess you like

Origin blog.csdn.net/weixin_52732185/article/details/129134026