当前位置:文档之家› 三次Bezier曲线的实现方法

三次Bezier曲线的实现方法

三次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 的直线。

为建构二次贝塞尔曲线,可以中介点 Q 0 和 Q 1 作为由 0 至 1 的 t :

? 由 P 0 至 P 1 的连续点 Q 0,描述一条线性贝塞尔曲线。 ? 由 P 1 至 P 2 的连续点 Q 1,描述一条线性贝塞尔曲线。

? 由 Q 0 至 Q 1 的连续点 B(t ),描述一条二次贝塞尔曲线。 ?

为建构高阶曲线,便需要相应更多的中介点。对于三次曲线,可由线性贝塞尔曲线描述的中介点 Q 0、Q 1、Q 2,和由二次曲线描述的点 R 0、R 1 所建构:

对于四次曲线,可由线性贝塞尔曲线描述的中介点 Q 0、Q 1、Q 2、Q 3,由二次贝塞尔曲线描述的点 R 0、R 1、R 2,和由三次贝塞尔曲线描述的点 S 0、S 1 所建构:

P(t)=(1-t)P0+tP1 ,。

矩阵表示为:

,。

P(t)=(1-t)2P0+2t(1-t)P1+t2P2,。

矩阵表示为:

,。

P(t)=(1-t)3P0+3t(1-t)2P1+3t2(1-t)P2+t3P3

矩阵表示为:

,。

(6-3-2)

,。

在(6-3-2)式中,M n+1是一个n+1阶矩阵,称为n次Bezier矩阵。

(6-3-3)

其中,

利用(6-3-3)式,我们可以得到任意次Bezier矩阵的显式表示,例如4次和5次Bezier矩阵为:

可以证明,n次Bezier矩阵还可以表示为递推的形式:

(6-3-4)

二、算法(c++)

工程目录是:Win32App

vc6.0

#include

#include

#include

#define NUM 10

LRESULT CALLBACK Winproc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstanc,LPSTR lpCmdLine,int nShowCmd)

{

MSG msg;

static TCHAR szClassName[] = TEXT("::Bezier样条计算公式由法国雷诺汽车公司的工程师Pierm Bezier于六十年代提出");

HWND hwnd;

WNDCLASS wc;

wc.cbClsExtra =0;

wc.cbWndExtra =0;

wc.hbrBackground =

(HBRUSH)GetStockObject(WHITE_BRUSH);

wc.hCursor = LoadCursor(NULL,IDC_ARROW);

wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);

wc.hInstance = hInstance;

wc.lpfnWndProc = Winproc;

wc.lpszClassName = szClassName;

wc.lpszMenuName = NULL;

wc.style = CS_HREDRAW|CS_VREDRAW;

if(!RegisterClass(&wc))

{

MessageBox(NULL,TEXT("注册失败"),TEXT("警告框

"),MB_ICONERROR);

return 0;

}

hwnd = CreateWindow(szClassName,szClassName,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,CW_USEDEFAULT,

NULL,NULL,hInstance,NULL);

ShowWindow(hwnd,SW_SHOWMAXIMIZED);

UpdateWindow(hwnd);

while(GetMessage(&msg,NULL,0,0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

LRESULT CALLBACK Winproc(HWND hwnd,UINT message, WPARAM wparam,LPARAM lparam)

{

HDC hdc;

static POINT pt[NUM];

TEXTMETRIC tm;

static int cxClient,cyClient;

HPEN hpen;

int i,j,k,n,t;

switch(message)

{

case WM_CREATE:

static int cxchar;

hdc = GetDC(hwnd);

GetTextMetrics(hdc,&tm);

cxchar = tm.tmAveCharWidth;

ReleaseDC(hwnd,hdc);

case WM_SIZE:

cxClient = LOWORD(lparam);

cyClient = HIWORD(lparam);

return 0;

case WM_PAINT:

hdc = GetDC(hwnd);

srand(time(0));

Rectangle(hdc,0,0,cxClient,cyClient);

for(i=0; i<500; i++)

{

SelectObject(hdc,GetStockObject(WHITE_PEN));

PolyBezier(hdc,pt,NUM);

for(j=0; j

{

pt[j].x = rand()%cxClient;

pt[j].y = rand()%cyClient;

}

hpen =

CreatePen(PS_INSIDEFRAME,3,RGB(rand()%256,rand()%25 6,rand()%256));

DeleteObject(SelectObject(hdc,hpen));

PolyBezier(hdc,pt,NUM);

for(k=0; k<50000000;k++);

}

for(i=0; i<100;i++)

{

Ellipse(hdc,rand()%cxClient,rand()%cyClient,rand()%c xClient,rand()%cyClient);

Pie(hdc,j=rand()%cxClient,k=rand()%cyClient,n=rand( )%cxClient,t=rand()%cyClient,rand()%cxClient,rand()%cyC lient,rand()%cxClient,rand()%cyClient) ;

}

if((n=(n+j)/2)>cxchar*20) n=cxchar*20;

SetTextColor(hdc,RGB(rand()%256,rand()%256,rand() %256));

TextOut(hdc,n/2,(t+k)/2,TEXT("瑾以此向Pierm Bezier致敬!"),lstrlen(TEXT("瑾以此向Pierm Bezier致敬!")));

ReleaseDC(hwnd,hdc);

DeleteObject(hpen);

ValidateRect(hwnd,NULL);

return 0;

case WM_DESTROY:

PostQuitMessage(0);

return 0;

}

return DefWindowProc(hwnd,message,wparam,lparam);

}

竖曲线习题

竖曲线练习题 1、设在桩号K2 +600 处设一竖曲线变坡点,高程m . i1 =1%, i2 = -2%,竖曲线半径3500 m试计算竖曲线个点高程(20m整桩即能被20整除的桩号) 解:ω= i2 -i1 = -2% -1% = -3% 为凸曲线。 曲线长L = Rω= 3500× = 105 m . 切线长T = L/2 = 105÷2 = m 竖曲线起点桩号= (K2 +600 ) -= K2 + 竖曲线终点桩号= ( K2 +600) += K2 + 竖曲线起点高程= -× = m 竖曲线终点高程= -× = m 各20 m整桩 K2+560 X1 = (K2 + 560)-( K2 + = m h1 =X2/2R = ÷7000 = m 切线高程: -[(K2 + 600) -(K2 + 560)] X = m 设计高程-= m K2+580 X1 = (K2 + 580)-( K2 + = m h1 =X2/2R = ÷7000 = m 切线高程: -((K2 + 600) -(K2 + 580)) X = m 设计高程-= m K2+600 X1 = T =(K2 + 6000)-( K2 + = m h1 =X2/2R = ÷7000 = m 切线高程: m 设计高程-= m K2+620 X1 = (K2 + )-( K2 +620) = m h1 =X2/2R = ÷7000 = m 切线高程: -((K2 + 620) -(K2 + 600)) X = 设计高程-= 9m K2+640 X1 = (K2 + )-( K2 +640) = m h1 =X2/2R = ÷7000 = m 切线高程: -[(K2 + 640 -(K2 + 600)] X = m 长度不小于500 m 。试确定竖曲线最小半径值并计算K1 +800 、K1 +840、K1 +860 设计高程。 解:ω= i2 -i1 = % -(-)% = 4% 为凹曲线。

计算机图形学上机实验4_实现Bezier曲线和Bezier曲面的绘制

昆明理工大学理学院 信息与计算科学专业操作性实验报告 年级: 10级姓名:刘陈学号: 201011101128 指导教师: 胡杰 实验课程名称:计算机图形学程序设计开课实验室:理学院机房216 实验内容: 1.实验/作业题目:用计算机高级语言VC++6.0实现计算机的基本图元绘制2.实验/作业课时:2学时 3.实验过程(包括实验环境、实验内容的描述、完成实验要求的知识或技能):实验环境:(1)硬件:每人一台PC机 (2)软件:windows OS,VC++6.0或以上版本。 试验内容及步骤: (1)在VC++环境下创建MFC应用程序工程(单文档) (2)编辑菜单资源 (3)添加菜单命令消息处理函数 (4)添加成员函数 (5)编写函数内容 试验要求: (1)掌握Bezier曲线、Bezier曲面、及另一个曲面的算法。 (2)实现对Bezier曲线、Bezier曲面、及另一个曲面。 (3)试验中调试、完善所编程序,能正确运行出设计要求结果。 (4)书写试验报告上交。 4.程序结构(程序中的函数调用关系图)

5.算法描述、流程图或操作步骤: 在lab4iew.cpp文件中添加如下头文件及变量 int flag_2=0; int n_change; #define M 30 #define PI 3.14159 //圆周率 #include "math.h" //数学头文件 在lab4iew.h文件中的public内添加变量: int move; int graflag; void Tiso(float p0[3],float x0, float y0, float p[3]); void OnBezierface(); 在lab4iew.h文件中的protected内添加变量: int n;//控制点数 const int N;//控制点数的上限 CPoint* a;//控制点存放的数组 double result[4][2]; 在lab4iew.cpp文件中的函数Clab4iew::OnDraw(CDC* pDC)下添加如下代码: int i,j; for(i=0;iFillSolidRect(a[i].x-2,a[i].y-2,4,4,RGB(255,55,255)); } pDC->MoveTo(a[0]);

三次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)包含有贝塞尔曲线。

竖曲线高程计算

4.3 某条道路变坡点桩号为K25+460.00,高程为780.72.m,i1=0.8%,i2=5%,竖曲线半径为5000m。(1)判断凸、凹性;(2)计算竖曲线要素;(3)计算竖曲线起点、K25+400.00、K25+460.00、K25+500.00、终点的设计高程。 解:ω=i2-i1=5%-0.8%=4.2%凹曲线 L=R?ω=5000×4.2%=210.00 m T=L/2=105.00 m E=T2/2R=1.10 m 竖曲线起点桩号:K25+460-T=K25+355.00 设计高程:780.72-105×0.8%=779.88 m K25+400: 横距:x=(K25+400)-(K25+355.00)=45m 竖距:h=x2/2R=0.20 m 切线高程:779.88+45×0.8%=780.2 m 设计高程:780.24+0.20=780.44 m K25+460:变坡点处 设计高程=变坡点高程+E=780.72+1.10=781.82 m 竖曲线终点桩号:K25+460+T=K25+565 设计高程:780.72+105×5%=785.97 m K25+500:两种方法 1、从竖曲线起点开始计算 横距:x=(K25+500)-(K25+355.00)=145m 竖距:h=x2/2R=2.10 m 切线高程(从竖曲线起点越过变坡点向前延伸):779.88+145×0.8%=781.04m 设计高程:781.04+2.10=783.14 m 2、从竖曲线终点开始计算 横距:x=(K25+565)-(K25+500)=65m 竖距:h=x2/2R=0.42 m 切线高程 (从竖曲线终点反向计算):785.97-65×5%=782.72m 或从变坡点计算:780.72+(105-65)×5%=782.72m 设计高程:782.72+0.42=783.14 m

计算机图形学 编程生成“三次贝塞尔”曲线

集美大学 计算机工程学院实验报告 课程名称计算机图形学教程 实验名称实验五、编程生成“三次贝塞尔”曲 线 实验类型设计型 学号 日期12月12日地点 成绩教师

一、实验目的: 一方面,让学生对自由曲线的生成算法有更深入的理解,特别是对于曲线的逼近,能够通过实验编程来验证书上所提供的算法思想:另一方面,在图形程序设计方法(如设计各种各样的图形)、绘图函数的使用以及C和C++语言编程环境、程序的调试和测试方面受到比较系统和严格的训练。 二、实验内容: 运用所学的三次贝塞尔曲线生成的算法,根据以下数据点[x, y]:[50, 100] [80, 230] [100, 270] [140, 160] [180, 50] [240, 65] [270, 120] [330, 230] [380, 230] [430, 150]计算出结果,并实现三段贝塞尔在屏幕上显示的功能 三、实验要求: (1)3段三次贝塞尔曲线在衔接点上要连续,曲线整体效果要光滑。 (2)整个图形轮廓要清晰,色彩要分明 四、实验环境: 1.PC,CPU:P4 2.0GHz以上,内存:512M,硬盘:40GB以上; 2.操作系统:Microsoft Windows 2000 /2003/XP; 3.软件:VC或JAVA等。 五、实验内容及完成情况: #include "graphics.h" #include "conio.h" #include "stdio.h" typedef struct { double x,y; } DPOINT; //定义结构体

class Bezier //定义Bezier类 { private: DPOINT* bP; int m_maxIndex; void drawFrame(); void drawCurve(); void drawCurve(int p0,int p1,int p2,int p3); public: Bezier(DPOINT* p,int len); //定义构造函数 void draw(); }; Bezier::Bezier(DPOINT* p,int len) //构造函数的实现{ this ->bP=p; m_maxIndex=len-1; } void Bezier::draw() //通过公有函数调用私有函数{

城市道路规划例题

1. 道路中线一转折处A ,转折角0 60=α,其旁有一重要建筑物,基础尺寸为m m 85?. 外边缘距A 点最短距离为25m,欲保留该建筑物,已知该路的设计车速为40h km /,道路宽度为24m,路拱横坡为2%,1.0=μ,问该弯道的可能最小半径值? 解:(1)按地形地物控制计算平曲线半径 )(422 24 525min m E =+ += 根据公式 )(7.2721 30sec 42 1 2 sec 0max min m E R =-= -= α 地形 取 )(300m R = (2)按满足设计车速、行车舒适和经济要求计算 根据公式 )(160) 02.01.0(1271600)(1272min m i V R =-?=-=μ 因为地形地物条件许可,且min min R R ≥地形,所以取 )(300m R = 该弯道的可能最小半径为300m 2. 某二级汽车专用公路上有一变坡点,桩号为,20010+k 切线标高为120.28m,两相邻路段 的纵坡为m R i i 5000%,3%,521=-==凸,试设计该变坡处的竖曲线。 解:(1)竖曲线长度 )(400m R L ==ω 切线长度 )(2002 m L T == 外距 )(422 m R T E == (2)求竖曲线的起点的终点桩号 起点桩号 0001020020010+=-+K K 终点桩号 4001020020010+=++K K (3)求各桩号的设计标高 竖曲线起点00010+K 切线标高 )(28.11005.020028.120m =?- 设计标高 )(28.110m 处10010+K 至起点距离 x =10100-10000=100m

三次贝塞尔曲线

练习45 三次贝塞尔曲线 一、练习具体要求 本例制作二维图形三次贝塞尔曲线。效果如图45-1所示。执行本例实例后,将创建一个绘有三次贝塞尔曲线的帧。本实例的知识点有:Graphics2D 类和Rectangular 类的应用,曲线绘制的方法。 二、程序及注释 (1)编程思路: java2中Graphics2D 中绘图的第一步是用setColor(),setFont(),setPointMode ,setXORMODE()之类的方法制定绘图属性,第二步生成一个shape 接口的对象,指定要画的形体,第三步是绘图。绘制形体是用三个Graphics2D 方法完成的。Chip()方法将绘图区缩小到指定形体与当前剪接区的交接部分,影响后面的绘图操作。Draw()方法用当前Stroke 绘制Shape 的外形。Fill()方法用当前Point 模式填充Shape 。CubicCurve2D 类生成三次曲线,他与其他曲线类不同,不是描述闭合形体,而是描述曲线。曲线类用贝塞尔曲线定义曲线上的实际点。生成曲线后,应用Draw()或Fill()方法,可以把起点和终点看成相连接的,从而得到闭合区域。 (2) 程序实现及注释: //ExitableJFrame.java import javax.swing.*; public class ExitableJFrame extends JFrame{ //构造函数 public ExitableJFrame(){ } //带窗口标题的构造函数 public ExitableJFrame(String title){ super(title); } //窗口的初始化 本例 知识 点 一句话讲解新学 知识编写Graphics2D 类 绘制图形使用CubicCurve2D 类 绘制图形已学 知识使用Graphics 类 画屏幕图像使用String 类管理字符串

竖曲线自动计算表格

竖曲线自动计算表格 篇一:Excel竖曲线计算 利用Excel表格进行全线线路竖曲线的统一计算 高速公路纵断面线型比较复杂,竖曲线数量比较多。由于相当多的竖曲线分段造成了设计高程计算的相对困难,为了方便直接根据里程桩号计算设计高程,遂编制此计算程序。程序原理: 1、根据设计图建立竖曲线参数库; 2、根据输入里程智能判断该里程位于何段竖曲线上; 3、根据得到的竖曲线分段标志调取该分段的曲线参数到计算表格中; 4、把各曲线参数带入公式进行竖曲线高程的计算; 5、对程序进<0 = J=0; M-P=0 = J=1 B: K<=D =B=-M ; KD = B=P 程序特色: 1、可以无限添加竖曲线,竖曲线数据库不限制竖曲线条数; 2、直接输入里程就可以计算设计高程,不需考虑该里程所处的竖曲线分段;

3、对计算公式进行保护,表格中不显示公式,不会导致公式被错误修改或恶意编辑。 程序的具体编制步骤: 1、新建Excel工作薄,对第一第二工作表重新命名为“参数库”和“计算程序”,根据设计图建立本标段线路竖曲线的参数库,需要以下条目: (1)、竖曲线编号; (2)、竖曲线的前后坡度(I1、I2)不需要把坡度转换为小数; (3)、竖曲线半径、切线长(不需要考虑是凸型或凹型);(4)、竖曲线交点里程、交点高程; (5)、竖曲线起点里程、终点里程(终点里程不是必要参数,只作为复核检测用);如图1所示: 图1 2、进行计算准备: (1)、根据输入里程判断该里程所处的曲线编号: 需要使用lookup函数,函数公式为“LOOKUP(A2,参数库!H3:H25,参数库!A3:A25)”。如图2所示: 里程为K15+631的桩号位于第11个编号的竖曲线处,可以参照图1 进行对照 (2)、在工作表“程序计算”中对应“参数库”相应的格式建立表格

道路工程(计算题)

计算题 1. 某城市道路相邻两段纵坡分别为1i =-3%,2i =2%,变坡点里K1+150,变坡点高程200.53m ,要使变坡点处得设计高程不小于201.80,则该竖曲线半径最小为多少(取到千米整数倍) 解:ω=2i -1i =2%-(-3%)=5% E+200.53≥201.80 ∴221+200.53201.808 R i -≥(i ),R ≥4064 取R=5000m 2. 城市道路相邻变坡分别为1i =3%,2i =-2%,变坡点里程为K1+150,变坡点高程为200.53m ,该竖曲线半径为5000m 。 (1) 计算竖曲线坡差ω并判断其竖曲线类型,计算竖曲线长,切线长,竖曲线外距 (2) 求竖曲线起点、终点桩号 (3) 计算K1+130桩号设计高程 解:(1)ω=2i -1i =-2%-3%=-5% L=R ω=5000×5%=250m T=L/2=250/2=125m E= 2 2T R =1.56m (2)QD=(K1+150)-125=K1+025.00 ZD=(K1+150)+125=K1+275.00 (3)K1+130装号设计标高:用变坡点里程为K1+150,故该桩号在变坡点前x=125-20=105m ,又因为切线长为125m,故该桩号在竖曲线起点和终点范围内, 2 2x y R ==1.10m ,H 切=200.53-20×3%=199.93m ,H 求=H 切-y=199.93-1.10=198.83m 3.某路线平面部分设计资料如下: JD1=K0+819.562 JD2=K1+270.427 ZH1=K0+619.150 ZH2=K1+095.155 HY1=K0+734.150 YH1=K0+849.351 HZ1=K0+964.351 (1) 试计算弯道1的切线长,曲线长,缓和曲线长及曲线中点桩号 (2) 试计算交点1和交点2间距 (3) 若交点1与交点2的曲线是属于反向曲线,且该道路设计速度v=80km/h ,曲线 1和曲线2之间的直线长度,该曲线间的直线长度是否满足直线最小长度的要求,为什么? 解:(1)切线长l 切=200.412m 曲线长l 曲=345.201m 缓和曲线长l 缓=115m QZ1=K0+791.751m

Bezier曲面算法及Bezier曲线

昆明理工大学理学院 信息与计算科学专业设计/综合性实验报告 年级:2015级姓名:学号:1105 指导教师:胡杰 实验课程名称:计算机图形学开课实验室:理学楼210 实验内容: 1.实验/作业题目: MFC绘图Bezier曲面算法及Bezier曲线 2.实验/作业课时:2个课时 3.问题描述(包括实验环境、实验内容的描述、完成实验要求的知识或技能):实验环境:(1)硬件:每人一台PC机 (2)软件:windows OS,VC++或以上版本。 实验内容的描述:Bezier曲面算法及Bezier曲线,Bezier去面啊绘制需要加入控制网格加以控制,先生成控制网格,再根据Bezier算法来绘制出曲面Bezier曲线根据控制点来绘制曲线。 完成实验要求的知识或技能: Bezier算法的迭代算法。 (2)Bezier曲线分为一次/二次/三次/多次贝塞尔曲线,之所以这么分是为了更好的理解其中的内涵。一次贝塞尔曲线(线性Bezier),实际上就是一条连接两点的直线段。在此使用了三次Bezier算法。 (3)曲线算法的几种主要算法以及各自的优缺点。 (4)基本的程序阅读能力,的基本使用技巧 4.基本要求(完成实验要达到的目标): Bezier曲线定义:给定n+1个控制顶点Pi(i=0~n) ,则Bezier曲线定

义为:P(t)=∑Bi,n(t)Pi u∈[0,1] 其中:Bi,n(t)称为基函数。Bi,n(t)=Ci nti (1-t)n-i Ci n=n!/(i!*(n-i)!) 二、Bezier曲线性质1、端点性质:a)P(0)=P0, P(1)=Pn, 即:曲线过二端点。b)P’(0)=n(P1-P0), P’(1)=n(Pn-Pn-1) 即:在二端点与控制多边形相切。2、凸包性:Bezier曲线完成落在控制多边形的凸包内。3、对称性:由Pi与Pn-i组成的曲线,位置一致,方向相反。4、包络性:Pn (t)=(1-t)Pn-1 (t)+tPn-1 (t) 5.程序结构(程序中的函数调用关系图) 6.算法描述或流程图:

第三次作业 三次Bezier曲线的绘制

第三次作业三次Bezier曲线的绘制一.解题思路: Bezier曲线是用N+1个顶点(控制点)所构成的N根折线来定义一根N阶曲线。本次作业中的三次Bezier曲线有4个顶点,设它们分别为P0,P1,P2,P3,那么对于曲线上各个点Pi(x,y)满足下列关系: x=x0*1-u)*(1-u)*(1-u)+x1 *3*u*(1-u)*(1-u)+x2 *3*u*u*(1-u)+x3 *t*t*t y=y0*(1-u)*(1-u)*(1-t)+y1*3*u*(1-u)*(1-u)+y2*3*u*u*(1-u) +y3 *u*u*u 所以只要确定控制点的坐标,该曲线可通过编程即可绘制出来。 本题取的初始控制点为:p0(-600,100)、p1(-300,400)、p2(300,600)、p3(600,100)。还可以通过输入不同的控制点画出不同的三次Bezier曲线。 程序中有绘制曲线,清空,清屏,退出四个按钮,其中点击绘制曲线按钮可根据控制点绘制出相应的曲线;点击清空按钮则可以将已绘制的曲线清除;点击清屏按钮可以将输入文本框中的数据清除,以方便输入新的数据;点击退出按钮则退出程序。 二.程序代码 Function f() Picture1.FontSize = 9 Picture1.Scale (-900, 1000)-(900, -1000) Picture1.Line (-800, 0)-(800, 0)

Picture1.Line (0, 800)-(0, -800) For i = -7 To 7 Picture1.Line (100 * i, 0)-(100 * i, 20) Picture1.CurrentX = i * 100 - 50: Picture1.CurrentY = -5: Picture1.Print i * 100 Next i For i = -7 To -1 Picture1.Line (0, 100 * i)-(20, 100 * i) Picture1.CurrentX = -100: Picture1.CurrentY = 100 * i + 20: Picture1.Print i * 100 Next i For i = 1 To 7 Picture1.Line (0, 100 * i)-(20, 100 * i) Picture1.CurrentX = -100: Picture1.CurrentY = 100 * i + 20: Picture1.Print i * 100 Next i End Function Private Sub Form_Load() Picture1.AutoRedraw = True Picture1.ScaleWidth = 900 Picture1.ScaleHeight = 900 f Text1.Text = -600: Text2.Text = 100: Text3.Text = -300: Text4.Text = 400 Text5.Text = 300: Text6.Text = 600: Text7.Text = 600: Text8.Text = 100 End Sub Private Sub command1_Click() x0 = Text1.Text: y0 = Text2.Text X1 = Text3.Text: Y1 = Text4.Text X2 = Text5.Text: Y2 = Text6.Text X3 = Text7.Text: Y3 = Text8.Text Picture1.FontSize = 18 Picture1.CurrentX = 800: Picture1.CurrentY = -5: Picture1.Print "X" Picture1.CurrentX = 10: Picture1.CurrentY = 810: Picture1.Print "Y" For t = 0 To 1 Step 0.001 x = x0 * (1 - t) * (1 - t) * (1 - t) + X1 * 3 * t * (1 - t) * (1 - t) + X2 * 3 * t * t * (1 - t) + X3 * t * t * t y = y0 * (1 - t) * (1 - t) * (1 - t) + Y1 * 3 * t * (1 - t) * (1 - t) + Y2 * 3 * t * t * (1 - t) + Y3 * t * t * t Picture1.CurrentX = x0 + 10: Picture1.CurrentY = y0 + 10: Picture1.Print "p0" Picture1.CurrentX = X1 + 10: Picture1.CurrentY = Y1 + 10: Picture1.Print "p1" Picture1.CurrentX = X2 + 10: Picture1.CurrentY = Y2 + 10: Picture1.Print "p2" Picture1.CurrentX = X3 + 10: Picture1.CurrentY = Y3 + 10: Picture1.Print "p3" Picture1.DrawWidth = 1 Picture1.Line (x0, y0)-(X1, Y1), vbBlue

纬地计算实例,你肯定用的着

首先,我是一个软件菜鸟,对于纬地道路也是听说了很久却不会用,待到真要使用的时候按照网上搜来的步骤总是运行不下去,苦苦钻研几天,也询问了一些同学,好在最终可以完成路线的平、纵、横断面布置及相关图表的输出。先将成果分析给有需求的人,赠人玫瑰,手留余香~ 纬地道路详细步骤: 1、首先在目的硬盘新建一个文件夹,按喜好为文件夹命名,比如说abc。 2、打开纬地系统,点击左上角“项目”→新建项目,在弹出的对话框填写新建项目名称abc,点击浏览为项目文件指定存放路径,找到所建文件夹abc的位置,并为新建项目文件命名,这里为abc.prj,点击确定,完成项目新建。 3、打开电子图(CAD .dwg文件类型)。 4、搞清楚各个图层的状态需要进行什么约束{(等高线╱约束线)、(地形点╱地形点的)}。 5、然后关闭图形,不进行修改 6、数模→数模组管理→新建数模→确定→关闭。 7、数模→三维数据读入→DWG 或 DXF 格式→找到刚打开的电子图读入将等高线设为约束线→地形点设为地形点→点击开始读入。 8、①数模→三角构网②数模→网格显示→显示所有网格→确定。 9、数模→数模组管理,弹出的对话框中选中显示的数模文件,点击保存数模,指定路径并命名为abc,文件后缀为(.dtm)→再次选中对话框中的文件,点击保存数模组,生成并保存.gtm文件,路径保持默认,即为文件夹abc,最后一次选中对话框中的文件,点击打开数模→关闭

10、打开地形图,设计→主线平面设计→找到自己要设计的路线起点→点击后→点插入→是→对除起终点之外的其他交点进行“拖动R”来设置平曲线→计算绘图→点存盘→是,得到“.jd”文件,并根据提示将交点文件自动转化为“.pm”文件。 11、项目→设计向导→下一步(多次重复下一步)自动计算超高加宽→完成(根据提示自动建立:路幅宽度变化数据文件(*.wid)、超高过渡数据文件(*.sup)、设计参数控制文件(*.ctr)、桩号序列文件(*.sta)等数据文件。 12、数模-→数模应用→纵断面插值,弹出对话框,勾选插值控制选项,点击开始插值,生成纵断面地面线文件(*.dmx)以及地面高程文件(*.zmx)。 13、数模-→数模应用→横断面插值,弹出对话框,选取绘制三维地面线及输出组数(其他默认),点击开始插值,生成横断面地面线文件(*.hdm)。) 14、CAD 新建→选择最后一个文件夹→打开→打开acadiso. 文件(样板文件)。 15、设计→纵断面设计→计算显示→确定。 16、设计→纵断面设计→选点(此时可以打开cad的栅格显示,在最下边)→在图上选第一个高程点点(左边端点起),再接着点击插入,插入几个变坡点,最后一个右边端点→点击实时修改对纵坡顶修改(将竖曲线调整到合理)→存盘→计算显示→删除纵断面图。 17、设计→路基设计计算→点击“... ”→保存→搜索全线→确定→计算 18、设计→横断面设绘图→选中土方数据文件→点击“... ”→保存→绘图控制→(选中记录三维数据、插入图框、绘出路槽图)→计算绘图→保存,在CAD合适位置完成横断面设计图的输出。 19、点击“表格“按需要输出各种表格。

Bezier曲线的生成算法参考代码

实现Bezier曲线的生成算法 实验步骤 (一)生成绘图应用程序的框架(如下图) 具体实现见第一次实验,过程不再详细说明。 (二)在应用程序中增加菜单 完成相关菜单的设计,具体的效果如下图所示,并设置好相关菜单消息的映射,具体的实现在前面的实验中介绍过,再此不在详细说明。

(三)在绘图函数中添加代码 通过以上步骤,得到了与菜单对应的消息映射,就可以在函数中添加代码绘制图形了。 1、利用Bezier曲线的生成算法实现二次Bezier曲线的生成(算法的详细原理见教材)。void CBezierView::OnBezier2() { // TODO: Add your command handler code here CDC*pDC=GetDC();//得到绘图类指针 RedrawWindow();//重绘窗口 CPen bluepen(PS_SOLID,2,RGB(0,0,255));//创建画实线、线宽为2的蓝色画笔 CPen *old=pDC->SelectObject(&bluepen); float x0=100,y0=100,x1=200,y1=50,x2=150,y2=250; float i,x,y,dt,t,n=30.0; dt=1/n; for(i=0;i<=n;i++) { t=i*dt; x=x0*(1-t)*(1-t)+x1*2*t*(1-t)+x2*t*t; y=y0*(1-t)*(1-t)+y1*2*t*(1-t)+y2*t*t; if(i==0)pDC->MoveTo(x,y); pDC->LineTo(x,y);

pDC->MoveTo(x0,y0); pDC->LineTo(x1,y1); pDC->LineTo(x2,y2); pDC->SelectObject(old); ReleaseDC(pDC); } 由以上代码绘出的图形如下: 2、利用Bezier曲线的生成算法实现二次Bezier曲线的生成(算法的详细原理见教材)。。void CBezierView::OnBezier3() { // TODO: Add your command handler code here CDC*pDC=GetDC();//得到绘图类指针 RedrawWindow();//重绘窗口 CPen redpen(PS_SOLID,2,RGB(255,0,0));//创建画实线、线宽为2的红色画笔 CPen *old=pDC->SelectObject(&redpen); float x0=50,y0=50,x1=150,y1=150,x2=300,y2=130,x3=350,y3=50; float i,x,y,dt,t,n=30.0; dt=1/n; for(i=0;i<=n;i++)

竖曲线计算(优.选)

竖曲线计算 竖曲线定义:纵断面上两个坡段的转折处,为了便于行车用一段曲线缓和,这条连接两个纵坡线的曲线称为竖曲线。 竖曲线作用: 1)以平缓曲线取代折线可消除汽车在变坡点处冲击, 2)确保道路纵向行车视距; 3)将竖曲线与平曲线恰当地组合,有利于路面排水和改善行车的视线诱导以及舒适感。 变坡点:在道路纵断面上两个相邻纵坡线的交点。 竖曲线分类:竖曲线常采用圆曲线,可以分为凸形和凹形两种。 凹凸竖曲线判断:如上图,当前坡段坡度大于后坡段坡度时为凸型曲线;当前坡段坡度小于后坡段坡度时为凹曲线;坡度:通常把坡面的垂直高度h和水平宽度l的比叫做坡度。(注:判断是凹凸竖曲线时,坡度含正负号,例如,前坡段坡度为-2.3%,后坡段坡度为-1.4%,因为-2.3%<-1.4%,故此竖曲线为凹形竖曲线,我们习惯把上坡段用“+”表示,下坡段用“-”表示) 道路纵断面线形常采用直线、竖曲线两种 线形,二者是纵断面线形的基本要素。竖曲线 技术指标主要有竖曲线半径和竖曲线长度。凸 形的竖曲线的视距条件较差,应选择适当的半 径以保证安全行车的需要。凹形的竖曲线,视 距一般能得到保证,但由于在离心力作用下汽 车要产生增重,因此应选择适当的半径来控制 离心力不要过大,以保证行车的平顺和舒适。 竖曲线基本要素: 竖曲线长:L 切线长:T 外距:E 半径:R 竖曲线起终点桩号计算: 竖曲线起点桩号:变坡点桩号-T

竖曲线终点桩号:变坡点桩号+T 如右图所示,两个相邻的纵坡为i1和i2,竖曲线半径为R,则测设元素为: 曲线长L=R ×α 由于竖曲线的转角α很小,故可以认为: α=i1-i2;所以L=R (i1-i2) 切线长T=Rtan 2 α 因为α很小,tan 2α=2α;所以可以推出: T=R ·2α=2L =21R (i1-i2) 又因为α很小,可以认为:DF=E;AF=T 根据三角形ACO与三角形ACF相似,根据相似三角形“边角边”定理得出: R:T=T:2E; 于是如上图外距E=R T 22 , 同理可导出竖曲线上任意一点P距切线纵距的计算公式:y =R x 22 式中:x —竖曲线上任意一点P 到竖曲线起点或终点的水平距离 Y —值在凹形竖曲线中为正号,在凸形竖曲线中为负号。 故竖曲线中任意一点的高程: H=O H ±x ·i R x 22 式中:O H —竖曲线起点或终点的高程(O H =变坡点的高程±T ·i ,) i —纵坡的坡度 x —竖曲线上任意一点P 到竖曲线起点或终点的水平距离 例题:竖曲线半径R=3000m,相邻坡段坡度为i1=+3.1%,i2=+1.1%,变坡点桩号为K16+770,其高程为396.67m ,若曲线上每10米设置一个桩,计算竖曲线上整10m 桩点的高程。 解:(1)计算竖曲线测设元素 根据如上公式:L =R ×α= R (i1-i2)=3000×(3.1%-1.1%)=60m T=2L =2 60=30m ;E=R T 22=30002302 =0.15 (2)计算竖曲线起、终点桩号和高程

C语言代码,Bezier三次曲线

Bezier三次曲线实验报告 一:实验目的 用C语言实现Bezier三次曲线原理的划线 二:实验环境 VC6.0 三:实验人数 一人 四:实验内容 Bezier曲线生成的原理和步骤都在程序上给了注释 五:实验步骤 #include #include #include //该方法为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) { 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); 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");//初始化图形系统 cleardevice();//清屏 setcolor(BLUE);//设置前景色为蓝色 moveto(p[0][0],p[0][1]);//把坐标移动到初始化定义的二维数组坐标的第一个坐标for (i=1;i

二次bezier曲线

#include #include #include #include #define ESC 0x1b void Initialize(void) { int graphdriver; int graphmode; int errorcode; graphdriver=DETECT; initgraph(&graphdriver,&graphmode,"C:\Program Files\WINYES\TCPP30H"); errorcode=graphresult(); if(errorcode != grOk) { printf("Graphics System Error:%s\n",grapherrormsg(errorcode)); exit(1); } } void bezier_2_ins(long q[][2]){ const NO=3; const KT=5; float p[3][2]; long pk[129][2],pt[129][2]; int i,k,m=NO-1; double ll,l1,l2; for(i=0;i

三次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 Integer PictDraw.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 40

PictDraw.Line (k, -5)-(k, 0): PictDraw.CurrentX = k - 20: PictDraw.CurrentY = 5: PictDraw.Print k Next k For k = (-280) To -40 Step 40 PictDraw.Line (5, k)-(0, k): PictDraw.CurrentX = -40: PictDraw.CurrentY = k - 10: PictDraw.Print (-1) * k Next k For k = (40) To 280 Step 40 PictDraw.Line (5, k)-(0, k): PictDraw.CurrentX = -40: PictDraw.CurrentY = k - 10: PictDraw.Print (-1) * k Next k End Function Private Sub Form_Load() PictDraw.AutoRedraw = True PictDraw.ScaleWidth = 800 PictDraw.ScaleHeight = 600 Text1.Text = -300: Text2.Text = -250: Text3.Text = 300: Text4.Text = -250 Text5.Text = -300: Text6.Text = 250: Text7.Text = 300: Text8.Text = 250 '作为初始值,便于测试 drawcs End Sub Private Sub cmdCancle_Click() PictDraw.Cls drawcs '清除屏幕后,重建坐标系 End Sub Private Sub delet_Click() '此模块为清除输入框中的值 Text1.Text = "" Text2.Text = "" Text3.Text = "" Text4.Text = "" Text5.Text = "" Text6.Text = "" Text7.Text = ""

相关主题
文本预览
相关文档 最新文档