精华内容
下载资源
问答
  • OpenGL画bezier曲线

    2021-01-20 02:03:51
    Bezier Curve算法是根据参数曲线方程来得到光滑曲线的一种算法,曲线方程的参数由控制点决定。...如下图,t = AE:AB = BF:BC = CG:CD = EH:EF = FI:FG = HJ:HI,J即为Bezier曲线上的点   t取0到1的过程就把be
  • openGLbezier曲线生成

    2015-12-12 13:11:33
    用vs2012、c++实现的简单bezier样条曲线生成实例,本人自己编写的代码,分享给大家,含较多注释,便于大家学习参考。
  • 1、利用OpenGL绘制Bezier曲线; 2、使用鼠标在屏幕中任意设置控制点,并生成曲线, 3、使用鼠标和键盘的交互操作实现对曲线的修改;
  • 使用OpenGL绘制Bezier曲线

    热门讨论 2014-04-05 21:24:48
    本程序主要通过调用OpenGL库中的基础函数实现了Bezier曲线的绘制,绘制原理是利用递推公式求解Bernstein多项式,进而求解出Bezier曲线上对应点的坐标值,然后连接这些点绘制出Bezier曲线。点击左键选择顶点,点击...
  • VS下用OpenGL实现的Bezier曲线算法
  • 利用OPENGL技术实现图形Bezier曲线,这对于学习OPENGL技术优点帮助
  • 主要为大家详细介绍了OpenGL绘制三次Bezier曲线,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要为大家详细介绍了OpenGL绘制Bezier曲线的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • opengl画bezier曲线

    2007-11-11 23:12:42
    实现bezier曲线的绘制,支持鼠标操作
  • openGL画离散bezier曲线

    2012-11-25 14:22:37
    openGL画离散bezier曲线,很简单的一个计算机图形学例子
  • OpenGL实现Bezier曲线

    千次阅读 2017-05-02 16:32:12
    Bezier曲线的形状是通过一组多边折线(特征多边形)的各顶点唯一地定义出来的。在这组顶点中: (1)只有第一个顶点和最后一个顶点在曲线上; (2)其余的顶点则用于定义曲线的导数、阶次和形状; (3)第一条边和最后一条...

    Bezier曲线的形状是通过一组多边折线(特征多边形)的各顶点唯一地定义出来的。在这组顶点中:

    (1)只有第一个顶点和最后一个顶点在曲线上;

    (2)其余的顶点则用于定义曲线的导数、阶次和形状;

    (3)第一条边和最后一条边则表示了曲线在两端点处的切线方向。


    
    
    // BezierCurve.cpp : 定义控制台应用程序的入口点。
    //
    


    展开全文
  • 今天小编就为大家分享一篇关于OpenGL实现Bezier曲线的方法示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • 基于c++mfc下利用opengl编写的Bezier曲线的绘制的程序,单击鼠标左键绘制曲线
  • 计算机图形学作业( 七):利用 OpenGL 绘制 Bezier 贝塞尔曲线Bezier 曲线原理OpenGL 实现思路捕获鼠标点击时的坐标根据顶点出连续的线段根据顶点Bezier 贝塞尔曲线效果代码 Bezier 曲线原理 Bezier 曲线的...

    Bezier 曲线原理

    Bezier 曲线的原理我参考了这篇博客:https://www.cnblogs.com/hyb1/p/3875468.html

    Bezier 曲线是应用于二维图形的曲线。曲线由顶点和控制点组成,通过改变控制点坐标可以改变曲线的形状。

    一次 Bezier 曲线公式:

    一次 Bezier 曲线是由 P0 至 P1 的连续点,描述的一条线段。

    二次 Bezier 曲线公式:

    二次 Bezier 曲线是 P0 至 P1 的连续点 Q0 和 P1 至 P2 的连续点 Q1 组成的线段上的连续点 B(t),描述一条抛物线。

    三次 Bezier 曲线公式:

    由此可得 Bezier 曲线的一般方程为:

    OpenGL 实现思路

    在 OpenGL 窗口中,我们希望能通过左键点击窗口添加 Bezier 曲线的控制点,右键点击则对当前添加的最后一个控制点进行消除。然后根据鼠标绘制的控制点实时更新 Bezier 曲线。

    捕获鼠标点击时的坐标

    我们需要用一个回调函数,该函数是在鼠标移动时不断获取鼠标在窗口的坐标。

    首先我们要声明全局的鼠标位置变量,代码如下:

    float mouseXPos, mouseYPos;
    

    然后在鼠标事件中不断更新全局位置变量的值。代码如下

    void cursor_position_callback(GLFWwindow* window, double x, double y) { 
    	mouseXPos = float((x - WINDOW_WIDTH / 2) / WINDOW_WIDTH) * 2;
    	mouseYPos = float(0 - (y - WINDOW_HEIGHT / 2) / WINDOW_HEIGHT) * 2;
    	return; 
    }
    

    根据顶点画出连续的线段

    前面我们获取的鼠标的当前位置,那么当鼠标点击左键时,我们要捕获该点击事件,将顶点数据添加到 lineVertices 并通过绑定 VAO 画出线段。

    先声明全局的顶点数据变量:

    // 声明全局顶点变量, 点个数为 vertexLen / 3
    int lineVertexLen = 0;
    float lineVertices[MAX_VERTEX_LEN] = {
    	//位置
    	//-0.5f, 0.5f, 0.0f
    };
    

    然后再鼠标点击事件中操作:

    void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { 
    	if (action == GLFW_PRESS) switch (button) { 
    		case GLFW_MOUSE_BUTTON_LEFT:			
    			// 每隔两个点画一条直线
    			// 鼠标点击的点
    			lineVertices[lineVertexLen] = mouseXPos;
    			lineVertexLen++;
    			lineVertices[lineVertexLen] = mouseYPos;
    			lineVertexLen++;
    			lineVertices[lineVertexLen] = 0.0f;
    			lineVertexLen++;
    			// 添加索引,前一个点也新的点一起确定新线段
    			if (lineIndicesLen >= 2) {
    				lineIndices[lineIndicesLen] = lineIndices[lineIndicesLen - 1];
    				lineIndicesLen++;
    				lineIndices[lineIndicesLen] = lineIndices[lineIndicesLen - 1] + 1;
    				lineIndicesLen++;
    			}
    			else {
    				lineIndices[lineIndicesLen] = lineIndicesLen;
    				lineIndicesLen++;
    			}
    			break;
    		default:				
    			break;
    	}	
    	return; 
    }
    

    之后便是通过 VAO、VBO 和 GL_LINES 等画出线段。

    根据顶点画出 Bezier 贝塞尔曲线

    根据之前的 Bezier 曲线一般式,我们能很容易地根据顶点计算出 Bezier 曲线的点数据。只要新声明一个函数,传入顶点的数据和长度,就能计算出各个位置上的 Bezier 曲线的点数据,如下:

    int getBezierVertex(float lineVertices[MAX_VERTEX_LEN], int lineVertexLen, float bezierVertices[MAX_BEZIER_VERTEX_LEN]) {
    	int bezierVertexLen = 0;
    	if (lineVertexLen == 0) return bezierVertexLen;
    	else if (lineVertexLen == 3) {
    		bezierVertices[bezierVertexLen] = lineVertices[0];
    		bezierVertexLen++;
    		bezierVertices[bezierVertexLen] = lineVertices[1];
    		bezierVertexLen++;
    		bezierVertices[bezierVertexLen] = lineVertices[2];
    		bezierVertexLen++;
    	}
    	else {
    		for (float t = 0.000f; t <= 1.000f; t = t + 0.001f) {
    			double new_xPos = 0, new_yPos = 0;
    			for (int index = 0; index < lineVertexLen / 3; index++) {
    				// x坐标
    				new_xPos += lineVertices[index * 3] * pow(t, index) * pow((1 - t), (lineVertexLen / 3 - 1 - index));
    				// y坐标
    				new_yPos += lineVertices[index * 3 + 1] * pow(t, index) * pow((1 - t), (lineVertexLen / 3 - 1 - index));
    			}
    			bezierVertices[bezierVertexLen] = new_xPos;
    			bezierVertexLen++;
    			bezierVertices[bezierVertexLen] = new_yPos;
    			bezierVertexLen++;
    			bezierVertices[bezierVertexLen] = 0.0f;
    			bezierVertexLen++;
    		}
    	}
    	return bezierVertexLen;
    }
    

    之后便可以通过 VAO、VBO 和 GL_POINTS 等画出 Bezier 曲线。

    效果

    代码

    #include <iostream>
    #include <cmath>
    #include <glad/glad.h>
    #include <GLFW/glfw3.h>
    
    #include "imgui.h"
    #include "imgui_impl_glfw.h"
    #include "imgui_impl_opengl3.h"
    
    #include <glm.hpp>
    #include <gtc/matrix_transform.hpp>
    #include <gtc/type_ptr.hpp>
    
    // 加载纹理的库
    #include "stb_image.h"
    
    //使用了官方的shader库文件,可以更方便地操作shader
    //注意,使用官方库操作shadder时,自己写的顶点和片段着色器代码必须另外写成文件
    //然后把文件路径传入shader.h提供的构造函数
    #include "shader.h"  
    
    using namespace std;
    
    const int WINDOW_WIDTH = 1000;
    const int WINDOW_HEIGHT = 800;
    const int MAX_VERTEX_LEN = 300;
    const int MAX_INDICES_LEN = 600;
    const int MAX_BEZIER_VERTEX_LEN = 3000;
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
    void cursor_position_callback(GLFWwindow* window, double x, double y);
    int getBezierVertex(float lineVertices[MAX_VERTEX_LEN],int lineVertexLen, float bezierVertices[MAX_BEZIER_VERTEX_LEN]);
    
    // 声明鼠标全局位置变量
    float mouseXPos, mouseYPos;
    
    // 声明全局顶点变量, 点个数为 vertexLen / 3
    int lineVertexLen = 0;
    float lineVertices[MAX_VERTEX_LEN] = {
    	//位置
    	//-0.5f, 0.5f, 0.0f,
    	//0.5f, 0.5f, 0.0f,
    	//0.5f, -0.5f, 0.0f
    };
    int lineIndicesLen = 0;
    unsigned int lineIndices[MAX_INDICES_LEN] = { // 注意索引从0开始! 
    	//0, 1, // 第一个线段
    	//1, 2
    };
    
    
    int main() {
    	//初始化opengl窗口和配置
    	glfwInit();
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    	
    	GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "LearnOpenGL", NULL, NULL);
    	if (window == NULL) {
    		std::cout << "Failed to create GLFW window" << std::endl;
    		glfwTerminate();
    		return -1;
    	}
    	glfwMakeContextCurrent(window);
    
    	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    	glfwSetMouseButtonCallback(window, mouse_button_callback);
    	glfwSetCursorPosCallback(window, cursor_position_callback);
    
    	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    		std::cout << "Failed to initialize GLAD" << std::endl;
    		return -1;
    	}
    
    	// 深度测试
    	glEnable(GL_DEPTH_TEST);
    
    	//创建并绑定ImGui
    	const char* glsl_version = "#version 130";
    	IMGUI_CHECKVERSION();
    	ImGui::CreateContext();
    	ImGuiIO& io = ImGui::GetIO(); (void)io;
    	ImGui::StyleColorsDark();
    	ImGui_ImplGlfw_InitForOpenGL(window, true);
    	ImGui_ImplOpenGL3_Init(glsl_version);
    
    	Shader lineShader("vertexShader.vs", "lineFragmentShader.fs");
    	Shader bezierShader("vertexShader.vs", "bezierFragmentShader.fs");
    
    	bool show_window = true;
    
    	while (!glfwWindowShouldClose(window)) {
    		processInput(window);
    
    		//清除屏幕
    		glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    		unsigned int VAO;
    		unsigned int VBO;
    		unsigned int EBO;
    
    		//必须先绑定VA0
    		glGenVertexArrays(1, &VAO);
    		glBindVertexArray(VAO);
    
    		//再绑定VBO
    		glGenBuffers(1, &VBO);
    		glBindBuffer(GL_ARRAY_BUFFER, VBO);
    		glBufferData(GL_ARRAY_BUFFER, sizeof(lineVertices), lineVertices, GL_STATIC_DRAW);
    
    		//使用EBO画多个线段,组合成其它图形
    		glGenBuffers(1, &EBO);
    		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lineIndices), lineIndices, GL_STATIC_DRAW);
    
    		//再设置属性
    		//位置属性
    		//属性位置值为0的顶点属性
    		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    		glEnableVertexAttribArray(0);
    
    		glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    		glEnableVertexAttribArray(1);
    
    		// 使用着色器程序
    		lineShader.use();
    
    		//画线段,
    		glBindVertexArray(VAO);
    		// 因为通过 indices 确定线段,每两点确定一线段,所以画多少线段,就填入线段数乘以2
    		if (lineIndicesLen >= 2) {
    			glDrawElements(GL_LINES, lineIndicesLen, GL_UNSIGNED_INT, 0);
    		}
    
    
    		// 以下是 bezier 点数据
    		// 声明 bezier 顶点变量 
    		int bezierVertexLen = 0;
    		float bezierVertices[MAX_BEZIER_VERTEX_LEN] = {
    			//-0.5f, 0.5f, 0.0f,
    		};
    
    		bezierVertexLen = getBezierVertex(lineVertices, lineVertexLen, bezierVertices);
    
    		unsigned int bezierVAO;
    		unsigned int bezierVBO;
    
    		//必须先绑定VA0
    		glGenVertexArrays(1, &bezierVAO);
    		glBindVertexArray(bezierVAO);
    
    		//再绑定VBO
    		glGenBuffers(1, &bezierVBO);
    		glBindBuffer(GL_ARRAY_BUFFER, bezierVBO);
    		glBufferData(GL_ARRAY_BUFFER, sizeof(bezierVertices), bezierVertices, GL_STATIC_DRAW);
    
    		//再设置属性
    		//位置属性
    		//属性位置值为0的顶点属性
    		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    		glEnableVertexAttribArray(0);
    
    		glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    		glEnableVertexAttribArray(1);
    
    		// 使用着色器程序
    		bezierShader.use();
    
    		//画线段,
    		glBindVertexArray(bezierVAO);
    		glDrawArrays(GL_POINTS, 0, bezierVertexLen / 3);
    
    		//创建imgui
    		ImGui_ImplOpenGL3_NewFrame();
    		ImGui_ImplGlfw_NewFrame();
    		ImGui::NewFrame();
    
    		ImGui::Begin("Edit cube", &show_window, ImGuiWindowFlags_MenuBar);
    
    
    		ImGui::End();
    
    		ImGui::Render();
    		int display_w, display_h;
    		glfwMakeContextCurrent(window);
    		glfwGetFramebufferSize(window, &display_w, &display_h);
    		glViewport(0, 0, display_w, display_h);
    		ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    
    		glfwPollEvents();
    		glfwSwapBuffers(window);
    	}
    
    	glfwTerminate();
    
    	return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    	glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow* window) {
    	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
    		glfwSetWindowShouldClose(window, true);
    	}
    }
    
    void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { 
    	if (action == GLFW_PRESS) switch (button) { 
    		case GLFW_MOUSE_BUTTON_LEFT:			
    			// 每隔两个点画一条直线
    			// 鼠标点击的点
    			lineVertices[lineVertexLen] = mouseXPos;
    			lineVertexLen++;
    			lineVertices[lineVertexLen] = mouseYPos;
    			lineVertexLen++;
    			lineVertices[lineVertexLen] = 0.0f;
    			lineVertexLen++;
    			// 添加索引,前一个点也新的点一起确定新线段
    			if (lineIndicesLen >= 2) {
    				lineIndices[lineIndicesLen] = lineIndices[lineIndicesLen - 1];
    				lineIndicesLen++;
    				lineIndices[lineIndicesLen] = lineIndices[lineIndicesLen - 1] + 1;
    				lineIndicesLen++;
    			}
    			else {
    				lineIndices[lineIndicesLen] = lineIndicesLen;
    				lineIndicesLen++;
    			}
    			break;
    		case GLFW_MOUSE_BUTTON_RIGHT:
    			if (lineVertexLen >= 3) {
    				lineVertexLen = lineVertexLen - 3;
    			}
    
    			if (lineIndicesLen >= 4) {
    				lineIndicesLen = lineIndicesLen - 2;
    			}
    			else {
    				lineIndicesLen = lineIndicesLen - 1;
    			}
    
    			break;
    		default:				
    			break;
    	}	
    	return; 
    }
    
    void cursor_position_callback(GLFWwindow* window, double x, double y) { 
    	mouseXPos = float((x - WINDOW_WIDTH / 2) / WINDOW_WIDTH) * 2;
    	mouseYPos = float(0 - (y - WINDOW_HEIGHT / 2) / WINDOW_HEIGHT) * 2;
    	return; 
    }
    
    int getBezierVertex(float lineVertices[MAX_VERTEX_LEN], int lineVertexLen, float bezierVertices[MAX_BEZIER_VERTEX_LEN]) {
    	int bezierVertexLen = 0;
    	if (lineVertexLen == 0) return bezierVertexLen;
    	else if (lineVertexLen == 3) {
    		bezierVertices[bezierVertexLen] = lineVertices[0];
    		bezierVertexLen++;
    		bezierVertices[bezierVertexLen] = lineVertices[1];
    		bezierVertexLen++;
    		bezierVertices[bezierVertexLen] = lineVertices[2];
    		bezierVertexLen++;
    	}
    	else {
    		for (float t = 0.000f; t <= 1.000f; t = t + 0.001f) {
    			double new_xPos = 0, new_yPos = 0;
    			for (int index = 0; index < lineVertexLen / 3; index++) {
    				// x坐标
    				new_xPos += lineVertices[index * 3] * pow(t, index) * pow((1 - t), (lineVertexLen / 3 - 1 - index));
    				// y坐标
    				new_yPos += lineVertices[index * 3 + 1] * pow(t, index) * pow((1 - t), (lineVertexLen / 3 - 1 - index));
    			}
    			bezierVertices[bezierVertexLen] = new_xPos;
    			bezierVertexLen++;
    			bezierVertices[bezierVertexLen] = new_yPos;
    			bezierVertexLen++;
    			bezierVertices[bezierVertexLen] = 0.0f;
    			bezierVertexLen++;
    		}
    	}
    	return bezierVertexLen;
    }
    
    
    展开全文
  • opengl的反馈模式的物体沿Bezier曲线运动
  • OpenGL绘制Bezier曲线

    万次阅读 2015-01-17 18:57:34
    本项目利用Bezier曲线生成算法生成可由用户自定义的曲线。可实现核心功能如下: 用户用鼠标左击屏幕任意处产生记录点。 鼠标右击屏幕任意处由先前的任意个数记录点和其先后关系生成Bezier曲线。 ...
    

    项目要求:

    – 使用鼠标在屏幕中任意设置控制点,并生成曲线

    – 使用鼠标和键盘的交互操作实现对曲线的修改。

    项目总体介绍

    本项目利用Bezier曲线生成算法生成可由用户自定义的曲线。可实现核心功能如下:

    1. 用户用鼠标左击屏幕任意处产生记录点。

    2. 鼠标右击屏幕任意处由先前的任意个数记录点和其先后关系生成Bezier曲线。

    另有辅助输入功能:

    1. 按键盘C键可清除所有记录点。

    2. 按键盘R键可清除上一个记录点。

    3. 按键盘Q键可推出程序。

     

     

    项目设计思路

    1Bezier曲线介绍:

    贝塞尔曲线就是这样的一条曲线,它是依据四个位置任意的点坐标绘制出的一条光滑曲线。在历史上,研究贝塞尔曲线的人最初是按照已知曲线参数方程来确定四个点的思路设计出这种矢量曲线绘制法。1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名是为贝塞尔曲线。

    2、生成公式:

    1线性公式(只有两个点情况)

    给定点P0P1,线性贝兹曲线只是一条两点之间的直线。这条线由下式给出:

    且其等同于线性插值。

    2二次方公式(三个点组成)

    二次方贝兹曲线的路径由给定点P0P1P2的函数Bt)追踪:

     

    TrueType字型就运用了以贝兹样条组成的二次贝兹曲线。

    3三次方公式(四个点)

    P0P1P2P3四个点在平面或在三维空间中定义了三次方贝兹曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1P2;这两个点只是在那里提供方向资讯。P0P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。

    曲线的参数形式为:

    现代的成象系统,如PostScriptAsymptoteMetafont,运用了以贝兹样条组成的三次贝兹曲线,用来描绘曲线轮廓。

     

     

    4一般参数公式n个点)

    阶贝兹曲线可如下推断。给定点P0P1、…、Pn,其贝兹曲线即:

     


    N阶的贝兹曲线,即N-1阶贝兹曲线之间的插值。

    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<GL/glut.h>
    //定义控制点数目的最大值
    #define MAX_CPTX 25  
    int ncpts=0;//实际控制点个数
    static int width=600,height=600;//窗口大小
    typedef struct
    {
    	GLfloat x,y;
    } POINT;
    POINT cpts[MAX_CPTX];//存储控制点坐标
    //求n!
    int JieCheng(int n)
    {
    	if(n==1||n==0)
    	{
    		return 1;
    	}
    	else
    	{
    		return n*JieCheng(n-1);
    	}
    }
    //求组合排列
    double C(int n,int i)
    {
    	return ((double)JieCheng(n))/((double)(JieCheng(i)*JieCheng(n-i)));
    }
    //求一个数u的num次方
    double N(double u,int n)
    {
    	double sum=1.0;
    	if (n==0)
    	{
    		return 1;
    	}
    	for(int i=0;i<n;i++)
    	{
    		sum*=u;
    	}
    	return sum;
    }
    
    //绘制bezier曲线
    void drawBezier(POINT *p)
    {    
    	void display();
    	if(ncpts<=0) return;	
    
    	POINT *p1;
    	p1=new POINT[1000];
    	GLfloat u=0,x,y;
    	int i,num=1;
    	p1[0]=p[0];
    	for(u=0;u<=1;u=u+0.001)
    	{   
    		x=0;
    		y=0;
    		for(i=0;i<ncpts;i++)
    		{	
    	      x+=C(ncpts-1,i)*N(u,i)*N((1-u),(ncpts-1-i))*p[i].x;
    	      y+=C(ncpts-1,i)*N(u,i)*N((1-u),(ncpts-1-i))*p[i].y;
    		}
    		p1[num].x=x;
    		p1[num].y=y;
    		num++;
    	}	
    
    	    glPointSize(4.0);
    	    glColor3f(0.0,0.0,0.0);
    	    glBegin(GL_LINE_STRIP);
    	    for(int k=0;k<1000;k++)
    		  glVertex2f(p1[k].x,p1[k].y);
    	    glEnd();
    	    glFlush();
    		return;
    }
    
    
    
    //输入新的控制点
    static void mouse(int button, int state,int x,int y)
    {
    void display();
    float wx,wy;
    //鼠标未按下左键,不做响应
    if(state!=GLUT_DOWN)
       return;
    else 
    	{if(button==GLUT_LEFT_BUTTON)
    	{
    //转换坐标
    wx=(2.0*x)/(float)(width-1)-1.0;
    wy=(2.0*(height-1-y))/(float)(height-1)-1.0;
    //判断控制点数目是否超过最大值
    if(ncpts==MAX_CPTX)
    	return;
    //存储控制点
    cpts[ncpts].x=wx;
    cpts[ncpts].y=wy;
    ncpts++;
    //绘制控制点
    glColor3f(0.0,0.0,0.0);
    glPointSize(5.0);
    glBegin(GL_POINTS);
    glVertex2f(wx,wy);
    glEnd();
    glFlush();
    }
    if(button==GLUT_RIGHT_BUTTON)
    {
    display();
    drawBezier(cpts);
    }
    }
    }
    void display(void)
    {
    	int i;
        glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(0.0,0.0,0.0);
        glPointSize(5.0);
        glBegin(GL_POINTS);
        for (i = 0; i < ncpts; i++)
            glVertex2f(cpts[i].x,cpts[i].y);
        glEnd();
        glFlush();
    
    }
    //键盘回调函数
    void keyboard(unsigned char key,int x,int y)
    {
    	switch (key)
        {
            case 'q': case 'Q':
                exit(0);
                break;
            case 'c': case 'C':
    			ncpts = 0;
    			glutPostRedisplay();
                break;
    		case 'r': case 'R':
    			ncpts--;
    			glutPostRedisplay();
    			break;
        }
    }
    
    //重绘函数
    void reshape(int w,int h)
    {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
    glMatrixMode(GL_MODELVIEW);
    glViewport(0,0,w,h);//调整视口
    width=w;
    height=h;
    }
    int main(int argc, char **argv)
    {
    //初始化
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGB);
    glutInitWindowSize(width,height);
    glutCreateWindow("zjc2012211763");
    //注册回调函数
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutKeyboardFunc(keyboard);
    glutReshapeFunc(reshape);
    glClearColor(1.0,1.0,1.0,1.0);
    glColor3f(0.0,0.0,0.0);
    glutMainLoop();
    }
    






    张竞成

    www.zjc18.com

    展开全文
  • 多控制点生成贝塞尔(Bezier-Curve)样条 C语言版
  • n次Bezier曲线

    2019-04-02 10:42:00
    在vc上基于openGL编写的n次Bezier曲线,可以选择n的大小绘制指定次数的Bezier曲线,之后有较好的交互性,可以在n次Bezier曲线的基础上,将两点拖至重合,变成n-1次Bezier曲线
  • 编程实现了Bezier曲线。并且用OPenGL显示实例
  • 计算机辅助几何设计之Bezier曲线(任意次数)程序实现,并可用鼠标左键进行屏幕选点,利用右键选中某一控制点并拖动控制点实时改变Bezier曲线形状。
  • 使用opengl的反馈模式,获得glut函数绘制的曲面上某一曲线的所有点坐标,来形成动画。包括菜单显示、三维显示、运动速度调节等等。
  • OpenGL-bezier曲线

    2021-04-30 14:12:50
    每一个t带入方程可以得到空间或平面上的一个点 当t从0-1就会得到bezier曲线 n n表示次数 是几次bezier曲线 Pi(0,1,2,…n): 控制多边形的n+1个顶点 (伯恩斯坦基函数)Bi,t(t): 二次bezier曲线 此时有三个控制点 ...

    曲线参数方程

    在这里插入图片描述
    每一个t带入方程可以得到空间或平面上的一个点 当t从0-1就会得到bezier曲线

    n

    n表示次数 是几次bezier曲线

    Pi(0,1,2,…n):

    控制多边形的n+1个顶点

    (伯恩斯坦基函数)Bi,t(t):

    在这里插入图片描述
    在这里插入图片描述

    二次bezier曲线

    此时有三个控制点 P0,P1,P2 ,n=2在这里插入图片描述

    最终简化 直接可以调用

    在这里插入图片描述

    矩阵形式

    在这里插入图片描述

    三次bezier曲线

    最终简化

    在这里插入图片描述

    bezier曲线性质

    端点性

    就是一定会经过第一个和最后一个点

    对称性

    假设n次bezier曲线控制多边形的顶点位置不变 把次序颠倒过来 曲线形状 仍然不变只不过曲线走向相反

    递推性

    n次的伯恩斯坦基函数可以由两个n-1次的伯恩斯坦基函数线性组合而成在这里插入图片描述

    走向

    bezier曲线的起点和终点处的切线方向和特征多边形的第一条和最后一条边走向相同

    变差缩减性在这里插入图片描述

    de Castel jau算法(bezier曲线递推算法)

    在这里插入图片描述
    在这里插入图片描述

    n次bezier曲线的递推公式

    在这里插入图片描述

    展开全文
  • /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(WIDTH, HEIGHT, "Bezier Curve", NULL, NULL); glfwSetWindowPos(window, 600, 200); if (!window) { ...
  • OpenGL画Bezier曲线

    千次阅读 2010-09-26 16:29:00
    最近在看Francis S Hill ,Jr 和 Stephen M Kelley合著的《计算机图形学》(OpenGL版)(第三版)书中有绘制三个控制点的Bezier曲线的代码。自己重新敲了一遍代码。发现了其中的一点小错误,修正过来了。并做了一点小小的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 981
精华内容 392
关键字:

opengl画bezier曲线