C语言实现生成贝塞尔曲线(代码)
贝塞尔曲线basic代码

以上是一个基本的贝塞尔曲线实现的BASIC代码示例。
该代码使用递归方法计算贝塞尔曲线上的点坐标,并通过循环依次输出点的坐标。
在代码中,首先定义了一个计算组合数的函数Combinations,用于计算贝塞尔曲线的控制点权重。
然后,定义了一个计算贝塞尔曲线上点坐标的函数BezierCurvePoint,该函数根据控制点的数量和权重计算给定参数t对应的点坐标。
在主程序中,首先设置了控制点的坐标,然后定义了步长stepSize和参数t的初始值为0。
接下来,通过循环不断增加t的值,调用BezierCurvePoint函数计算贝塞尔曲线上的点坐标,并将结果输出。
请注意,以上代码仅为基本示例,可能需要根据具体需求进行修改和适配。
C#实现贝塞尔曲线的方法

C#实现贝塞尔曲线的⽅法本⽂实例为⼤家分享了C#实现贝塞尔曲线的具体代码,供⼤家参考,具体内容如下话不多直接上代码public Transform[] controlPoints; //曲线的控制点,最少三个,起点,弧度点,终点public GameObject codeGameObject; //要动的物体private int _segmentNum = 50; //运动物体过程分的段数private int numIndex = 1;void Start(){moveGameObject(2);}void moveGameObject(float time){numIndex = 1;InvokeRepeating("setInterval", 0, time/50);}void setInterval(){int nodeIndex = 0;float t = numIndex / (float)_segmentNum;Vector3 pixel = CalculateCubicBezierPoint(t, controlPoints[nodeIndex].position,controlPoints[nodeIndex + 1].position, controlPoints[nodeIndex + 2].position);codeGameObject.gameObject.transform.position= pixel;numIndex++;if(numIndex> _segmentNum){CancelInvoke("setInterval");}}Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2){float u = 1 - t;float tt = t * t;float uu = u * u;Vector3 p = uu * p0;p += 2 * u * t * p1;p += tt * p2;return p;}项⽬⾥的截图:运⾏就可以看到球在三个⽅块之间移动的曲线了第⼆种⽅案使⽤DOTweenPath/*** @brief 播放道具飞⾏动画** @param prop 道具* @param sendPos 起始点* @param endP 终点* @param fHeight 贝塞尔曲线中间点的⾼度(控制曲线)** @return 飞⾏动画时间*/public float PlaySendFlyAnim(GameObject prop, Vector3 sendPos, Vector3 endP, float fHeight, float time) {float fTime = 0.0f;if (prop == null){return fTime;}Vector3 startP = sendPos;prop.transform.position = startP;float x = Mathf.Min(startP.x, endP.x) + Mathf.Abs(startP.x - endP.x) / 2f;float y = Mathf.Min(startP.y, endP.y) + Mathf.Abs(startP.y - endP.y) / 2f;float z = startP.z;Vector3 midP = new Vector3(x, y, z);double length = Math.Sqrt(Math.Pow(sendPos.x - midP.x, 2) + Math.Pow(sendPos.y - midP.y, 2));//midP.x = fHeight / (float)length * (sendPos.x - midP.x) + midP.x;//midP.y = fHeight / (float)length * (sendPos.y - midP.y) + midP.y;int rangeRadomNum = UnityEngine.Random.Range(0, 2);if(rangeRadomNum == 1){midP.x = fHeight / (float)length * (endP.x - midP.x) + midP.x;midP.y = endP.y;}else{midP.y = fHeight / (float)length * (endP.y - midP.y) + midP.y;midP.x = endP.x;}//fTime = 2.0f;fTime = time;List<Vector3> arrRecPos = new List<Vector3>();arrRecPos.Add(startP);arrRecPos.Add(midP);arrRecPos.Add(endP);prop.transform.DOPath(arrRecPos.ToArray(), fTime, PathType.CatmullRom, PathMode.Full3D).SetEase(Ease.Linear); return fTime;}/// <param name="sendPos"> 玩家头像位置</param>/// <param name="endP">筛⼦停⽌位置</param>/// <param name="i">筛⼦⼤⼩</param>/// <param name="radian">弧度</param>/// <param name="time">时间</param>/// <returns></returns>public float PlayAddFriendAnim(Vector3 sendPos, Vector3 endP,int i,int radian = 0, float time = 1.5f){GameObject shaizi = this.transform.Find("shaizi_anmi4_0").gameObject;shaizi.GetComponent<Animator>().enabled = true;SpriteRenderer _shaizhiV = shaizi.GetComponent<SpriteRenderer>();float fTime = PlaySendFlyAnim(shaizi, sendPos, endP, radian, time);DOTween.Sequence().AppendInterval(fTime).AppendCallback(() =>{if (shaizi != null){shaizi.GetComponent<Animator>().enabled = false;_shaizhiV.sprite = shaiziData[i-1];StartCoroutine(Destroyshaizi(shaizi));}});return fTime;}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
Bezier曲线原理及实现代码(c++)

Bezier曲线原理及实现代码(c++)Bezier曲线原理及实现代码(c++)2009-06-30 18:50:09| 分类: |字号⼀、原理:贝塞尔曲线于,由⼯程师(Pierre Bézier)所⼴泛发表,他运⽤贝塞尔曲线来为的主体进⾏设计。
贝塞尔曲线最初由于运⽤开发,以的⽅法求出贝塞尔曲线。
线性贝塞尔曲线给定点 P0、P1,线性贝塞尔曲线只是⼀条两点之间的。
这条线由下式给出:且其等同于。
⼆次⽅贝塞尔曲线的路径由给定点 P0、P1、P2的函数 B(t) 追踪:。
字型就运⽤了以组成的⼆次贝塞尔曲线。
P0、P1、P2、P3四个点在平⾯或在三维空间中定义了三次⽅贝塞尔曲线。
曲线起始于 P0⾛向 P1,并从 P2的⽅向来到 P3。
⼀般不会经过 P1或 P2;这两个点只是在那⾥提供⽅向资讯。
P0和 P1之间的间距,决定了曲线在转⽽趋进 P3之前,⾛向 P2⽅向的“长度有多长”。
形式为:。
现代的成象系统,如、和,运⽤了以组成的三次贝塞尔曲线,⽤来描绘曲线轮廓。
P0、P1、…、P n,其贝塞尔曲线即。
例如:。
如上公式可如下递归表达:⽤表⽰由点 P0、P1、…、P n所决定的贝塞尔曲线。
则⽤平常话来说,阶贝塞尔曲线之间的插值。
⼀些关于参数曲线的术语,有即多项式,定义 00 = 1。
点 P i称作贝塞尔曲线的控制点。
以带有的贝塞尔点连接⽽成,起始于 P0并以 P n终⽌,称作贝塞尔多边形(或控制多边形)。
贝塞尔多边形的(convex hull)包含有贝塞尔曲线。
线性贝塞尔曲线函数中的t会经过由 P0⾄P1的 B(t) 所描述的曲线。
例如当t=0.25时,B(t) 即⼀条由点 P0⾄ P1路径的四分之⼀处。
就像由0 ⾄ 1 的连续t,B(t) 描述⼀条由 P0⾄ P1的直线。
为建构⼆次贝塞尔曲线,可以中介点 Q0和 Q1作为由 0 ⾄ 1 的t:由 P0⾄ P1的连续点 Q0,描述⼀条线性贝塞尔曲线。
贝塞尔曲线 递归画法 vc++

贝塞尔曲线递归画法 vc++贝塞尔曲线是一种平滑曲线,它的形状由一系列的控制点决定。
在计算机图形学中,贝塞尔曲线通常用于绘制平滑的曲线和曲面。
贝塞尔曲线的递归画法是通过递归算法来绘制贝塞尔曲线的一种方法,它可以在绘制曲线时实现更加灵活和精细的控制。
在VC++中,我们可以通过递归算法来实现贝塞尔曲线的绘制。
首先,我们需要了解贝塞尔曲线的数学原理和算法。
贝塞尔曲线由一系列的控制点以及一个参数t决定,通过调整参数t的值,我们可以得到曲线上不同位置的点。
贝塞尔曲线的递归画法可以通过分割曲线的方式来实现。
我们可以将一条贝塞尔曲线分割成两部分,然后再分别递归地绘制每一部分,直到曲线足够平滑为止。
在VC++中,我们可以使用C++语言来实现贝塞尔曲线的递归画法。
首先,我们需要定义一个表示2D点的结构体,用来存储曲线上的点的坐标。
然后,我们需要实现一个递归绘制函数,这个函数接受一组控制点和绘制的精度作为参数,然后递归地绘制曲线直到达到指定的精度为止。
下面是一个简单的示例代码,用来实现贝塞尔曲线的递归画法:```cpp#include <iostream>#include <vector>//定义一个表示2D点的结构体struct Point{float x;float y;};//定义一个递归绘制贝塞尔曲线的函数void drawBezierCurve(std::vector<Point>& controlPoints, float t, int depth){if (depth == 0){//绘制曲线上的点//这里可以使用画图的API来实现}else{std::vector<Point> newPoints;for (int i = 0; i < controlPoints.size() - 1; i++){//根据贝塞尔曲线的递推公式计算新的控制点Point newPoint;newPoint.x = controlPoints[i].x + t * (controlPoints[i + 1].x - controlPoints[i].x);newPoint.y = controlPoints[i].y + t * (controlPoints[i + 1].y - controlPoints[i].y);newPoints.push_back(newPoint);}//递归调用自己drawBezierCurve(newPoints, t, depth - 1);}}int main(){//定义一组控制点std::vector<Point> controlPoints = { {100, 100}, {200, 300}, {400, 200}, {500, 400} };//设置绘制精度int depth = 5;//设置参数t的步长float step = 0.01;//循环调用绘制函数绘制曲线for (float t = 0; t <= 1; t += step){drawBezierCurve(controlPoints, t, depth);}return 0;}```在上面的示例代码中,我们定义了一个表示2D点的结构体Point,然后实现了一个递归绘制贝塞尔曲线的函数drawBezierCurve。
绘制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曲线,点击右键表示确定,移动节点改变形状。
三次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 会经过由 P0至P1的 B(t) 所描述的曲线。
例如当t=0.25时.B(t) 即一条由点 P0至 P1路径的四分之一处。
就像由 0 至 1 的连续t.B(t) 描述一条由 P0至 P1的直线。
Bezier 曲线绘制实验文档

Bezier 曲线绘制实验文档
2005.10
一、实验目的
编程实现中点分割法绘制Bezier曲线。
二、实现功能
实验程序通过OpenGL实现,可以通过鼠标单击左键绘制Bezier控制点,单击右键结束控制点绘制并显示Bezier曲线。
单击控制点可以选择控制点,这个时候可以通过拖拽移动控制点,同时Bezier曲线的变化也将反应;按键盘上的d可以删除控制点,i可以在这个控制点和下一个控制点的中点位置增加一个新的控制点。
按c可以清除所有内容以重新绘制。
通过上下键可以增加或者缩小阈值。
三、程序实现
1、Bezier曲线绘制算法
函数calBezier通过中点分割法绘制Bezier曲线。
利用递归的方法实现,calPiece是递归子函数。
算法伪码描述如下:
考虑到最后需要求出2n-1个控制点,因此预先将n个控制点间隔排列放到大小为2n-1的数组中。
之后对于每一层次的求解,将两个控制点的中点求出来的结果放到这两个控制点所在数组序号中间的位置即可。
如下表所示(4个控制点)。
表中红色的内容为每一个循环中需要计算的内容,使用其上一行中序号在前一位和后一位的控制点的中点。
最后结果前4项就是第一段Bezier曲线的控制点,后4项就是第二段Bezier曲线的控制点。
3、OpenGL函数
四、实验结果
在VS2003+WinXP平台下实现了程序。
C语言代码,Bezier三次曲线

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>请大家安装一个文件
VC实现贝塞尔曲线绘制

VC实现贝塞尔曲线绘制摘要:本文主要通过对Bezier曲线的几何图形的进一步理解,探讨其具体的控制方法,结合具体绘制实际分析理论描述对控制点计算理解的偏差,统一了认识;结合曲线绘制函数PolyBezier()具体的要求,实现VC环境下简单的曲线绘制方法研究。
关键词:贝塞尔曲线;PolyBezier;曲线连续性1贝塞尔曲线描述贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度。
所以本函数的顶点数组的记录方式是:控制点+顶点+控制点+控制点+顶点+控制点+……。
所以两个顶点之间的曲线是由两个顶点以及两个顶点之间的控制点来决定的。
一条贝塞尔样条由4个定义点定义:两个端点和两个控制点。
2曲线的绘制方法2.1PolyBezier函数PolyBezier函数用于画贝赛尔样条曲线,原型:BOOL PolyBezier (HDC,hdc,CONST POINT *lppt,DWORD cPoints);参数:hdc:指定的设备环境句柄。
Lppt:POINT结构数组的指针,包括了样条端点和控制点的坐标、其顺序是起点的坐标、起点的控制点的坐标、终点的控制点的坐标和终点的坐标。
cPoints:指明数组中的点的个数。
本文中绘制曲线主要用到这个函数。
2.2一阶连续性图1所示为一段Bezier曲线经过p0、p1两个端点,要绘制经过它们的曲线需要再确定k1、K2两个控制点,这条曲线最终是由p0、k1、k2、p1四个点决定。
图2为经过p0、p1(p2)、p3的一段连续曲线,可以看出,它是由p0-p1及p2-p3两段曲线组成,连续的贝塞尔曲线会把前一个终止点当作起始点:即p1=p2。
要绘制如图2所示曲线,关键在于确定k0、k1、k2、k3四个控制点方法,一般是根据两段曲线连续(即一阶连续性:两个相邻曲线段在交点处有相同的一阶导数)条件来得出。
总的来说,就是k0p0 连线即为曲线在p0处切线,k1p1连线为p1处切线,k24p2为p2处切线,k3p3为p3处切线,两段曲线连续必然要求k1p1与k2p2在一条线上。
在opencv下绘制Bezier 贝赛尔 曲线

在opencv下绘制Bezier 贝赛尔曲线2008-11-01 01:31因需要研究了一下贝赛尔曲线,并在opencv下实现. 可以修改控制点,连接多条曲线,修改曲线精度。
// TrainingTools.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include <iostream>#include <string.h>#include <cxcore.h>#include <cv.h>#include <highgui.h>#include <fstream>using namespace std;const int WW_MAX_MARK_COUNT = 40; //最大40个控制点int mark_count =4;int conner_pt_index =-1;CvPoint3D32f Control_pts[WW_MAX_MARK_COUNT];IplImage *image = 0 ; //原始图像bool is_showControlLines = true;// 两个向量相加,p=p+qCvPoint3D32f pointAdd(CvPoint3D32f p, CvPoint3D32f q) ...{p.x += q.x; p.y += q.y; p.z += q.z;return p;}// 向量和标量相乘p=c*pCvPoint3D32f pointTimes(float c, CvPoint3D32f p) ...{p.x *= c; p.y *= c; p.z *= c;return p;}// 计算贝塞尔方程的值// 变量u的范围在0-1之间//P1*t^3 + P2*3*t^2*(1-t) + P3*3*t*(1-t)^2 + P4*(1-t)^3 = Pnew CvPoint3D32f Bernstein(float u, CvPoint3D32f *p) ...{CvPoint3D32f a, b, c, d, r;a = pointTimes(pow(u,3), p[0]);b = pointTimes(3*pow(u,2)*(1-u), p[1]);c = pointTimes(3*u*pow((1-u),2), p[2]);d = pointTimes(pow((1-u),3), p[3]);r = pointAdd(pointAdd(a, b), pointAdd(c, d));return r;}//画控制线void DrawControlLine(CvPoint3D32f *p) ...{CvPoint pc[4];for(int i=0;i<4;i++)...{pc[i].x = (int)p[i].x;pc[i].y = (int)p[i].y;}cvLine(image,pc[0],pc[1],CV_RGB(0,0,255),1,CV_AA,0);cvLine(image,pc[2],pc[3],CV_RGB(0,0,255),1,CV_AA,0);}//得到最近Control_pts的indexint getNearPointIndex(CvPoint mouse_pt)...{CvPoint pt;for(int i =0; i<mark_count;i++)...{pt.x= mouse_pt.x - Control_pts[i].x;pt.y= mouse_pt.y - Control_pts[i].y;float distance = sqrt ((float)( pt.x*pt.x + pt.y*pt.y )); if(distance<10) return i;}return -1;}void on_mouse( int event, int x, int y, int flags, void *param ) ...{if( event == CV_EVENT_LBUTTONDOWN )...{CvPoint pt = cvPoint(x,y);//cout<<x<<","<<y<<endl;if(conner_pt_index >-1)conner_pt_index = -1;else...{conner_pt_index = getNearPointIndex(pt);//添加新的控制点if(conner_pt_index==-1)...{if(mark_count<=(WW_MAX_MARK_COUNT-1))...{Control_pts[mark_count].x = pt.x;Control_pts[mark_count].y = pt.y;Control_pts[mark_count].z = 0;mark_count++;}}}}else if ( event == CV_EVENT_MOUSEMOVE ) //修改控制点坐标...{if(conner_pt_index >-1)...{Control_pts[conner_pt_index].x = x;Control_pts[conner_pt_index].y = y;}}};int main(int argc, char* argv[])...{CvSize image_sz = cvSize( 1000,1000);image = cvCreateImage(image_sz , 8, 3 );cvNamedWindow("Win",0);cvSetMouseCallback( "Win", on_mouse, 0 );cvResizeWindow("Win",500,500);cout<<"============== Bezier curve DEMO =============="<<endl; cout<<" "<<endl;cout<<"e mouse to click control point (red) to select a control point"<<endl;cout<<"e mouse to modify control point"<<endl;cout<<"3.click mouse on somewhere to add a control point,add three points for add a new curve"<<endl;cout<<"e 'W','S' to add precision or reduce precision."<<endl; cout<<"5.press 'Z' to show control points."<<endl;cout<<"===press ESC to exit==="<<endl;//初始化四个控制点Control_pts[0].x = 200;Control_pts[0].y = 200;Control_pts[0].z = 0;Control_pts[1].x = 300;Control_pts[1].y = 500;Control_pts[1].z = 0;Control_pts[2].x = 400;Control_pts[2].y = 560;Control_pts[2].z = 0;Control_pts[3].x = 500;Control_pts[3].y = 100;Control_pts[3].z = 0;int divs = 50; //控制精细度for(;;)...{CvPoint pt_now,pt_pre;cvZero(image);//绘制控制点if(is_showControlLines)...{for(int i =0;i<mark_count;i++)...{CvPoint ptc;ptc.x = (int) Control_pts[i].x;ptc.y = (int) Control_pts[i].y;cvCircle( image, ptc, 4, CV_RGB(255,0,0), 1,CV_AA, 0);}}//绘制Bezier曲线CvPoint3D32f *pControls = Control_pts;for(int j=0;j<mark_count-3;j+=3)...{for (int i=0;i<=divs;i++)...{float u = (float)i/divs;CvPoint3D32f newPt =Bernstein(u,pControls);pt_now.x = (int)newPt.x;pt_now.y = (int)newPt.y;if(i>0) cvLine(image,pt_now,pt_pre,CV_RGB(230,255, 0),2,CV_AA, 0 );pt_pre = pt_now;}//画控制线if(is_showControlLines)DrawControlLine(pControls);pControls+=3;}cvShowImage("Win",image);int keyCode = cvWaitKey(20);if (keyCode==27) break;if(keyCode=='w'||keyCode=='W') divs+=2;if(keyCode=='s'||keyCode=='S') divs-=2;if(keyCode=='z'||keyCode=='Z') is_showControlLines =is_showControlLines^1;//cout<<"precision : "<<divs<<endl;}return 0;}。
三次贝塞尔曲线生成C++代码

三次贝塞尔曲线⽣成C++代码void createCurve(point2D *originPoint,int originCount,std::vector<point2D> &curvePoint){//控制点收缩系数,经调试0.6较好,CvPoint是opencv的,可⾃⾏定义结构体(x,y)float scale = 0.6;point2D midpoints[originCount];//⽣成中点for(int i = 0 ;i < originCount ; i++){int nexti = (i + 1) % originCount;midpoints[i].x = (originPoint[i].x + originPoint[nexti].x)/2.0;midpoints[i].y = (originPoint[i].y + originPoint[nexti].y)/2.0;}//平移中点CvPoint extrapoints[2 * originCount];for(int i = 0 ;i < originCount ; i++){int nexti = (i + 1) % originCount;int backi = (i + originCount - 1) % originCount;CvPoint midinmid;midinmid.x = (midpoints[i].x + midpoints[backi].x)/2.0;midinmid.y = (midpoints[i].y + midpoints[backi].y)/2.0;int offsetx = originPoint[i].x - midinmid.x;int offsety = originPoint[i].y - midinmid.y;int extraindex = 2 * i;extrapoints[extraindex].x = midpoints[backi].x + offsetx;extrapoints[extraindex].y = midpoints[backi].y + offsety;//朝 originPoint[i]⽅向收缩int addx = (extrapoints[extraindex].x - originPoint[i].x) * scale;int addy = (extrapoints[extraindex].y - originPoint[i].y) * scale;extrapoints[extraindex].x = originPoint[i].x + addx;extrapoints[extraindex].y = originPoint[i].y + addy;int extranexti = (extraindex + 1)%(2 * originCount);extrapoints[extranexti].x = midpoints[i].x + offsetx;extrapoints[extranexti].y = midpoints[i].y + offsety;//朝 originPoint[i]⽅向收缩addx = (extrapoints[extranexti].x - originPoint[i].x) * scale;addy = (extrapoints[extranexti].y - originPoint[i].y) * scale;extrapoints[extranexti].x = originPoint[i].x + addx;extrapoints[extranexti].y = originPoint[i].y + addy;}CvPoint controlPoint[4];//⽣成4控制点,产⽣贝塞尔曲线for(int i = 0 ;i < originCount ; i++){controlPoint[0] = originPoint[i];int extraindex = 2 * i;controlPoint[1] = extrapoints[extraindex + 1];int extranexti = (extraindex + 2) % (2 * originCount);controlPoint[2] = extrapoints[extranexti];int nexti = (i + 1) % originCount;controlPoint[3] = originPoint[nexti];float u = 1;while(u >= 0){int px = bezier3funcX(u,controlPoint);int py = bezier3funcY(u,controlPoint);//u的步长决定曲线的疏密u -= 0.005;CvPoint tempP = cvPoint(px,py);//存⼊曲线点curvePoint.push_back(tempP);}}}//三次贝塞尔曲线double CurvePlot::bezier3funcX(double _t,point2D *controlP){ // cal x coordouble part0 = controlP[0].x * _t * _t * _t;double part1 = 3 * controlP[1].x * _t * _t * (1 - _t);double part2 = 3 * controlP[2].x * _t * (1 - _t) * (1 - _t);double part3 = controlP[3].x * (1 - _t) * (1 - _t) * (1 - _t);return part0 + part1 + part2 + part3;}double CurvePlot::bezier3funcY(double _t,point2D *controlP){ // cal y coordouble part0 = controlP[0].y * _t * _t * _t;double part1 = 3 * controlP[1].y * _t * _t * (1 - _t);double part2 = 3 * controlP[2].y * _t * (1 - _t) * (1 - _t);double part3 = controlP[3].y * (1 - _t) * (1 - _t) * (1 - _t);return part0 + part1 + part2 + part3;}double CurvePlot::cal_angle(double _t, point2D *controlP){ // cal dy / dx angledouble _dx_1= 3 * controlP[0].x * _t * _t;double _dx_2= 3 * controlP[1].x * (_t * 2 - 3 * _t * _t);double _dx_3= 3 * controlP[2].x * (1 - 4 * _t + 3 * _t * _t);double _dx_4= - 3 * controlP[3].x * (1 - _t) * (1 - _t);double _dy_1= 3 * controlP[0].y * _t * _t;double _dy_2= 3 * controlP[1].y * (_t * 2 - 3 * _t * _t);double _dy_3= 3 * controlP[2].y * (1 - 4 * _t + 3 * _t * _t);double _dy_4= - 3 * controlP[3].y * (1 - _t) * (1 - _t);return std::atan2(_dy_1 + _dy_2 + _dy_3 + _dy_4 , _dx_1 + _dx_2 + _dx_3 + _dx_4); }cal_angle 求分辨率为 _resolution 的时候每⼀点的切线⽅向。
c实现贝塞尔曲线插补

c实现贝塞尔曲线插补C语言中可以通过控制点的位置来实现贝塞尔曲线的插补。
以下是一个简单的C程序示例:```c#include <stdio.h>struct Point {float x;float y;};struct Point getBezierPoint(struct Point* controlPoints, int n, float t) {if (n == 1) {return controlPoints[0];}struct Point* tempPoints = (struct Point*)malloc((n - 1) *sizeof(struct Point));for (int i = 0; i < n - 1; i++) {tempPoints[i].x = controlPoints[i].x + t * (controlPoints[i + 1].x - controlPoints[i].x);tempPoints[i].y = controlPoints[i].y + t * (controlPoints[i + 1].y - controlPoints[i].y);}return getBezierPoint(tempPoints, n - 1, t);}int main() {struct Point controlPoints[] = {{0, 0}, {3, 1}, {4, 2}, {6, 3}}; // 控制点坐标int numPoints = sizeof(controlPoints) / sizeof(struct Point);for (float t = 0; t <= 1; t += 0.1) {struct Point p = getBezierPoint(controlPoints, numPoints, t); printf("t=%.1f, x=%.1f, y=%.1f\n", t, p.x, p.y);}return 0;}```这个程序通过递归调用`getBezierPoint`函数来计算贝塞尔曲线上的点。
mfc 贝塞尔曲线

MFC(Microsoft Foundation Class)是一组用于开发Windows桌面应用程序的C++类库。
在MFC中,您可以使用贝塞尔曲线来创建平滑曲线或路径。
贝塞尔曲线是一种数学曲线,通常用于绘制平滑的曲线或路径,其中包括四个控制点:起点、终点以及两个控制点。
以下是在MFC中使用贝塞尔曲线的基本步骤:1. **包含MFC头文件**:首先,在您的MFC应用程序中包含必要的头文件。
通常,您需要包含`afxwin.h`和`afxext.h`等头文件。
2. **创建CPoint对象**:为了定义贝塞尔曲线,您需要创建四个`CPoint`对象来表示起点、终点以及两个控制点。
```cppCPoint startPoint(x1, y1); // 起点坐标CPoint endPoint(x2, y2); // 终点坐标CPoint controlPoint1(x3, y3); // 控制点1坐标CPoint controlPoint2(x4, y4); // 控制点2坐标```3. **使用CDC对象绘制贝塞尔曲线**:MFC中的CDC(Device Context)对象用于绘制图形。
您可以使用CDC对象的`PolyBezier`方法来绘制贝塞尔曲线。
```cppCDC* pDC = GetDC(); // 获取设备上下文对象pDC->PolyBezier(startPoint, controlPoint1, controlPoint2, endPoint);ReleaseDC(pDC); // 释放设备上下文对象```上述代码使用`PolyBezier`方法绘制了一个贝塞尔曲线,其中`startPoint`是起点,`endPoint`是终点,`controlPoint1`和`controlPoint2`是控制点。
4. **刷新窗口**:如果在视图或对话框中进行绘制,通常需要在绘制之后调用`Invalidate`或`InvalidateRect`来请求重绘窗口,以使绘制的曲线可见。
c语言贝塞尔曲线控制点

在C语言中,贝塞尔曲线是一种常用的数学曲线,通常用于计算机图形学和动画中。
贝塞尔曲线由一系列控制点定义,这些控制点决定了曲线的形状。
贝塞尔曲线的控制点可以是一维的,也可以是多维的。
一维控制点定义了二维空间中的曲线,而多维控制点定义了更高维度的曲线。
在二维空间中,二次贝塞尔曲线由两个控制点定义。
这两个控制点可以表示为
(x1, y1)和(x2, y2)。
二次贝塞尔曲线的数学公式如下:
(B(t) = (1-t)^2 P0 + 2(1-t)t P1 + t^2 P2)
其中 (P0) 和 (P2) 是控制点,(t) 是一个参数,范围在 [0, 1] 之间。
下面是一个简单的C语言代码示例,用于计算二次贝塞尔曲线上的点:
这个代码示例定义了一个bezier函数,该函数接受一个控制点数组和一个参数t,并返回计算得到的贝塞尔曲线上的点。
在main函数中,我们使用三个控制点(0,0), (1,2), (2,0) 来计算贝塞尔曲线,并打印出曲线上的点。
编程贝塞尔曲线

编程贝塞尔曲线贝塞尔曲线是一种常用于计算机图形学和计算机动画中的数学曲线。
它通过控制点来绘制平滑曲线,具有良好的插值性质和变形能力。
在编程中,贝塞尔曲线被广泛应用于图形设计、动画效果、游戏开发等领域。
本文将介绍贝塞尔曲线的原理和常用编程方法,并以实例说明如何使用代码实现和操作贝塞尔曲线。
一、贝塞尔曲线的原理贝塞尔曲线由控制点组成,而曲线上的所有点都由这些控制点决定。
在二维平面中,贝塞尔曲线可以通过多个控制点来定义。
对于二次贝塞尔曲线,需要三个控制点,分别为起点、终点和控制点;对于三次贝塞尔曲线,需要四个控制点,依此类推。
贝塞尔曲线的特点是平滑和可变形。
它能够通过调整控制点的位置和数量,实现各种不同形状的曲线。
同时,贝塞尔曲线还具有良好的插值性质,即曲线上的点在控制点所决定的区域内连续变化。
在计算机图形学中,贝塞尔曲线通常使用参数方程来描述。
假设有n个控制点,将它们依次标记为P0,P1,...,Pn-1,在参数范围[0, 1]内,贝塞尔曲线可以表示为下列形式的参数方程:B(t) = Σ(C(n, i) * t^i * (1-t)^(n-i) * Pi)其中,C(n, i)是组合数,表示从n个元素中选取i个的组合数。
贝塞尔曲线上的任一点B(t)由所有控制点的加权和决定,权重由组合数和参数t的幂次决定。
二、贝塞尔曲线的编程实现在编程中,可以通过数值计算来近似表示和绘制贝塞尔曲线。
常见的实现方式包括使用递归算法和迭代算法。
1. 递归算法递归算法是最直观和常用的绘制贝塞尔曲线的方法。
对于二次贝塞尔曲线,可以使用如下伪代码实现:function drawQuadraticBezierCurve(P0, P1, P2):for t from 0 to 1 with step 0.01:B(t) = (1 - t)^2 * P0 + 2 * t * (1 - t) * P1 + t^2 * P2drawPoint(B(t))其中,P0、P1和P2分别表示起点、控制点和终点的坐标。
贝塞尔曲线 递归画法 vc++

贝塞尔曲线递归画法 vc++贝塞尔曲线是一种数学曲线,可以通过多个控制点来定义曲线形状。
在VC++中,可以使用递归的方式来画贝塞尔曲线。
要画一条二阶贝塞尔曲线,需要三个控制点:起始点P0、控制点P1和结束点P2。
这条曲线可以通过以下公式计算得出:B(t) = (1-t)^2 * P0 + 2 * (1-t) * t * P1 + t^2 * P2,其中0 ≤ t ≤ 1。
具体的绘制过程如下:1. 首先,需要定义一个函数,该函数用于计算贝塞尔曲线上的坐标点:```PointF calculateBezierPoint(PointF P0, PointF P1, PointF P2, float t){PointF point;float u = 1 - t;float tt = t * t;float uu = u * u;float uuu = uu * u;float ttt = tt * t;point.X = uuu * P0.X + 2 * uu * t * P1.X + tt * P2.X;point.Y = uuu * P0.Y + 2 * uu * t * P1.Y + tt * P2.Y;return point;}```2. 接下来,在绘制函数中调用上述函数,逐步计算贝塞尔曲线上的点,并连接这些点:```void drawBezierCurve(Graphics^ g, PointF P0, PointF P1,PointF P2){float step = 0.01; // 步长,控制曲线的平滑程度for (float t = 0; t <= 1; t += step){PointF point = calculateBezierPoint(P0, P1, P2, t);g->DrawLine(Pens::Black, point, point);}}```3. 最后,在主绘图函数中调用上述函数,并传入控制点的坐标:```void PaintEventHandler(System::Object^ sender,PaintEventArgs^ e){PointF P0(100, 100); // 起始点坐标PointF P1(200, 300); // 控制点坐标PointF P2(400, 100); // 结束点坐标drawBezierCurve(e->Graphics, P0, P1, P2);}```通过以上步骤,就可以绘制出一条二阶贝塞尔曲线。
计算机图形学-Bezier曲线算法de-Castljau

/*1.实现Bezier曲线2.数据由data.in读入,其格式为:点数各个点坐标例如:410 15050 50150 50190 1503.可以实现100阶以内Bezier*/#include <windows.h>#include <stdio.h>#include <vector>using namespace std;LRESULT CALLBACK WinSunProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameter LPARAM lParam // second message parameter);void MidpointLine(int x0, int y0, int x1, int y1, HWND hwnd); void bezier(HWND hwnd);int cnt = 0;const int MAX = 105;const int COUNT = 1000;int n;int ptr;struct Point{double x, y;};vector<Point> p[2], vec;int WINAPI WinMain(HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine, // command lineint nCmdShow // show state){WNDCLASS wndcls;wndcls.cbClsExtra=0;wndcls.cbWndExtra=0;wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);wndcls.hInstance=hInstance;wndcls.lpfnWndProc=WinSunProc;wndcls.lpszClassName="Ted";wndcls.lpszMenuName=NULL;wndcls.style=CS_HREDRAW | CS_VREDRAW;RegisterClass(&wndcls);HWND hwnd;hwnd=CreateWindow("Ted","XukeIsDaHaoRen!",WS_OVERLAPPEDWINDOW, 0,0,600,400,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return 0;}LRESULT CALLBACK WinSunProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter){switch(uMsg){case WM_CHAR:char szChar[20];sprintf(szChar,"char is %d",wParam);MessageBox(hwnd,szChar,"Nothing",0);break;case WM_LBUTTONDOWN:MessageBox(hwnd,"Waiting...","Performance",0);//HDC hdc;//hdc=GetDC(hwnd);//MidpointLine(100, 100, 200, 200, hwnd);bezier(hwnd);break;case WM_PAINT:HDC hDC;PAINTSTRUCT ps;hDC=BeginPaint(hwnd,&ps);TextOut(hDC,0,0,"By Ted",strlen("By Ted"));EndPaint(hwnd,&ps);break;case WM_CLOSE:if(IDYES==MessageBox(hwnd,"Quit?(Y/N)"," ",MB_YESNO)){DestroyWindow(hwnd);}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd,uMsg,wParam,lParam);}return 0;}int curPtr(){return ptr % 2;}int prePtr(){return (ptr + 1) % 2;}Point cut(Point p1, Point p2, double t){Point temp;temp.x = p1.x + t * (p2.x - p1.x);temp.y = p1.y + t * (p2.y - p1.y);return temp;}Point deCasteljau(double t){//Point temp;for(int i = 0; i < n - 1; i++){int cur = curPtr(), pre = prePtr();p[pre].clear();for(int j = 0; j < (int)p[cur].size() - 1; j++){Point temp = cut(p[cur][j], p[cur][j + 1], t);p[pre].push_back(temp);}++ptr;}int cur = curPtr();return p[cur][0];}void bezier(HWND hwnd){HDC dc;dc = GetDC(hwnd);int i;Point temp;FILE *fp = fopen("data.in", "r");fscanf(fp, "%d\n", &n);//char str[20];//sprintf(str, "%d\n", n);//MessageBox(hwnd,"Waiting...",str,0);for(i = 0; i< n; i++){fscanf(fp, "%lf %lf\n", &temp.x, &temp.y);vec.push_back(temp);}//HDC dc;//dc = GetDC(hwnd);for(i = 0; i < (int)vec.size(); i++){SetPixel(dc, (int)vec[i].x, (int)vec[i].y, RGB(255,0,0));if(i < (int)vec.size() - 1){MoveToEx(dc, (int)vec[i].x, (int)vec[i].y, (LPPOINT) NULL);//MoveToEx(hdc, (int) 110, (int) 110, (LPPOINT) NULL);LineTo(dc, (int)vec[i + 1].x, (int)vec[i + 1].y);}}for(int t = 0; t <= COUNT; t++){ptr = 0;p[ptr] = vec;temp = deCasteljau((double)((double)t / (double)COUNT));SetPixel(dc, (int)temp.x, (int)temp.y, RGB(255,0,0));}return ;}void MidpointLine(int x0, int y0, int x1, int y1, HWND hwnd){HDC dc;dc=GetDC(hwnd);int a=0;int b=0;int d1=0;int d2=0;int d=0;int x=0;int y=0;a=y0-y1;b=x1-x0;d=2*a+b;d1=2*a;d2=2*a+2*b;x=x0;y=y0;SetPixel(dc,x,y,RGB(255,0,0));while(x<x1){if(d<0){x++;y++;d += d2;}else{x++;d =+ d1;}SetPixel(dc,x,y,RGB(255,0,0));}ReleaseDC(hwnd,dc);}。
控制和生成贝塞尔曲线

生成与控制贝塞尔曲线源代码:#include<stdafx.h>#include<iostream.h>#include<string.h>#include<cxcore.h>#include<cv.h>//#include<math.h>#include<highgui.h>#include<fstream.h>//using namespace std;const int WW_MAX_MARK_COUNT=40;//总共的点数,依据函数开始有4个点,之后每三个点(共用前面一个点)画贝塞尔曲线int mark_count=4;int conner_pt_index=-1;CvPoint3D32f Control_pts[WW_MAX_MARK_COUNT];IplImage *image=0;bool is_showControlLines=true;CvPoint3D32f pointAdd(CvPoint3D32f p,CvPoint3D32f q){p.x+=q.x;p.y+=q.y;p.z+=q.z;return p;}CvPoint3D32f pointTimes(float c,CvPoint3D32f p){p.x*=c;p.y*=c;p.z*=c;return p;}CvPoint3D32f Bernstein(float u,CvPoint3D32f *p){CvPoint3D32f a,b,c,d,r;a=pointTimes(pow(u,3),p[0]);//这是贝塞尔曲线生成与周围4点的关系(不是太懂。
)b=pointTimes(3*pow(u,2)*(1-u),p[1]);c=pointTimes(3*u*pow((1-u),2),p[2]);d=pointTimes(pow((1-u),3),p[3]);r=pointAdd(pointAdd(a,b),pointAdd(c,d));return r;}void DrawControlLine(CvPoint3D32f *p){CvPoint pc[4];for(int i=0;i<4;i++){pc[i].x=(int)p[i].x;pc[i].y=(int)p[i].y;}cvLine(image,pc[0],pc[1],CV_RGB(0,0,255),1,CV_AA,0);cvLine(image,pc[2],pc[3],CV_RGB(0,0,255),1,CV_AA,0);}int getNearPointIndex(CvPoint mouse_pt){CvPoint pt;for(int i=0;i<mark_count;i++){pt.x=mouse_pt.x-(int)Control_pts[i].x;pt.y=mouse_pt.y-(int)Control_pts[i].y;float distance=sqrt((float)(pt.x*pt.x+pt.y*pt.y));if(distance<10) return i;//如果距离小于10,可以手动控制线的端点(感觉很牛b}return -1;}void on_mouse(int event,int x,int y,int flags,void *param)//个人感觉这类似于单片机中断{if(event==CV_EVENT_LBUTTONDOWN)//left button down(鼠标左键按下,与之对应的是:right button down){CvPoint pt=cvPoint(x,y);cout<<x<<","<<y<<endl;if(conner_pt_index>-1)conner_pt_index=-1;else{conner_pt_index=getNearPointIndex(pt);if(conner_pt_index==-1){if(mark_count<=(WW_MAX_MARK_COUNT-1)){Control_pts[mark_count].x=(float)pt.x;Control_pts[mark_count].y=(float)pt.y;Control_pts[mark_count].z=0;mark_count++;}}}}else if(event==CV_EVENT_MOUSEMOVE){if(conner_pt_index>-1){Control_pts[conner_pt_index].x=(float)x;Control_pts[conner_pt_index].y=(float)y;}}}int main()//书中有int argc,char *argv[].个人感觉没必要!{CvSize image_sz=cvSize(1000,1000);image=cvCreateImage(image_sz,8,3);cvNamedWindow("Win",0);cvSetMouseCallback("Win",on_mouse,0);//类似设置中断,可以右键点击看看cvSetMouseCallback的函数组成。