|
|
/**
|
|
|
* @file CCurveClosure.h
|
|
|
* @brief 曲线闭合区域类接口
|
|
|
* @author 王昌伟
|
|
|
* @time 2010-11-30 2012-9-4修改
|
|
|
*/
|
|
|
|
|
|
#pragma once
|
|
|
#include "stdafx.h"
|
|
|
#include <vector>
|
|
|
#include <iostream>
|
|
|
#include "CurveEx.h"
|
|
|
|
|
|
using namespace std;
|
|
|
#define CPVEC vector<CCrossPointW>
|
|
|
|
|
|
/** @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<int> 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);
|