/******************************************************************** 创建日期:2017年9月11日 文 件 名:PDSBezier.h 原始作者:孙宇飞 描 述:二次或者三次Bezier曲线 修改记录: 版本号 修改日期 作者 修改内容 *********************************************************************/ #ifndef _PDS_BEZIER_H_ #define _PDS_BEZIER_H_ #include #include #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 { public: //扩展的变量 public: //扩展的方法 CPDSBezierPointList& operator=(CPDSBezierPointList& rhs); //赋值 CPDSBezierPoint& operator[](int iIndex); //根据索引值检索,不可越界 //根据listPoint设置this void SetPoint(CList& listPoint); //将this的数据输出至listPoint void GetPoint(CList& 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_