/** * @file CCurveClosure.h * @brief 曲线闭合区域类接口 * @author 王昌伟 * @time 2010-11-30 2012-9-4修改 */ #pragma once #include "stdafx.h" #include #include #include "CurveEx.h" using namespace std; #define CPVEC vector /** @brief 曲线交点结构体*/ struct AFX_EXT_CLASS CCrossPointW { int number[2]; //组成交点的两条线分别为线链表中的第几条线 double x; double y; double z; double l[2]; //两条线的桩号 CCurveEx* cur[2]; //两条线的curve bool operator ==(const CCrossPointW &cp) const { return number[0] == cp.number[0] && number[1] == cp.number[1] && fabs(x - cp.x) < 1e-5&&fabs(y - cp.y) < 1e-5&&fabs(z - cp.z) < 1e-5; } bool operator <(const CCrossPointW &cp) const { if (number[0] < cp.number[0]) return true; if (number[0] == cp.number[0] && number[1] < cp.number[1]) return true; else return false; } }; /** * @brief 邻近曲线. */ struct AFX_EXT_CLASS NearbyCurveItem { CCurveEx* cur; //曲线 double ls0; //辅助线探测的顺时针方向曲线段的起点 double ll0; //辅助线探测的顺时针方向曲线段的终点 double ls1; //曲线段的顺时针方向起始端点 double ll1; //曲线段的顺时针方向结束端点 int ils1Clockwise;//曲线段的顺时针方向起始端点曲线走向 int ill1Clockwise;//曲线段的顺时针方向结束端点曲线走向 double angle0; //曲线段的顺时针方向起始端点弧度, 中心点垂直向上为起始弧度,初始为0 double angle1; //曲线段的顺时针方向结束端点弧度, 中心点垂直向上为起始弧度,初始为0 bool isBorder; NearbyCurveItem() { ls0 = -1; ll0 = -1; ls1 = -1; ll1 = -1; ils1Clockwise = -1; ill1Clockwise = -1; angle0 = -1; angle1 = -1; isBorder = TRUE; } }; /* @brief 曲线闭合区域类*/ class AFX_EXT_CLASS CCurveClosure { public: /** * @brief 创建闭合曲线. * * @param curveList 曲线列表 * @param dMaxExtend 曲线延伸长度 * @param dRadius 扫描半径 */ CCurveClosure(CPtrList *curveList = NULL, double dMaxExtend = 0, double dRadius = 1e10); ~CCurveClosure(); /** @brief 创建闭合曲线*/ CCurveEx* CreateClosedCurve(dfPoint& dfp); /** @brief 中心点*/ void SetCenterPoint(dfPoint& fpt); /** @brief 扫描半径 */ void SetRadius(double radius); /** @brief 曲线延伸长度 */ void SetMaxExtend(double dMaxExtend); /** @brief 清空对象数据,重新初始化对象 */ void Create(CPtrList *CurveList = NULL, double dMaxExtend = 0 , double dRadius = 1e10);//初始化类 /** @brief 清空数据*/ void ClearAll(); private: //*************************************************原始算法实现********************************************// /** @brief 所有曲线延伸*/ void CurveExtend(CPtrList *CurveList, double dMaxExtend); /** @brief CurveList中所有曲线交点*/ int GetAllCrossPoints(CPtrList *CurveList, double dMaxExtend = 0); /** @brief 找到距离目标点最近的线,并找到该最近点两侧相交结点序号,i1->i2为顺时针方向 * ml1 与ml2 为nod点i1,i2在icurve上对应桩号 auxAngle 为辅助线与垂直线的夹角正弦(顺时针方向) */ int GetInitPoint(CCurveEx* &icurve, double& ml1, double& ml2, int& i1, int& i2, double auxAngletan = 0); /** @brief 得到曲线某一桩号前后结点桩号*/ int GetNearbyLocation(CCurveEx* curve, double l0, double& ls, double& ll); /** @brief 找到指定曲线指定桩号两旁最近的CrossNod序号,得到对应桩号,1代表都存在且不重合,0代表至少一侧无nod,2代表其两侧nod重合*/ int GetNearbyCrossNods(CCurveEx* curve, double l0, double& lsmaller, double& llarger, int& ismaller, int& ilarger); /** @brief 得到曲线上下一个结点坐标, 返回桩号*/ double GetNextPoint(CCurveEx* curve, double l1, double l2, dfPoint& fpt); /** @brief 通过交点集和已知曲线段,结点序号, 结点前一个点桩号找到正确的相交曲线段, * 将其点存入m_BorderPoints,如该nodNum已经查找过,返回false*/ bool FindNextCurve(CCurveEx* &curve, int& nodNum, double& lahead); /** @brief *通过辅助点与中心点连线找到距离中心点最近的交点, 并判断该交点所处曲线走向对于 * cpoint是顺时针还是逆时针,iClockWise = 1为顺时针, 0为逆时针,其它为无法判断出 */ bool GetAuxCrossPoint(dfPoint& auxpt, CCurveEx* &tarCurve, double& tarl0, int& bClockWise); /** @brief 直接得到工区内任一点周围的闭合区域,并将其组成一条单个CCurve曲线*/ bool GetClosurePoints(dfPoint &dfp); //*************************************************原始算法实现********************************************// //*************************************************改进算法实现********************************************// /** @brief *通过辅助点与中心点连线找到距离中心点最近的交点, 并判断该交点所处曲线走向对于 * cpoint是顺时针还是逆时针,iClockWise = 1为顺时针, 0为逆时针,其它为无法判断出 * 填充的曲线筛除 */ bool GetAuxCrossCurve(dfPoint& auxpt, CCurveEx* &tarCurve, double& tarl0); /** * @brief 清除邻近计算数据. * */ void ClearNearbyData(); /** * @brief 获取与中心点邻近的曲线集合. * * @param dfp 中心点 * @return 曲线数量 */ int GetNearbyCurves(); /** * @brief 设置邻近曲线的两个曲线交点位置. * * @return */ int SetNearbyCurveCrossNods(); /** * @brief 创建边界曲线. * * @return */ CCurveEx* CreateRegionCurve(); /** * @brief 截取曲线. * * @param pCur * @param pl * @param ls * @param ll * @param bClockwise * @return */ int ExtractCurveSegment(CCurveEx *pCur, CPointList &pl, double ls, double ll, int bClockwise); //*************************************************改进算法实现********************************************// public: CPointList m_BorderPoints; ///< 闭合区域边界上所有点 dfPoint m_cpoint; ///<中心点坐标 CPVEC m_CrossNods; ///<所有交点 set m_FoundNodNumSet; ///< 已经查找过的结点 CPtrList *m_pCurveList; ///<工区内所有曲线的list double m_dMaxExtend; //曲线延伸长度 double m_dRadius; CPtrList *m_pNearbyCurveList; ///中心点邻近曲线,存放的NearbyCurveItem指针 CPtrList *m_pSelctedCurveList; // 存放的CCurveEx指针 }; /** @brief 得到向量pt1,pt2 与pt2, pt3之间的夹角cos值*/ double GetCosVal(CPoint2D& pt1, CPoint2D& pt2, CPoint2D& pt3); //两向量叉积 double CrossProduct(double x1, double y1, double x2, double y2); //两向量点积 double DotProduct(double x1, double y1, double x2, double y2);