一:实验目的:
模仿第一象限椭圆弧段扫描转换的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一直增长一。