计算机图形学绘制双曲线(可分别在x轴,y轴绘制,代码简单易懂,可运行!!!)

环境介绍:

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;
}

效果图:

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小yuan不搜题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值