You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.9 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @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代表至少一侧无nod2代表其两侧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);