PlotterHMI/datafile/dxf/dxflib/PDSMath/PDSBezier.h
huahaiyan 9f74511e69 20240315
1、增加数据分割功能(完成)
2、更换dxf库(进行中)
2024-03-15 16:49:50 +08:00

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_