C语言代码,Bezier三次曲线

y=(int)(yt);
lineto(x,y);
}
}
void main()
{
static double p[4][2]={50,400,140,20,400,40,635,420};
const NO=3;
int i;
int driver=DETECT,mode;
initgraph(&driver,&mode,"C://tools/tc2.0");//初始化图形系统
Bezier三次曲线实验报告
一:实验目的
用C语言实现Bezier三次曲线原理的划线
二:实验环境
VC6.0
三:实验人数
一人
四:实验内容
Bezier曲线生成的原理和步骤都在程序上给了注释
五:实验步骤
#include <stdio.h>
#include <graphiห้องสมุดไป่ตู้s.h>
#include <conio.h>
//该方法为Bezier三阶的曲线原理
void bezier_3(int color, double p[4][2])
{
double t,t1,t2,xt,yt;
int rate=200,x,y;
setcolor(color);
moveto(p[0][0],p[0][1]);
for (t=0;t<=1;t+=1.0/rate)
bezier_3(LIGHTRED,p);//调用函数,并传递实参颜色、坐标
getch();
closegraph();
}
六:实验问题及解决
用到了很多C语言库自带的函数,通过,进行了学习;如果大家在编译的时候没有#include <graphics.h>请大家安装一个文件
地址:/s/1gN9Xc
cleardevice();//清屏
setcolor(BLUE);//设置前景色为蓝色
moveto(p[0][0],p[0][1]);//把坐标移动到初始化定义的二维数组坐标的第一个坐标
for (i=1;i<NO;i++)//3阶,三次循环
lineto(p[i][0],p[i][1]);//划直线从前一个坐标到后一个坐标
{
yt=1-t;
t1=yt*yt;
t2=3*yt*t;
xt=p[0][0]*t1*yt+p[1][0]*t2*yt+p[2][0]*t2*t+p[3][0]*t*t*t;
yt=p[0][1]*yt*t1+p[1][1]*t2*yt+p[2][1]*t2*t+p[3][1]*t*t*t;
x=(int)(xt);
合集下载

bezier曲线或b样条曲线的绘制

bezier曲线或b样条曲线的绘制

淮阴工学院计算机科学系实验报告书课程名:《计算机图形学》题目:实验4 BEZIER曲线或B样条曲线的绘制班级:学号:姓名:评语:成绩:指导教师:批阅时间:年月日1、实验内容或题目编程实现三次BEZIER或B样条曲线的绘制。

2、实验目的与要求(1) 通过实验,进一步理解和掌握生成BEZIER或B样条曲线的算法;(2) 掌握BEZIER或B样条曲线的基本生成过程;(3) 通过编程,会在TC环境下编程实现三次BEZIER或B样条曲线的绘制。

3、实验步骤与源程序错误!未找到引用源。

实验步骤1、算法、原理清晰,有详细的设计步骤;2、依据算法、步骤或程序流程图,用C语言编写源程序;3、编辑源程序并进行调试;4、进行特殊模式的运行测试,并结合情况进行调整;5、对运行结果进行保存与分析;6、打印源程序或把源程序以文件的形式提交;7、按格式书写实验报告。

错误!未找到引用源。

源代码#include "graphics.h"float px[4]={ 50,80,120,140 };float py[4]={100,230,230,160};void Bezier(){float a0,a1,a2,a3,b0,b1,b2,b3;int k,x,y;float i,t,n=4;setcolor(15);for(k=0;k<3;k++){moveto(px[k],py[k]);lineto(px[k+1],py[k+1]);}setcolor(4);a0=px[0];a1=-3*px[0]+3*px[1];a2=3*px[0]-6*px[1]+3*px[2];a3=-px[0]+3*px[1]-3*px[2]+px[3];b0=py[0];b1=-3*py[0]+3*py[1];b2=3*py[0]-6*py[1]+3*py[2];b3=-py[0]+3*py[1]-3*py[k+2]+py[3];for(i=0;i<n;i+=0.001){t=i;x=a0+a1*t+a2*t*t+a3*t*t*t;y=b0+b1*t+b2*t*t+b3*t*t*t;if(i==0)moveto(x,y);lineto(x,y);}}void main(){int driver,mode;driver=DETECT;initgraph(&driver,&mode,"..\\bgi");Bezier();}4、测试数据与实验结果5、结果分析与实验体会通过这次实验,我初步熟悉了turboc 的运行环境。

三次Bezier曲线的生成与拼接

三次Bezier曲线的生成与拼接

三次Bezier曲线的生成与拼接李红林【摘要】本文利用VC++编程环境,生成两段三次Bezier曲线,并对曲线进行连续性条件讨论,且实现了曲线拼接.【期刊名称】《科技视界》【年(卷),期】2016(000)021【总页数】2页(P126,187)【关键词】三次;Bezier;连续性;曲线拼接【作者】李红林【作者单位】曲靖师范学院信息工程学院,云南曲靖655011【正文语种】中文Bezier曲线是由法国人Bezier于20世纪70年代初为解决汽车外型设计而提出的一种新的参数表示方法[1]。

Bezier方法是曲线、曲面造型中的一个里程碑,它以逼近原理为基础,应用Bezier方法,可逼近数学曲线、曲面或设计师勾画的草图,起到辅助设计的作用[2-3]。

由于实际应用中的线和面形状复杂,用单一曲线、曲面无法表示,所以有必要对曲线、曲面进行拼接。

1.1 Bezier曲线的定义其中,t∈[0,1],Pi是特征多边形第i个顶点的坐标(xi,yi)。

依次用线段连接Pi(i=0,1,…,n)中相邻两个向量的终点,组成的n边折线多边形称为Bezier多边形或特征多边形[4]。

Bi,n(t)是伯恩斯坦多项式。

1.2 三次Bezier曲线当n=3时,即为三次Bezier曲线。

三次Bezier曲线用矩阵表示如下:在VC++6.0环境下,新建一个基于MFC的单文档工程。

在工程View.cpp中添加Bezier曲线生成函数,当n=3时,生成任意两条三次Bezier曲线,如图1所示。

样条曲线是由各个多项式曲线段连接而成,为了保证各个曲线段在连接点处是光滑的,需要满足各种连续性条件[5]。

连续性有参数连续性和几何连续性。

若两条相邻参数曲线段在连接点处具有n阶连续导矢,即n阶连续可微,则将这类连续性称为n阶参数连续性条件,记为Cn。

若只要求两条相邻参数曲线段在连接点处的n阶导矢成比例,而不要求必须相等,则将这类连续性称为n阶几何连续性,记为Gn。

三次Bezier曲线原理及实现代码

三次Bezier曲线原理及实现代码

Bezier曲线原理及实现代码(c++)一、原理:贝塞尔曲线于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。

贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau 算法开发,以稳定数值的方法求出贝塞尔曲线。

线性贝塞尔曲线给定点P0、P1,线性贝塞尔曲线只是一条两点之间的直线。

这条线由下式给出:且其等同于线性插值。

二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t) 追踪:。

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

P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝塞尔曲线。

曲线起始于P0走向P1,并从P2的方向来到P3。

一般不会经过P1或P2;这两个点只是在那里提供方向资讯。

P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。

曲线的参数形式为:。

现代的成象系统,如PostScript、Asymptote和Metafont,运用了以贝塞尔样条组成的三次贝塞尔曲线,用来描绘曲线轮廓。

一般化P0、P1、…、P n,其贝塞尔曲线即。

例如:。

如上公式可如下递归表达:用表示由点P0、P1、…、P n所决定的贝塞尔曲线。

则用平常话来说,阶贝塞尔曲线之间的插值。

一些关于参数曲线的术语,有即多项式又称作n阶的伯恩斯坦基底多项式,定义00 = 1。

点P i称作贝塞尔曲线的控制点。

多边形以带有线的贝塞尔点连接而成,起始于P0并以P n终止,称作贝塞尔多边形(或控制多边形)。

贝塞尔多边形的凸包(convex hull)包含有贝塞尔曲线。

线性贝塞尔曲线函数中的 t 会经过由 P 0 至P 1 的 B(t ) 所描述的曲线。

例如当 t=0.25 时,B(t ) 即一条由点 P 0 至 P 1 路径的四分之一处。

就像由 0 至 1 的连续 t ,B(t ) 描述一条由 P 0 至 P 1 的直线。

绘制Bezier曲线编程及说明

绘制Bezier曲线编程及说明

绘制Bezier曲线编程及说明整体方案:(1)单击鼠标左键绘制控制点(不超过10个顶点),并自动连接为控制多边形。

(2)单击鼠标右键确定绘制Bezier曲线完毕。

(3)绘制时鼠标显示坐标。

(4)点击控制点可以改变Bezier曲线形状。

(5)可以使用鼠标或者键盘输入坐标绘制Bezier曲线。

关键技术:最小二乘法,曲线拟合,MFC框架编程Bezier曲线编程算法:// JjbView.cpp : implementation of the CJjbView class//#include "stdafx.h"#include "Jjb.h"#include "JjbDoc.h"#include "JjbView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CJjbViewIMPLEMENT_DYNCREATE(CJjbView, CView)BEGIN_MESSAGE_MAP(CJjbView, CView)//{{AFX_MSG_MAP(CJjbView)ON_COMMAND(ID_BEZIER, OnBezier)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_WM_RBUTTONDOWN()//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CJjbView construction/destructiondouble J(int n,int i);double C(int n,int i);double N(double u,int n);int JieCheng(int n);//构造函数CJjbView::CJjbView(){// TODO: add construction code herem_bIsChoosed=false;m_bStopDraw=false;m_bMakeSure=false;m_eChooseType=Bezier;while (m_vInputPoint.size()!=0){m_vInputPoint.pop_back();}while (m_vControlPoint.size()!=0){m_vControlPoint.pop_back();}while (m_vXiShu.size()!=0){m_vXiShu.pop_back();}}//析构函数CJjbView::~CJjbView(){while (m_vInputPoint.size()!=0){m_vInputPoint.pop_back();}while (m_vControlPoint.size()!=0){m_vControlPoint.pop_back();}while (m_vXiShu.size()!=0){m_vXiShu.pop_back();}}BOOL CJjbView::PreCreateWindow(CREATESTRUCT& cs) //定义窗口{// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CJjbView drawing// 刷新时绘图void CJjbView::OnDraw(CDC* pDC){CJjbDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereGetClientRect(&rect);if (m_eMouseStatus==MouseMove&&m_bStopDraw==false){m_vInputPoint.push_back(m_cMovePoint);}CString str;CClientDC d(this);int i;if(m_bIsChoosed==true){if (m_bStopDraw==false){str.Format(" X=%d,y=%d ]",m_cMovePoint.x,m_cMovePoint.y);d.TextOut(m_cMovePoint.x+10,m_cMovePoint.y+10,str);}switch(m_eChooseType)//菜单选择{case Bezier: //选择后的窗口状态str.Format("Bezier曲线,点击右键表示确定,移动节点改变形状。

实验4 Beizer曲线

实验4 Beizer曲线

实验4、Beizer曲线系别:计算机学院专业班级:10信科2姓名:学号:实验日期:实验报告日期:一、实验目的1熟悉VC6.0开发平台;2熟悉OpenGL开发库;二、实验内容:1.自己编写函数实现三次一段Bezier曲线的绘制。

2.调用OpenGL函数绘制两段Bezier曲线并实现拼接,要求在节点处满足一阶几何连续。

三、实验指导:算法实现过程中需要计算两个矩阵的乘积。

由于参与运算的两个矩阵的大小不确定,而C 语言中二维数组作参数至多省略第一维的大小显得不够灵活,而一维数组做参数则不受此限制。

因此,在实现矩阵乘积时用一维数组代替二维数组,调用该函数前也需要将二维数组转化为一维数组,转化方法是遵循C语言的行优先。

函数实现如下://计算矩阵A左乘矩阵B的值,结果存入C。

其中,A、B、C的大小分别为mxn、nxp、mxp //二维数组作参数至少第二维的大小必须是确定的,此处为了使矩阵的两个维大小均可变,将二维数组转化为一维数组进行处理// 传递实参A、B时,要求其中的数据存放顺序与C语言中二维数组存放顺序一致,即行优先。

//输入参数:m为第一个矩阵的行数和结构矩阵的行数,p为第一个矩阵的列数,第二个矩阵的行数,n为第二个矩阵的列数和结果矩阵的列数void matrix_mul(double A[], double B[], double C[], int m, int n, int p){for (int i = 0; i < m; i++){for (int j = 0; j < p; j++){C[i*p+j] = 0;//C[i][j]对应一维数组的C[i*p+j]for (int k = 0; k < n; k++){C[i*p+j] += A[i*n+k] * B[k*p+j];//A[i][k]对应一维数组的A[i*n+k];B[k][j]对应一维数组的B[k*p+j]}}}}此外,计算出各型值点后调用glBegin(GL_LINE_STRIP),用首尾相连的这线段连接起来即得到三次Beizer曲线。

三次bezier曲线控制点计算

三次bezier曲线控制点计算

在计算三次Bezier曲线控制点时,我们需要首先了解什么是Bezier曲线和它的控制点。

Bezier曲线是一种常用的曲线插值方法,它由起始点、结束点和控制点组成。

三次Bezier曲线由四个点控制,分别是起始点P0,结束点P3,以及两个控制点P1和P2。

计算这些控制点的位置是为了确定曲线的形状和路径。

1. 理解Bezier曲线我们需要理解Bezier曲线的基本原理。

Bezier曲线是通过多个控制点插值计算出来的曲线,其中三次Bezier曲线的数学表达式为:\[B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3 \]在这个公式中,\(t\) 是曲线的参数,取值范围在0到1之间。

\(P0\) 到 \(P3\) 分别是起始点、结束点和两个控制点。

2. 计算控制点针对三次Bezier曲线,我们需要计算出控制点 \(P1\) 和 \(P2\) 的具体位置。

这个过程可以通过各种不同的方法来实现,其中一种常用的方法是通过参数化的方式来计算。

- 参数化计算参数化的计算方法是通过设定特定的参数值来计算控制点的位置。

一种常用的参数化计算方法是通过离散化的方式,将曲线按一定的步长进行分割,然后根据每个分割点的位置来计算出对应的控制点。

这种方法的优势在于可以灵活地控制曲线的形状和路径,同时也比较容易理解和实现。

但是在实际应用中,可能需要根据具体情况来选择不同的参数化方法,以获得更好的效果。

3. 个人观点和总结对于三次Bezier曲线控制点的计算,我个人认为在实际应用中需要根据具体情况来选择合适的计算方法。

在计算过程中需要考虑到曲线的平滑度、路径和形状,以达到更好的效果。

三次Bezier曲线控制点的计算是一个重要且复杂的问题,需要综合考虑数学、计算机图形学和实际应用等方面的知识。

通过深入研究和实践,我们可以更好地掌握这个技术,并将其运用到实际的项目中。

三次Bezier曲线是一种重要的数学工具,在计算机图形学、工程建模和动画制作等领域都有着广泛的应用。

分段连续三次Bezier 曲线控制点的构造算法

N k*3 + 1 = P 0R; (2.5) 置 N k*3 + 0 = P 0 ,
图5
三点共线时中间点的控制点的不同方向选取
(3) 当 k == n + 1 - 3时, 计算结束点的左控制点: 由 (1) 可知, 此时
P1、 P1R, 点 P1R已计算出, 点 P 2为结束点, 利用点 P 2、 计算点 P 2的左控制
[1]
来实现) , 地形数据调度策略一般基于视点连续变化来设计, 如果视点方向变化剧烈, 很容易产生大规模新的地形数据内 存加载, 导致系统运行不流畅, 影响视觉效果。因此, 用户希 望看到飞行转弯时能平滑、 自然, 这就要求对飞行路线进行逼 近或插值, 尤其需要对路线线段的转折处进行光滑处理, 分段 三次 Overhauser 样条、 Bezier 样条等都能满足这类需求。选用 分段连续三次 Bezier 曲线, 对曲线的控制点进行设计, 构造出 合理的控制点集, 保证拟合曲线通过用户输入的所有关键点, 具有一定的光滑度, 而且, 用户通过生成的控制点, 可对曲线 进行一定程度的局部修改, 从而可进一步完成交互编辑功能。
1
引言
在与地形相关的软件中, 一般都要提供给用户模拟飞行
使用 Bezier 曲线进行拟合, 同时注意在两段的连接点与其两 侧的新插入的控制点保持三点共线, 参看图 1。文献 [2] 中给 出了插入控制点的基本过程, 本文则进一步给出了更加详细 的控制点的构造设计及几何说明。在图 2 中, 用户通过调整
P1R, 点 P1两侧在方向 P 012上取两点 P1L、 参看图 4。
P1 P 1R
输入点 {
P1 = Ci + 1, P 2 = Ci + 2; (0) 置 P 0 = C i, P1、 P 2, (1) 通过三点 P 0、 计算点 P1的左控制点 P1L和右控制点 P1R:

双三次Bezier曲面的绘制

课程名称:?计算机图形学?论文题目:双三次Bezier曲面的绘制教学部:年级:班级:学号:姓名:摘 要:本文主要讨论了在VC++中使用OpenGL 绘制Bezier 、NURBS 等典型曲面的一般性方法和OpenGL 的特点及功能,OpenGL 可以与Visual C++严密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性 。

关键词:Bezier 曲面;OpenGL ;曲面绘制一、设计概述1.设计要求1〕掌握双三次Bezier 曲面定义:Bezier 曲面与 Bezier 曲线有一样的性质,Bezier 曲面片是由特征多面体的顶点决定的,利用两组正交的 Bezier 曲线逼近由控制点网格描述的曲面。

给定〔n+1〕*〔m+1〕个点Pjk 〔i=0,1…n ;j=0,1,...m 〕,那么可以生成一个n*m 次的Bezier 曲面片,其表示形式为其中Pij 是Bezier 曲面片的特征多面体。

当m=n=3时,特征多面体有16个顶点,其相应的Bezier 曲面片称为双三次Bezier 曲面片。

2〕实现矩阵相关运算;双三次Bezier 曲面片的矩阵表示为其中2.设计方案∑∑===m i n j n j m i j i Q v B u B p v u 00,,,)()(),([0,1]v)(u,∈T T bb Q V GM UM v u =),(⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡----=0001003303631331b M ⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡=44434241343332312423222114131211P P P P P P P P P P P P P P P P G []123u u u U =[]123v v v V =1〕给定16个三维控制点如下:P00(200,20,0),P01(150,0,100),P02(50,-130,100),P03(0,-250,50);P10(150,100,100),P11(100,30,100),P12(50,-40,100),P13(0,-110,100);P20(140,280,90),P21(80,110,120),P22(30,30,130),P23(-50,-100,150);P30(150,350,30),P31(50,200,150),P32(0,50,200),P33(-70,0,100);2〕实现键盘控制曲面旋转效果二、环境需求分析开发环境:Windows XP开发工具:Microsoft Visual Studio 2005运行环境:本系统是基于OpenGL软件接口和VC++应用程序开发的一套管理系统,本系统可以在装有Windows 98 /2000/XP/NT的操作系统下运行。

三次Bezier曲线

作业三:三次Bezier曲线1. 设计要求:1.在程序窗口中建立坐标系2.输入控制点,绘制出三次Bezier曲线3.四个控制点间依次用细线连接4.在程序窗口显示四个控制点的位置并标出2. 设计思路:先在草稿纸上算出三次Bezier曲线的函数表达式: (0≤u≤1)=a×+b×+c×u+d其中a、b、c、d的值为:a=(-) + 3 × - 3 × +b=3× - 6 × + 3 ×c=(-3) × + 3 ×d=将、、、中的(x,y)坐标值分别代入a、b、c、d中得到、、、和、、、则:=×+×+×u+ (1)=×+×+×u+ (2)根据以上结果(1)和(2)编程求得当u取不同值时所得到的点P(u)。

再将各点用线连接起来即可拟合三次Bezier曲。

3. 设计过程:以下是用VB编三次Bezier曲线时的源代码:其中显示四个控制点的思路是将控制点在x和y方向的坐标值都增大1,然后再与控制点用粗实线连接起来。

这样一来在窗口中显示的即为一个较大的实点。

Function drawcs() '此模块为建立坐标系Dim k As IntegerPictDraw.DrawWidth = 1: PictDraw.FontSize = 9 '设置线宽和字体 PictDraw.Line (-400, 0)-(400, 0), RGB(100, 100, 100)PictDraw.Line (0, -300)-(0, 300), RGB(100, 100, 100)For k = (-360) To 360 Step 40PictDraw.Line (k, -5)-(k, 0): PictDraw.CurrentX = k - 20: PictDraw.CurrentY = 5: PictDraw.Print kNext kFor k = (-280) To -40 Step 40PictDraw.Line (5, k)-(0, k): PictDraw.CurrentX = -40: PictDraw.CurrentY = k - 10: PictDraw.Print (-1) * kNext kFor k = (40) To 280 Step 40PictDraw.Line (5, k)-(0, k): PictDraw.CurrentX = -40: PictDraw.CurrentY = k - 10: PictDraw.Print (-1) * kNext kEnd FunctionPrivate Sub Form_Load()PictDraw.AutoRedraw = TruePictDraw.ScaleWidth = 800PictDraw.ScaleHeight = 600Text1.Text = -300: Text2.Text = -250: Text3.Text = 300: Text4.Text = -250Text5.Text = -300: Text6.Text = 250: Text7.Text = 300: Text8.Text = 250 '作为初始值,便于测试drawcsEnd SubPrivate Sub cmdCancle_Click()PictDraw.Clsdrawcs '清除屏幕后,重建坐标系End SubPrivate Sub delet_Click() '此模块为清除输入框中的值 Text1.Text = ""Text2.Text = ""Text3.Text = ""Text4.Text = ""Text5.Text = ""Text6.Text = ""Text7.Text = ""Text8.Text = ""End SubPrivate Sub cmdDraw_Click() '此模块为画三次Bezier曲线Dim px(4) As Double '定义控制点的x坐标的数组Dim py(4) As Double '定义控制点的y坐标的数组Dim a1, b1, c1, d1 As Double '定义x系数Dim a2, b2, c2, d2 As Double '定义y系数Dim x, y, u As Double '定义曲线中的自变量u和变量x,y Dim i As IntegerIf (Not IsNumeric(Text1) Or Not IsNumeric(Text2) Or Not IsNumeric(Text3) Or Not IsNumeric(Text4) _Or Not IsNumeric(Text5) Or Not IsNumeric(Text6) Or Not IsNumeric(Text7) Or Not IsNumeric(Text8)) ThenText1.Text = "": Text2.Text = ""Text3.Text = "": Text4.Text = ""Text5.Text = "": Text6.Text = ""Text7.Text = "": Text8.Text = ""Text1.SetFocus '判断输入框中的字符是否为数字,如果为数字执行else开始画图Elsepx(0) = Text1.Text: py(0) = Text2.Textpx(1) = Text3.Text: py(1) = Text4.Textpx(2) = Text5.Text: py(2) = Text6.Textpx(3) = Text7.Text: py(3) = Text8.TextPictDraw.FontSize = 18 '设置字体,为显示输入的四个点设置字体大小PictDraw.CurrentX = px(0): PictDraw.CurrentY = (-1) * py(0): PictDraw.Print "P"; 0For i = 0 To 2PictDraw.DrawWidth = 1PictDraw.Line (px(i), (-1) * py(i))-(px(i + 1), (-1) * py(i + 1)), RGB(0, 0, 255): PictDraw.Print "P"; i + 1Next iFor i = 0 To 3PictDraw.DrawWidth = 7PictDraw.Line (px(i), (-1) * py(i))-(px(i) + 1, (-1) * py(i) - 1)Next ia1 = -px(0) + 3 * px(1) - 3 * px(2) + px(3) '计算x和y的参数 b1 = 3 * px(0) - 6 * px(1) + 3 * px(2)c1 = -3 * px(0) + 3 * px(1)d1 = px(0)a2 = -py(0) + 3 * py(1) - 3 * py(2) + py(3)b2 = 3 * py(0) - 6 * py(1) + 3 * py(2)c2 = -3 * py(0) + 3 * py(1)d2 = py(0)For u = 0 To 1 Step 0.001 '每当u增加0.001求一次x和y x = a1 * u * u * u + b1 * u * u + c1 * u + d1 '求x的值y = (-1) * (a2 * u * u * u + b2 * u * u + c2 * u + d2) '求y的值 If u = 0 ThenPictDraw.CurrentX = x '设置画线起点PictDraw.CurrentY = yElsePictDraw.DrawWidth = 2PictDraw.Line -(x, y), RGB(255, 0, 0) '连点成线End IfNext uEnd IfEnd SubPrivate Sub cmdEnd_Click() '退出窗口程序EndEnd Sub4. 设计截图:图四.三次Bezier曲线截图。

计算机图形学实验4-----Hermite-Bezier-B样条三种曲线的绘制

实验四 Hermite Bezier B样条三种曲线的绘制一、实验目的了解和学习Hermite、Bezier、B样条三种曲线算法掌握基于 Win32、Visual C++环境MFC绘制图形配置过程制过程编程实现Hermite、Bezier、B样条三种曲线的绘制二、实验原理三次参数曲线1.曲线段可以用端点、切向量和曲线段之间的连续性等约束条件来定义2.两个端点和两端点处的切向量定义Hermite曲线;3.两个端点和另外两个控制端点切向量的点定义的Bezier曲线;4.由四个控制顶点定义的样条曲线。

三、实验关键代码void CDrawYTQXView::Hermite() //绘制Hermite三次插值样条{int a[4][4] ={{2,-2,1,1},{-3,3,-2,-1},{0,0,1,0},{1,0,0,0}};//Mh 矩阵系数int b[4][2];//边界点for(int i=0;i<4;i++){b[0][0]=p1[i][0];b[0][1]=p1[i][1];//起点的坐标b[1][0]=p1[i+1][0];b[1][1]=p1[i+1][1];//终点的坐标b[2][0]=p2[i][0];b[2][1]=p2[i][1];//起点的导数b[3][0]=p2[i+1][0];b[3][1]=p2[i+1][1];//终点的导数Caculate(a,b);CClientDC dc(this);CPen MyPen,*pOldPen;MyPen.CreatePen(PS_SOLID,1,RGB(0,0,255));pOldPen=dc.SelectObject(&MyPen);dc.MoveTo(p1[i][0],p1[i][1]);for(double t=0.0;t<=1;t+=1.0/400){int x=ROUND(pow(t,3)*result[0][0]+pow(t,2)*result[1][0]+ t*result[2][0]+result[3][0]);int y=ROUND(pow(t,3)*result[0][1]+pow(t,2)*result[1][1]+ t*result[2][1]+result[3][1]);dc.LineTo(x,y);}dc.SelectObject(pOldPen);MyPen.DeleteObject();}}void CDrawYTQXView::Caculate(int a[4][4],int b[4][2])//矩阵相乘{int i,j,k;for(i=0;i<4;i++)for(j=0;j<2;j++)result[i][j]=0; //矩阵清零for(i=0;i<2;i++)for(j=0;j<4;j++)for(k=0;k<4;k++)result[j][i]+=a[j][k]*b[k][i];}void CDrawYTQXView::DrawBezier()//绘制Bezier曲线{CClientDC dc(this);double x,y;int rate=400,n;n=CtrlPoint-1;for(double t=0;t<=1;t+=1.0/rate){x=0;y=0;for(int i=0;i<=n;i++){x+=pt[i].x*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);y+=pt[i].y*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);}dc.SetPixel(ROUND(x),ROUND(y),RGB(0,0,255)); //曲线颜色}}double CDrawYTQXView::Cnk(const int &n, const int &i)//Bernstein 第一项{return double(Factorial(n)/(Factorial(i)*Factorial(n-i)));}int CDrawYTQXView::Factorial(int m)//阶乘函数{int f=1;for(int i=1;i<=m;i++)f*=i;return f;}void CDrawYTQXView::DrawB3_curves() //绘制B样条曲线{CClientDC dc(this);int i,rate=10,m;long lx,ly;m=CtrlPoint-(3+1);double F03,F13,F23,F33;lx=ROUND((pt[0].x+4.0*pt[1].x+pt[2].x)/6.0); //t=0的起点x坐标ly=ROUND((pt[0].y+4.0*pt[1].y+pt[2].y)/6.0);//t=0的起点y坐标dc.MoveTo(lx,ly);CPen MyPen2,*pOldPen2;MyPen2.CreatePen(PS_SOLID,2,RGB(0,0,255)); //颜色设置pOldPen2=dc.SelectObject(&MyPen2);for(i=1;i<m+2;i++) //m+1段三次样条曲线{for(double t=0;t<=1;t+=1.0/rate){F03=(-t*t*t+3*t*t-3*t+1)/6;//计算F0,3(t)F13=(3*t*t*t-6*t*t+4)/6;//计算F1,3(t)F23=(-3*t*t*t+3*t*t+3*t+1)/6;//计算F2,3(t)F33=t*t*t/6;//计算B3,3(t)lx=ROUND(pt[i-1].x*F03+pt[i].x*F13+pt[i+1].x*F23+pt[i+2].x*F33 );ly=ROUND(pt[i-1].y*F03+pt[i].y*F13+pt[i+1].y*F23+pt[i+2].y*F33 );dc.LineTo(lx,ly);}}dc.SelectObject(pOldPen2);MyPen2.DeleteObject();}void CDrawYTQXView::DrawCharPolygon()//绘制控制多边形{CClientDC dc(this);CPen MyPen,*pOldPen;MyPen.CreatePen(PS_SOLID,2,RGB(0,0,0)); //控制多边形pOldPen=dc.SelectObject(&MyPen);for(int i=0;i<CtrlPoint;i++){if(i==0){dc.MoveTo(pt[i]);dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);}else{dc.LineTo(pt[i]);dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);}}dc.SelectObject(pOldPen);MyPen.DeleteObject();}void CDrawYTQXView::OnLButtonDown(UINT nFlags, CPoint point)//获得屏幕控制点坐标{// TODO: Add your message handler code here and/or call default CView::OnLButtonDown(nFlags, point);if(Flag){pt[CtrlPoint].x=point.x;pt[CtrlPoint].y=point.y;if(CtrlPoint<N_MAX_POINT)CtrlPoint++;elseFlag=false;DrawCharPolygon();}else DrawCharPolygon1();}void CDrawYTQXView::OnRButtonDown(UINT nFlags, CPoint point)//调用绘制函数{// TODO: Add your message handler code here and/or call default Flag=false;if(Sign==0)Hermite();if(Sign==1)DrawBezier();if(Sign==2)DrawB3_curves();CView::OnRButtonDown(nFlags, point);}四、实验结果1、绘制Hermite曲线2、绘制Bezier曲线3. 绘制B样条曲线五、心得体会通过实验进一步学习和了解MFC的菜单的实现及其响应函数的实现,并设置鼠标的左键激活绘制多边形,右键激活绘制Hermite、Bezier、B样条三种曲线。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档