OpenGL绘制贝塞尔曲线

作者:薛昭君 时间:2022-02-28 11:51:57 

本文实例为大家分享了OpenGL绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下

最终效果图:

通过3个点形成一条贝塞尔曲线

OpenGL绘制贝塞尔曲线

1. 鼠标问题

在使用鼠标获取坐标的时候,要知道鼠标获取的坐标和屏幕坐标是不同的;

openGL使用右手坐标
从左到右,x递增
从下到上,y递增
从远到近,z递增

而鼠标是从左到右增x,同时从上到下也是增y

所以在求 y 的时候,用(屏幕大小-y)来获取

2. 绘制

setpoint 用来绘制点
setline 用来绘制线
setBezier 用来绘制贝塞尔曲线

其中公式的意义可以参考百科:

OpenGL绘制贝塞尔曲线

实际绘制的时候就是不断的增加t,求出下一点的值然后将两个链接起来,然后再将下一个点作为起点,再求出下下一个点

Api解释在代码中


#include "GL\glut.h"
#include <math.h>
#include <Windows.h>

//这是一个点的类,用于存储其中点的坐标
class Point
{
public:
 int x, y;
 void setxy(int _x, int _y) {
   x = _x;
   y = _y;
 }
};

//点的数量
static int POINTSNUM = 0;

//用于存储点的集合,因为绘制的都是4个点的贝塞尔曲线,所以数组大小为4
static Point points[4];

//初始化函数
void init(void)
{
 glClearColor(1.0, 1.0, 1.0, 0); //设定背景为黑色
 glColor3f(0.0,0.0,0.0); //绘图颜色为白色
 glPointSize(2.0); //设定点的大小为2*2像素的
 glMatrixMode(GL_PROJECTION); // 设定合适的矩阵
 glLoadIdentity(); // 是一个无参的无值函数,其功能是用一个4×4的单位矩阵来替换当前矩阵,实际上就是对当前矩阵进行初始化。也就是说,无论以前进行了多少次矩阵变换,在该命令执行后,当前矩阵均恢复成一个单位矩阵,即相当于没有进行任何矩阵变换状态
 gluOrtho2D(0.0,600.0,0.0,480.0); //平行投影,四个参数分别是x,y范围
}

//绘制点
void setPoint(Point p) {
 glBegin(GL_POINTS);
 glVertex2f(p.x, p.y);
 glEnd();
 glFlush();
}

// 绘制直线
void setline(Point p1, Point p2) {
 glBegin(GL_LINES);
 glVertex2f(p1.x,p1.y);
 glVertex2f(p2.x, p2.y);
 glEnd();
 glFlush();
}

// 绘制贝塞尔曲线
Point setBezier(Point p1, Point p2, Point p3, Point p4,double t) {
 Point p;
 double a1 = pow((1 - t), 3);
 double a2 = pow((1 - t), 2) * 3 * t;
 double a3 = 3 * t*t*(1 - t);
 double a4 = t*t*t;
 p.x = a1*p1.x + a2*p2.x + a3*p3.x + a4*p4.x;
 p.y = a1*p1.y + a2*p2.y + a3*p3.y + a4*p4.y;
 return p;
}

//display函数
void display()
{
 glClear(GL_COLOR_BUFFER_BIT);
 glFlush();
}

// 鼠标事件
void mymouseFunction(int button, int state, int x, int y) {
 if (state == GLUT_DOWN) // 如果鼠标按下,不区分左右键的
 {
   points[POINTSNUM].setxy(x,480- y); // 这里求鼠标点的坐标的时候
   // 设置点的颜色,绘制点
   glColor3f(1.0,0.0,0.0);
   setPoint(points[POINTSNUM]);
   // 设置线的颜色,绘制线
   glColor3f(1.0,0.0,0.0);
   if(POINTSNUM > 0) setline(points[POINTSNUM-1],points[POINTSNUM]);

//如果达到了4个绘制贝塞尔曲线,并在之后给计数器清零
   if (POINTSNUM == 3) {
     //绘制贝塞尔曲线  
     glColor3f(0.0, 0.0, 1.0); // 设定贝塞尔曲线的颜色

Point p_current = points[0]; //设为起点
     for (double t = 0.0; t <= 1.0; t += 0.05)
     {
       Point P = setBezier(points[0], points[1], points[2], points[3], t);
       setline(p_current, P);
       p_current = P;
     }

POINTSNUM = 0;
   }
   else {
     POINTSNUM++;
   }
 }
}

int main(int argc, char *argv[])
{
 glutInit(&argc, argv); //固定格式
 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);  //缓存模式
 glutInitWindowSize(600, 480);  //显示框的大小
 glutInitWindowPosition(100, 100); //确定显示框左上角的位置
 glutCreateWindow("第四次作业");

init(); // 初始化
 glutMouseFunc(mymouseFunction); // 添加鼠标事件
 glutDisplayFunc(display); // 执行显示  
 glutMainLoop(); //进人GLUT事件处理循环
 return 0;
}

来源:https://blog.csdn.net/qq_28057541/article/details/51305292

标签:OpenGL,贝塞尔曲线
0
投稿

猜你喜欢

  • Android之来电秀实战示例

    2023-10-05 08:02:27
  • Android自定义荷载进度的两种方法

    2022-08-29 03:21:39
  • Java线程安全和锁Synchronized知识点详解

    2023-01-23 03:59:38
  • MyBatisPlus 大数据量查询慢的问题解决

    2022-06-17 05:56:39
  • C#中使用Cache框架快速实现Cache操作

    2023-01-21 22:35:27
  • Java Servlet简单实例分享(文件上传下载demo)

    2022-03-03 06:35:04
  • 详解Java中List的正确的删除方法

    2021-09-19 13:20:42
  • 详解java爬虫jsoup解析多空格class数据

    2021-12-30 14:47:41
  • Android 之BottomsheetDialogFragment仿抖音评论底部弹出对话框效果(实例代码)

    2023-08-06 01:01:56
  • java实现单机版五子棋

    2022-12-20 20:15:07
  • 解决SpringMVC使用@RequestBody注解报400错误的问题

    2022-02-26 16:06:43
  • 秒懂Kotlin之Java工程师快速掌握Kotlin的技巧

    2023-07-09 21:25:19
  • SpringBoot配置拦 截器实现过程详解

    2023-11-24 17:14:58
  • c# winform取消右上角关闭按钮的实现方法

    2023-05-05 18:56:28
  • 一文详解Spring是怎么读取配置Xml文件的

    2023-07-30 00:27:37
  • Java/Web调用Hadoop进行MapReduce示例代码

    2023-09-01 05:05:50
  • springboot中使用rabbitt的详细方法

    2023-06-17 09:57:43
  • Android编程中Tween动画和Frame动画实例分析

    2023-12-03 06:31:56
  • springboot +rabbitmq+redis实现秒杀示例

    2022-04-21 02:29:28
  • C#中使用UDP通信的示例

    2022-11-19 21:09:07
  • asp之家 软件编程 m.aspxhome.com