环境介绍:
visual studio2019+win10
语言:c++
源代码:
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<glut.h>
using namespace std;
void Init(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);//设置背景色
}
void MidHyperbola(double a, double b)
{
double x, y;
double d1, d2;
cout << "请选择焦点在x轴或y轴,分别输入x或y";
char n;
cin >> n;
double m;
//用于判断像素点与曲线的位置关系,d1,d2分别判断0<k<1与k>1时中点坐标与曲线的位置关系
x = 0, y = a;
//从y轴起点(0,a)开始绘制
if (a == b)
//判断渐近线斜率等于1的情况,需要考虑中点转换与偏移修正
{
d1 = b * b * (0.5 + y) * (y + 0.5) - a * a * (x + 1) * (x + 1) - a * a * b * b;
//中点初始值
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
while (a * a * (x + 1) <= b * b * (y + 0.5))
//当曲率小于1时,中点像素坐标横向移动增幅大于纵向移动幅度,x++占主导地位
{
if (d1 <= 0)
{
d1 += 2 * b * b * (y + 1) - a * a * (2 * x + 3);
//中点在曲线外,选取新中点后的d值
x++;
y++;
//更新下一个像素点的位置
}
else
{
d1 -= a * a * (2 * x + 3);
//中点在曲线内,选取新中点后的d值
x++;
//更新下一个像素点的位置
}
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
}
//当曲率大于1时,中点像素坐标纵向移动幅度大于横向移动幅度,y++占主导地位
//此时需要设定新的d来判断中点像素与曲线的位置关系
d2 = b * b * (y + 1) * (y + 1) - a * a * (x + 0.5) * (x + 0.5) - a * a * b * b;
while (y < 1500)//双曲线无限延伸,需要给y设定边界
{
if (d2 <= 0)
{
d2 += b * b * (2 * y + 3);
while (y < 1500)
{
if (d2 <= 0)
{
d2 += b * b * (2 * y + 3);
y++;
}
}
}
else
{
d2 += b * b * (2 * y + 3) - 2 * a * a * (x + 1);
x++;
y++;
}
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
}
}
else if (a < b) //判断渐近线斜率小于1的情况,即x++
{
d1 = b * b * (0.5 + y) * (y + 0.5) - a * a * (x + 1) * (x + 1) - a * a * b * b;//中点初始值
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
for (int i = 0; i <= 600; i++) //双曲线无限延伸,需要设定像素点数量控制范围
{
if (d1 <= 0)
{
d1 += 2 * b * b * (y + 1) - a * a * (2 * x + 3);
//中点在曲线外,选取新中点后的d值
x++;
y++;
//更新下一个像素点的位置
}
else
{
d1 -= a * a * (2 * x + 3);
//中点在曲线内,选取新中点后的d值
x++;
//更新下一个像素点的位置
}
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
}
}
else // (a > b) 判断渐近线斜率大于1的情况,即y++
{
d1 = b * b * (0.5 + y) * (y + 0.5) - a * a * (x + 1) * (x + 1) - a * a * b * b;
//中点初始值
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
for (int i = 0; i <= 1000; i++) //双曲线无限延伸,需要设定像素点数量控制范围
{
if (d1 <= 0)
{
d1 += 2 * b * b * (y + 1) - a * a * (2 * x + 3);
//中点在曲线外,选取新中点后的d值
y++;
//更新下一个像素点的位置
}
else
{
d1 -= a * a * (2 * x + 3);
//中点在曲线内,选取新中点后的d值
if (x <= (sqrt(a * a - b * b)) / (b * b))
//解决图像尖端锐化问题,该x值为k=1时的大小
//当x处于0与该值之间时,x++,图像顶点钝化
{
x++;
}
else
{
x++;
y++;
}
//更新下一个像素点的位置
}
if (n == 'y')
{
glVertex2i(x, y);//绘制对称点如下
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
if (n == 'x')
{
glVertex2i(y, x);//绘制对称点如下
glVertex2i(-y, -x);
glVertex2i(-y, x);
glVertex2i(y, -x);
}
}
}
}
void display()
{
while (1) {
double a, b;
cout << "输入a与b的值" << endl;
cin >> a >> b;
cout << endl;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 1.0f, 1.0f);//设置前景图像rgb颜色
glPointSize(4);
glBegin(GL_POINTS);//画点
MidHyperbola(a, b); //设置半长轴a,b
glEnd();
glFlush();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(150, 150); //窗口位置
glutInitWindowSize(600, 600);
glutCreateWindow("Bresenham_Hyperbola");
glClearColor(0.0, 0.0, 0.0, 0.0);
Init();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(-300, 300, -300, 300);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
效果图:![](https://img-blog.csdnimg.cn/0ca0fa2d414845258e3019879421e593.png)