139 lines
4.8 KiB
C++
139 lines
4.8 KiB
C++
/********************************************************************
|
|
创建日期:2017年9月11日
|
|
文 件 名:PDSBezier.h
|
|
原始作者:孙宇飞
|
|
描 述:二次或者三次Bezier曲线
|
|
|
|
修改记录:
|
|
版本号 修改日期 作者 修改内容
|
|
*********************************************************************/
|
|
#ifndef _PDS_BEZIER_H_
|
|
#define _PDS_BEZIER_H_
|
|
|
|
#include <afxwin.h>
|
|
#include <afxtempl.h>
|
|
#include "PDSMath.h"
|
|
|
|
//Bezier点
|
|
class CPDSBezierPoint : public CObject
|
|
{
|
|
public:
|
|
CDBLPoint m_ptPoint; // 点,Bezier曲线必须要经过该点
|
|
CDBLPoint m_ptPrev; // 前切线点
|
|
CDBLPoint m_ptNext; // 后切线点
|
|
|
|
double m_dParam; // 该点对应的参数值,在计算Bezier曲线的实际点链的过程中起作用,默认值:0
|
|
|
|
public:
|
|
CPDSBezierPoint(void);
|
|
CPDSBezierPoint(CDBLPoint ptPoint, CDBLPoint ptPrev, CDBLPoint ptNext, double dParam = 0.0);
|
|
CPDSBezierPoint(CPoint ptPoint, CPoint ptPrev, CPoint ptNext, double dParam = 0.0);
|
|
CPDSBezierPoint(CPDSBezierPoint& rhs);
|
|
virtual ~CPDSBezierPoint(void);
|
|
CPDSBezierPoint& operator=(CPDSBezierPoint& rhs);
|
|
BOOL operator==(CPDSBezierPoint& rhs); // 仅比较m_ptPoint是否相等
|
|
BOOL operator!=(CPDSBezierPoint& rhs); // 仅比较m_ptPoint是否相等
|
|
|
|
void Initial(void);
|
|
|
|
//使用ptPoint,ptPrev,ptNext设置this
|
|
void SetPoint(CPoint ptPoint, CPoint ptPrev, CPoint ptNext);
|
|
|
|
//获取ptPoint,ptPrev,ptNext
|
|
void GetPoint(CPoint& ptPoint, CPoint& ptPrev, CPoint& ptNext);
|
|
};
|
|
|
|
//Bezier点的链表
|
|
class CPDSBezierPointList : public CList<CPDSBezierPoint,CPDSBezierPoint>
|
|
{
|
|
public: //扩展的变量
|
|
public: //扩展的方法
|
|
|
|
CPDSBezierPointList& operator=(CPDSBezierPointList& rhs); //赋值
|
|
CPDSBezierPoint& operator[](int iIndex); //根据索引值检索,不可越界
|
|
|
|
//根据listPoint设置this
|
|
void SetPoint(CList<CPoint,CPoint>& listPoint);
|
|
|
|
//将this的数据输出至listPoint
|
|
void GetPoint(CList<CPoint,CPoint>& listPoint);
|
|
|
|
POSITION AddWithoutDuplicate(CPDSBezierPoint ptBezierPoint, BOOL bAddTail = TRUE);
|
|
|
|
void AddWithoutDuplicate(CPDSBezierPointList& listBezierPoint, BOOL bAddTail = TRUE);
|
|
|
|
//根据给定的参数值,查找索引值
|
|
int FindParamIndex(double dParam);
|
|
|
|
//获取长度
|
|
double GetLength(void);
|
|
|
|
//将this翻转
|
|
void Reverse(void);
|
|
};
|
|
|
|
//Bezier曲线类
|
|
class CPDSBezierCurve : public CObject
|
|
{
|
|
public:
|
|
//成员变量封装在一起,方便写代码,Bezier曲线的计算函数并不使用成员变量
|
|
CPDSBezierPointList m_listCtrlPoint; // 控制点链,前后切线点参与计算
|
|
CPDSBezierPointList m_listRealPoint; // 实际点链,忽略前后切线点的值
|
|
int m_iBezierDegree; // Bezier曲线的次数,二次或者三次,默认值:3
|
|
|
|
public:
|
|
CPDSBezierCurve(void);
|
|
CPDSBezierCurve(CPDSBezierCurve& rhs);
|
|
virtual ~CPDSBezierCurve(void);
|
|
CPDSBezierCurve& operator=(CPDSBezierCurve& rhs);
|
|
|
|
void Initial(void);
|
|
|
|
//计算Bezier曲线
|
|
//输入参数:
|
|
// listCtrlPoint 控制点链,前一个点的next切线点与后一个点的prev切线点计算这两点之间的实际点链
|
|
// bClose =true 闭合线,GetTail()与GetHead()之间的部分需要计算,=false 开口线
|
|
// iBezierDegree Bezier曲线的次数,=2或者=3
|
|
// dMaxError 最大误差值
|
|
//输出参数:
|
|
// listRealPoint 实际点链
|
|
static void CalculateBezierCurve(CPDSBezierPointList& listCtrlPoint, BOOL bClose, int iBezierDegree, double dMaxError, CPDSBezierPointList& listRealPoint);
|
|
|
|
protected:
|
|
|
|
//计算两点之间的Bezier曲线
|
|
//输入参数:
|
|
// ptPrevBezierPoint 前一个Bezier点,它的next切线点参与计算
|
|
// ptNextBezierPoint 后一个Bezier点,它的prev切线点参与计算
|
|
// iBezierDegree Bezier曲线的次数,=2或者=3
|
|
// dMaxError 最大误差值
|
|
//输出参数:
|
|
// listRealPoint 实际点链
|
|
static void CalculateBezierBetweenTwoPoint(CPDSBezierPoint ptPrevBezierPoint, CPDSBezierPoint ptNextBezierPoint, int iBezierDegree, double dMaxError, CPDSBezierPointList& listRealPoint);
|
|
|
|
//根据给定的参数值计算Bezier点
|
|
//输入参数:
|
|
// ptPrevBezierPoint 前一个Bezier点,它的next切线点参与计算
|
|
// ptNextBezierPoint 后一个Bezier点,它的prev切线点参与计算
|
|
// iBezierDegree Bezier曲线的次数,=2或者=3
|
|
// dParam 参数值,0<=dParam<=1
|
|
//返回值:
|
|
// Bezier点
|
|
static CPDSBezierPoint CalculateBezierPoint(CPDSBezierPoint ptPrevBezierPoint, CPDSBezierPoint ptNextBezierPoint, int iBezierDegree, double dParam);
|
|
|
|
//根据计算切点的参数
|
|
//输入参数:
|
|
// ptPrevBezierPoint 前一个Bezier点,它的next切线点参与计算
|
|
// ptNextBezierPoint 后一个Bezier点,它的prev切线点参与计算,这两个点构成了一段Bezier曲线
|
|
// iBezierDegree Bezier曲线的次数,=2或者=3
|
|
// ptBezierPoint1 该段Bezier曲线上的点1
|
|
// ptBezierPoint2 该段Bezier曲线上的点2
|
|
//输出参数:
|
|
// dParam1 参数,介于1点的参数和2点的参数之间
|
|
// dParam2 参数,介于1点的参数和2点的参数之间,并且大于dParam1
|
|
//返回值:
|
|
// =2 有两个解,=1 有一个解,=0 没有解
|
|
static int CalculateTangentParam(CPDSBezierPoint ptPrevBezierPoint, CPDSBezierPoint ptNextBezierPoint, int iBezierDegree, CPDSBezierPoint ptBezierPoint1, CPDSBezierPoint ptBezierPoint2, double& dParam1, double& dParam2);
|
|
};
|
|
|
|
#endif // _PDS_BEZIER_H_
|