OpenGL绘制贝塞尔曲线

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

最终效果图:

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

1. 鼠标问题

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

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

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

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

2. 绘制

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

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

实际绘制的时候就是不断的增加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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用OpenGL绘制Bezier曲线

    本文实例为大家分享了OpenGL绘制Bezier曲线的具体代码,供大家参考,具体内容如下 最近在看Francis S Hill ,Jr 和 Stephen M Kelley合著的<计算机图形学>(OpenGL版)(第三版)书中有绘制三个控制点的Bezier曲线的代码.自己重新敲了一遍代码.发现了其中的一点小错误,修正过来了.并做了一点小小的改动. 源码见下 #include <windows.h> #include <math.h> #include <gl/GL

  • OpenGL画bezier曲线

    Bezier Curve算法是根据参数曲线方程来得到光滑曲线的一种算法,曲线方程的参数由控制点决定. 其本质是由调和函数根据控制点插值而成,其参数方程如下: 其中Pi(i=0,1,-,n)为控制点的向量, Bi,n(t)为伯恩斯坦Bernstein基函数,其多项式表示为: 线性Bezier Curve由两个控制点决定: 二次Bezier Curve由三个控制点决定: 三次Bezier Curve由四个控制点决定: 如下图,t = AE:AB = BF:BC = CG:CD = EH:EF = F

  • OpenGL绘制Bezier曲线的方法

    本文实例为大家分享了OpenGL绘制Bezier曲线的具体代码,供大家参考,具体内容如下 项目要求: – 使用鼠标在屏幕中任意设置控制点,并生成曲线 – 使用鼠标和键盘的交互操作实现对曲线的修改. 项目总体介绍 本项目利用Bezier曲线生成算法生成可由用户自定义的曲线.可实现核心功能如下: 1.用户用鼠标左击屏幕任意处产生记录点. 2.鼠标右击屏幕任意处由先前的任意个数记录点和其先后关系生成Bezier曲线. 另有辅助输入功能: 1.按键盘'C'键可清除所有记录点. 2.按键盘'R'键可清除上

  • OpenGL实现Bezier曲线的方法示例

    Bezier曲线的形状是通过一组多边折线(特征多边形)的各顶点唯一地定义出来的.在这组顶点中: (1)只有第一个顶点和最后一个顶点在曲线上: (2)其余的顶点则用于定义曲线的导数.阶次和形状: (3)第一条边和最后一条边则表示了曲线在两端点处的切线方向. // BezierCurve.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h"</div></div></li><li><div class=

  • OpenGL绘制三次Bezier曲线

    本文实例为大家分享了OpenGL绘制三次Bezier曲线的具体代码,供大家参考,具体内容如下 计算公式: 运行结果: 代码如下: #include<gl/glut.h> #include<math.h> #include<windows.h> #include<vector> #include<algorithm> using namespace std; struct Point { int x, y; Point(){}; Point(int

  • OpenGL实现贝塞尔曲线或曲面

    本文实例为大家分享了OpenGL实现贝塞尔曲线或曲面的具体代码,供大家参考,具体内容如下 理论基础 贝塞尔曲线和曲面:OpenGL只能直接绘制基本图元,对于曲线和曲面我们一般采用一系列线段或多边形来模拟的,这样当线段或多边形增多时必定很耗性能.其实对于这种曲线和曲面,我们可以使用一些控制点,通过求值器程序先计算出坐标等信息,然后直接用这些数据绘制,这样不仅节省内存,还提高了模拟曲线或曲面的精度(本质还是通过线段或多边形绘制的,只是求值器提前算出了曲线或曲面的顶点信息). 求值器使用一般步骤:1.

  • OpenGL绘制贝塞尔曲线

    本文实例为大家分享了OpenGL绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下 最终效果图: 通过3个点形成一条贝塞尔曲线 1. 鼠标问题 在使用鼠标获取坐标的时候,要知道鼠标获取的坐标和屏幕坐标是不同的; openGL使用右手坐标 从左到右,x递增 从下到上,y递增 从远到近,z递增 而鼠标是从左到右增x,同时从上到下也是增y 所以在求 y 的时候,用(屏幕大小-y)来获取 2. 绘制 setpoint 用来绘制点 setline 用来绘制线 setBezier 用来绘制贝塞尔曲线 其中公

  • Android Path绘制贝塞尔曲线实现QQ拖拽泡泡

    这两天学习了使用Path绘制贝塞尔曲线相关,然后自己动手做了一个类似QQ未读消息可拖拽的小气泡,效果图如下: 最终效果图 接下来一步一步的实现整个过程. 基本原理 其实就是使用Path绘制三点的二次方贝塞尔曲线来完成那个妖娆的曲线的.然后根据触摸点不断绘制对应的圆形,根据距离的改变改变原始固定圆形的半径大小.最后就是松手后返回或者爆裂的实现. Path介绍: 顾名思义,就是一个路径的意思,Path里面有很多的方法,本次设计主要用到的相关方法有 moveTo() 移动Path到一个指定的点 qua

  • 基于JavaScript canvas绘制贝塞尔曲线

    简单描述:页面上有四个点,鼠标拖动四个点的位置来改变贝塞尔曲线的形状,双击放置点位 效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> html{overflow: hidden;} * {padding: 0;margin: 0;}

  • Android自定义View绘制贝塞尔曲线的方法

    本文实例为大家分享了Android自定义View绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下 在平面内任选 3 个不共线的点,依次用线段连接. 在第一条线段上任选一个点 D.计算该点到线段起点的距离 AD,与该线段总长 AB 的比例. 根据上一步得到的比例,从第二条线段上找出对应的点 E,使得 AD:AB = BE:BC. 连接这两点 DE. 从新的线段 DE 上再次找出相同比例的点 F,使得 DF:DE = AD:AB = BE:BC. 到这里,我们就确定了贝塞尔曲线上的一个点 F.接下

  • Android自定义View绘制贝塞尔曲线实现流程

    目录 前言 二阶贝塞尔曲线 三阶贝塞尔曲线 前言 对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的API供你调用.由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主要讲解二阶和三阶. 二阶贝塞尔曲线 在Android中,使用quadTo来实现二阶贝塞尔 path.reset() path.moveTo(startX, startY) path.quadTo(currentX, currentY, endX, endY) canvas.drawPath(path, cur

  • C语言实现绘制贝塞尔曲线的函数

    目录 程序截图 简单说明 代码实现 程序截图 简单说明 这个函数就是 void drawBezierCurve(COLORREF color, const unsigned int len, ...) color 是贝塞尔曲线的颜色,len 是画出贝塞尔曲线所需要的点的个数,最少 1 个,不要乱传.之后的参数传的就是画出贝塞尔曲线要的点,数据类型为 Vec2. 这个函数实现的基础是参数方程,用参数方程将一条直线转化为一个参数的方程,如: A * x + B * y + C=0 可以转化为 x =

  • Android自定义View绘制贝塞尔曲线中小红点的方法

    目录 前言 需求 效果图 代码 主要问题 简单画法 使用贝塞尔曲线 前言 上一篇文章用扇形图练习了一下安卓的多点触控,实现了单指旋转.二指放大.三指移动,四指以上同时按下进行复位的功能.今天这篇文章用很多应用常见的小红点,来练习一下贝塞尔曲线的使用. 需求 这里想法来自QQ的拖动小红点取消显示聊天条数功能,不过好像是记忆里的了,现在看了下好像效果变了.总而言之,就是一个小圆点,拖动的时候变成水滴状,超过一定范围后触发消失回调,核心思想如下: 1.一个正方形view,中间是小红点,小红点距离边框有

随机推荐