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.

288 lines
16 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.

////////////////////////////////////////////////////////////////////////////////////////
//GraphUtility.h
#pragma once
#include "CommonDefines.h"
class CGraphUtility
{
public:
CGraphUtility();
~CGraphUtility();
//Attributes
public:
/* 求p0p1线与p2p1线的夹角,返回弧度 */
static double angle(CPoint2D& p0,CPoint2D& p1,CPoint2D& p2);
/*射线p1p0到射线p1p2的旋转角,逆时针为正,返回弧度*/
static double rotateangle(CPoint2D& p0,CPoint2D& p1,CPoint2D& p2);
/*求p0p1线与p2p1线的夹角的余弦*/
static double cosa(CPoint2D& p0,CPoint2D& p1,CPoint2D& p2);
/*求点p到线段p1p2的距离,返回值>0.0 点在线的右侧; 返回值<0.0 点在线的左侧,interpoint保存的是p点在线段上的投影*/
static double GetPointAndLineDistance(CPoint2D& p1,CPoint2D& p2,CPoint2D& p,INTERPOINT& interpoint);
/*求两个点的距离*/
static double TwoPointDistance(CPoint2D& p1,CPoint2D& p2);
/*求两个点的距离*/
static int TwoPointDistance(POINT p1,POINT p2);
/*求两点距离的平方*/
static double SquareTwoPointDistance(CPoint2D& p1,CPoint2D& p2);
/* 点p是否在闭合的区域内
如果点在区域外返回0
点在区域边界上返回1 如果pIndex!=NULL则pIndex返回所在的线段号
点在区域内返回2 */
static int PointInRegion(CPoint2D* point,int count,CPoint2D p,double& dIndex);
static int PointInRegion(POINT* point,int count,POINT p,double& dIndex);
//判断两个不相交的多边形的相对关系
//0--没有重叠
//1--部分重叠
//2--区域0在区域1内部
//3--区域1在区域0内部
//4--完全重叠
//static int PolygonInPolygon(CGDFPolygon* polygon0,CGDFPolygon* polygon1);
//多边形逻辑运算
//0--没有重叠 返回0时表示合并多边形未成功
//1--部分重叠
//2--区域0在区域1内部
//3--区域1在区域0内部
//4--完全重叠
// static int AndPolygon(CGDFPolygon* polygon0,CGDFPolygon* polygon1,CTypedPtrArray<CPtrArray,CGDFPolygon*>& polygonarray);
// static int SubPolygon(CGDFPolygon* polygon0,CGDFPolygon* polygon1,CTypedPtrArray<CPtrArray,CGDFPolygon*>& polygonarray);
// static int AddPolygon(CGDFPolygon* polygon0,CGDFPolygon* polygon1,CTypedPtrArray<CPtrArray,CGDFPolygon*>& polygonarray);
//
// //检查多边形的方向,如果是逆时针就调整为顺时针
// static void AssertClockwise(CPoint2D* p,int count);
/*改变多边形的方向,原来的头点变为尾点,原来的尾点变为头点*/
static void ReversePolyline(CPoint2D* p,int count);
//
/*计算多边形的面积,返回值<0,表示多边形是顺时针,>0表示多边形是逆时针*/
static double CalculateArea(CPoint2D* p,int count);
//计算Bezier多边形的面积,返回值<0,表示多边形是顺时针,>0表示多边形是逆时针
static double CalculateBezierArea(CPoint2D* p,int count);
// //计算折线的长度
// static double CalculateLength(CPoint2D* p,int count,BOOL bClose);
// //计算Bezier曲线的长度,p0为头点,p1为头点的右侧控制点,p2为尾点的左侧控制点,p3为尾点
// static double CalculateBezierLength(CPoint2D& p0,CPoint2D& p1,CPoint2D& p2,CPoint2D& p3);
// //计算Bezier折线的长度
// static double CalculateBezierLength(CPoint2D* p,int count,BOOL bClose);
//计算折线的方向,0--无法判断 1--顺时针 -1--逆时针
static int GetPolygonDirection(CPoint2D* p,int count);
//
// //计算两个闭合的多边形的交点
// //0--没有重叠
// //1--部分重叠
// //2--区域0在区域1内部
// //3--区域1在区域0内部
// //4--完全重叠
// static int GetRegionInterPoint(CPoint2D* p,int count,CPoint2D* p1,int count1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
//求两个多边形的交点,返回的是交点的个数
static int GetInterPoint(CPoint2D* p0,int count0,BOOL bClose0,CPoint2D* p1,int count1,BOOL bClose1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
//求多边形与线段的交点,返回交点的个数
static int GetInterPoint(CPoint2D* p,int count,BOOL bClose,CPoint2D p0,CPoint2D p1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
//求两个线段的交点
static int GetInterPoint(CPoint2D point0,CPoint2D point1,CPoint2D p0,CPoint2D p1,INTERPOINT& interpoint);
//点是否在折线上
//返回1,在折线上,pdIndex返回在折线上的位置
//返回0,在线的左侧
//返回2,在线的右侧
//返回3,无法确定
static int PointInLine(POINT point,POINT* pPointArray,int iPointCount,BOOL bClose,double* pdIndex=NULL);
//点是否在折线上
//返回1,在折线上,pdIndex返回在折线上的位置
//返回0,在线的左侧
//返回2,在线的右侧
//返回3,无法确定
static int PointInLine(CPoint2D point,CPoint2D* pPointArray,int iPointCount,BOOL bClose,double* pdIndex=NULL);
//判断点是否在线段上
//0--在线的左侧
//1--在线上
//2--在线的右侧
//-1--在线上,但不在线段上
//3--无法确定在哪一侧,只有当p0与p1重合时才会出现这种情况
static int PointInLine(POINT& point,POINT& p0,POINT& p1);
//判断点是否在线段上
//0--在线的左侧
//1--在线上
//2--在线的右侧
//-1--在线上,但不在线段上
//3--无法确定在哪一侧,只有当p0与p1重合时才会出现这种情况
static int PointInLine(CPoint2D& point,CPoint2D& p0,CPoint2D& p1);
//取得线段上的一个点,parameter为位置索引,parameter>=0.0 && parameter<=1.0,parameter=0.5表示取中间点
static POINT GetPointInLine(POINT p1,POINT p2,double parameter);
static CPoint2D GetPointInLine(CPoint2D p1,CPoint2D p2,double parameter);
//判断鼠标是否选种一条折线
static double LineHitTest(POINT* pPoint,int count,POINT point,BOOL bClosed,GDFLOGPEN* pLogPen=NULL,double dZoomFactor=1.0);
static double LineHitTest(POINT point1,POINT point2,POINT point,GDFLOGPEN* pLogPen=NULL,double dZoomFactor=1.0);
//accuracy为精度值,是逻辑坐标单位
static double LineHitTest(int accuracy,POINT point1,POINT point2,POINT point);
//得到Bezier曲线上的一个点,dParameter为点的位置索引
static CPoint2D GetBezierPosition(CPoint2D p0,CPoint2D p1,CPoint2D p2,CPoint2D p3,double dParameter);
//得到Bezier曲线上的一个点,dIndex为点的位置索引,dIndex有可能>1.0
static CPoint2D GetBezierPosition(CPoint2D* p,int count,BOOL bClose,double dIndex);
//得到Bezier曲线上的一个点,dParameter为点的位置索引
static POINT GetBezierPosition(POINT& p0,POINT& p1,POINT& p2,POINT& p3,double fParameter);
//得到Bezier曲线上的一个点,dIndex为点的位置索引,dIndex有可能>1.0
static POINT GetBezierPosition(POINT* p,int count,BOOL bClose,double dIndex);
//把Bezier曲线转换为一般的折线,通过插值的方式
static void ConvertBezierToPolyline(CPoint2D* point,int count,BOOL bClose,CArray<CPoint2D,CPoint2D>& pointarray);
static void ConvertBezierToPolyline(CPoint2D& p0,CPoint2D& p1,CPoint2D& p2,CPoint2D& p3,CPoint2D* pointarray);
static void ConvertBezierToPolyline(CPoint2D* point,int count,BOOL bClose,int index0,int index1,CArray<CPoint2D,CPoint2D>& pointarray);
//各段插入的点数不等
static void ConvertBezierToPolylineAutoStep(CPoint2D* point,int count,BOOL bClose,CArray<CPoint2D,CPoint2D>& pointarray,double steplength,CArray<double,double>* pIndexArray=NULL);
static void ConvertBezierToPolylineAutoStep(CPoint2D& p0,CPoint2D& p1,CPoint2D& p2,CPoint2D& p3,CArray<CPoint2D,CPoint2D>& pointarray,double steplength,CArray<double,double>* pIndexArray=NULL);
static void ConvertBezierToPolylineAutoStep(CPoint2D* point,int count,BOOL bClose,int index0,int index1,CArray<CPoint2D,CPoint2D>& pointarray,double steplength,CArray<double,double>* pIndexArray=NULL);
static void ConvertBezierToPolyline(POINT* point,int count,BOOL bClose,CArray<POINT,POINT>& pointarray);
static void ConvertBezierToPolyline(POINT& p0,POINT& p1,POINT& p2,POINT& p3,POINT* pointarray);
//各段插入的点数不等
static void ConvertBezierToPolylineAutoStep(POINT* point,int count,BOOL bClose,CArray<POINT,POINT>& pointarray,int steplength,CArray<double,double>* pIndexArray=NULL);
static void ConvertBezierToPolylineAutoStep(POINT& p0,POINT& p1,POINT& p2,POINT& p3,CArray<POINT,POINT>& pointarray,int steplength,CArray<double,double>* pIndexArray=NULL);
static void GetBezierCutPoint(CPoint2D p0,CPoint2D p1,CPoint2D p2,CPoint2D p3,double dParameter,CPoint2D* point);
static void GetBezierCutPoint(CPoint2D* p,int count,BOOL bClose,double dIndex,CPoint2D* point);
static void GetBezierCutPoint(POINT p0,POINT p1,POINT p2,POINT p3,double dParameter,POINT* point);
static void GetBezierCutPoint(POINT* p,int count,BOOL bClose,double dIndex,POINT* point);
static int PointOnLineSide(CPoint2D& p0,CPoint2D& p1,CPoint2D& p,double& dIndex);//点在线的上侧还是下侧
static int PointOnLineSide(POINT& p0,POINT& p1,POINT& p,double& dIndex);
//
// //矩形相加
// static CRect8 AddRect(CRect8 rect1,CRect8 rect2);
//
// //求点p与线段p0p1的最近点,返回距离,interpoint返回最近点的具体位置
// static double GetNearestDistance(CPoint2D p0,CPoint2D p1,CPoint2D p,INTERPOINT& interpoint);
// static double GetNearestDistance(CPoint2D* pointarray,int count,BOOL bClose,CPoint2D p,INTERPOINT& interpoint);
//
// //求两条折线的最近点,返回最小距离,interpoint中保存最近点的具体位置
// static double GetNearestDistance(CPoint2D* pointarray0,int count0,BOOL bClose0,CPoint2D* pointarray1,int count1,BOOL bClose1,INTERPOINT& interpoint);
//
// //点是否在闭合Bezier曲线中
// //返回1,在折线上,pdIndex返回在折线上的位置
// //返回0,在区域外
// //返回2,在区域内
// static int PointInBezierRegion(POINT* point,int count,POINT p,double& dIndex);
// static int PointInBezierRegion(CPoint2D* point,int count,CPoint2D p,double& dIndex);
// static int PointInBezierRegion(CBezierStyleDrawPointSegmentArray* pSegmentArray,POINT p);
// static int PointInBezierRegion(CBezierStyleMapPointSegmentArray* pSegmentArray,CPoint2D p);
//
// //求点p到Bezier线段的最小距离
// static double GetBezierNearestDistance(CPoint2D a0,CPoint2D a1,CPoint2D a2,CPoint2D a3,CPoint2D p,INTERPOINT& interpoint);
// //求两个Bezier线段的最小距离
// static double GetBezierNearestDistance(CPoint2D a0,CPoint2D a1,CPoint2D a2,CPoint2D a3,CPoint2D b0,CPoint2D b1,CPoint2D b2,CPoint2D b3,INTERPOINT& interpoint);
// //求点p到Bezier曲线的最小距离
// static double GetBezierNearestDistance(CPoint2D* point,int count,BOOL bClose,CPoint2D p,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D* point,int count,BOOL bClose,CPoint2D p0,CPoint2D p1,CPoint2D p2,CPoint2D p3,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D* p0,int count0,BOOL bClose0,CPoint2D* p1,int count1,BOOL bClose1,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D a0,CPoint2D a1,CPoint2D a2,CPoint2D a3,double dHeadIndex,double dEndIndex,CPoint2D p,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D* point,int count,BOOL bClose,double dHeadIndex,double dEndIndex,CPoint2D p,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D* point,int count,BOOL bClose,double dHeadIndex,double dEndIndex,CPoint2D p0,CPoint2D p1,CPoint2D p2,CPoint2D p3,double dHeadIndex1,double dEndIndex1,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D a0,CPoint2D a1,CPoint2D a2,CPoint2D a3,double dHeadIndexa,double dEndIndexa,CPoint2D b0,CPoint2D b1,CPoint2D b2,CPoint2D b3,double dHeadIndexb,double dEndIndexb,INTERPOINT& interpoint);
// static double GetBezierNearestDistance(CPoint2D* p0,int count0,BOOL bClose0,double dHeadIndex0,double dEndIndex0,CPoint2D* p1,int count1,BOOL bClose1,double dHeadIndex1,double dEndIndex1,INTERPOINT& interpoint);
//
// //移动矩形的位置,返回新的矩形位置
// static CRect8 MoveRect(CRect8 rect,CSize8 size);
//
// //判断线段与Bezier曲线是否有交点
// static BOOL IfBezierHaveInterPoint(CPoint2D* p,int count,BOOL bClose,CPoint2D p0,CPoint2D p1);
//
// //求Bezier曲线的交点,返回交点个数
// static int GetBezierInterPoint(CPoint2D* point0,int count0,BOOL bClose0,CPoint2D* point1,int count1,BOOL bClose1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
// static int GetBezierInterPoint(CPoint2D a0,CPoint2D a1,CPoint2D a2,CPoint2D a3,CPoint2D b0,CPoint2D b1,CPoint2D b2,CPoint2D b3,CArray<INTERPOINT,INTERPOINT>& interpointarray);
// static int GetBezierInterPoint(CPoint2D* point0,int count0,BOOL bClose0,double dHeadIndex0,double dEndIndex0,CPoint2D* point1,int count1,BOOL bClose1,double dHeadIndex1,double dEndIndex1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
// static int GetBezierInterPoint(CPoint2D a0,CPoint2D a1,CPoint2D a2,CPoint2D a3,double dHeadIndex0,double dEndIndex0,CPoint2D b0,CPoint2D b1,CPoint2D b2,CPoint2D b3,double dHeadIndex1,double dEndIndex1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
//
// //求Bezier曲线与线段的交点,返回交点个数
// static int GetBezierAndLineInterPoint(CPoint2D* p,int count,BOOL bClose,CPoint2D p0,CPoint2D p1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
// static int GetBezierAndLineInterPoint(CPoint2D p0,CPoint2D p1,CPoint2D p2,CPoint2D p3,CPoint2D point0,CPoint2D point1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
// static int GetBezierAndLineInterPoint(CPoint2D* p,int count,BOOL bClose,double dHeadIndex,double dEndIndex,CPoint2D p0,CPoint2D p1,CArray<INTERPOINT,INTERPOINT>& interpointarray);
//
//
// //得到Bezier曲线的一部分,返回新的Bezier曲线的四个点的位置,dHeadIndex和dEndIndex为新的Bezier曲线的位置索引的范围
// static void GetPartOfBezier(CPoint2D p0,CPoint2D p1,CPoint2D p2,CPoint2D p3,double dHeadIndex,double dEndIndex,CPoint2D& q0,CPoint2D& q1,CPoint2D& q2,CPoint2D& q3);
//
// //判断鼠标是否选种Bezier曲线
// static double BezierLineHitTest(POINT* pPoint,int count,POINT point,BOOL bClosed,GDFLOGPEN* pLogPen=NULL,double dZoomFactor=1.0);
// static double BezierLineHitTest(int accuracy,POINT& p0,POINT& p1,POINT& p2,POINT& p3,POINT point);
//
// //把圆弧转换为Bezier曲线,direction==forward表示从dStartAngle逆时针转到dStopAngle,direction==backward表示顺时针旋转
// static void ConvertArcToBezierLine(CPoint2D p0,double a,double b,double dAngle,double dStartAngle,double dStopAngle,FACIESSEGMENTDIRECTION direction,CArray<CPoint2D,CPoint2D>& pointarray);
// static void ConvertArcToBezierLine(POINT p0,double a,double b,double dAngle,double dStartAngle,double dStopAngle,FACIESSEGMENTDIRECTION direction,CArray<POINT,POINT>& pointarray);
//
// //坐标变换
// //x0,y0为新坐标系在老坐标系中的原点位置
// //angle为新坐标系相对于老坐标系的角度
// //x,y为点在新坐标系中的坐标
// //X,Y为换算出的点在老坐标系中的坐标
// static void ConvertCoordinateNO(double x0,double y0,double angle,double x,double y,double& X,double& Y);
//
// //x0,y0为新坐标系在老坐标系中的原点位置
// //angle为新坐标系相对于老坐标系的角度
// //x,y为点在老坐标系中的坐标
// //X,Y为换算出的点在新坐标系中的坐标
// static void ConvertCoordinateON(double x0,double y0,double angle,double x,double y,double& X,double& Y);
// //把圆弧转换为折线
// static void ConvertArcToPolyline(CPoint2D p0,double a,double b,double dAngle,double dStartAngle,double dStopAngle,FACIESSEGMENTDIRECTION direction,double dStep,CArray<CPoint2D,CPoint2D>& pointarray);
// static void ConvertArcToPolyline(POINT p0,double a,double b,double dAngle,double dStartAngle,double dStopAngle,FACIESSEGMENTDIRECTION direction,double dStep,CArray<POINT,POINT>& pointarray);
//
// static void ConvertRectToBezierLine(CPoint2D p0,double a,double b,double dAngle,CPoint2D roundpoint,CArray<CPoint2D,CPoint2D>& pointarray);
// static void ConvertRectToBezierLine(POINT p0,double a,double b,double dAngle,POINT roundpoint,CArray<POINT,POINT>& pointarray);
//
// static void ConvertRectToPolyline(CPoint2D p0,double a,double b,double dAngle,CPoint2D roundpoint,CArray<CPoint2D,CPoint2D>& pointarray);
// static void ConvertRectToPolyline(POINT p0,double a,double b,double dAngle,POINT roundpoint,CArray<POINT,POINT>& pointarray);
//
// static BOOL HaveIntersection(CRect8& rect0,CRect8& rect1);
//
//
// //求Bezier曲线的控制点
// static void SmoothLine(CPoint2D* pPointArray,BYTE* pbyteSmoothFlag,int count,BOOL bClose);
// static void SmoothOneNode(CPoint2D* pPointArray,BYTE* pbyteSmoothFlag,int count,BOOL bClose,int index);
//
// //求p点过p1,p0线的镜像点,rp为返回的镜像点,返回值为是否存在镜像点
// static BOOL GetMirrorPoint(CPoint2D p1,CPoint2D p2,CPoint2D p,CPoint2D& rp);
//
//private:
// static void AddArray(CPoint2D* d,int count,double startindex,double stopindex,CArray<CPoint2D,CPoint2D>* parray,BOOL bReverse=FALSE);
// static BOOL HaveIntersection(CPoint2D P0,CPoint2D P1,CPoint2D p0,CPoint2D p1);
// static BOOL IsSameDirection(CPoint2D P0,CPoint2D P1,CPoint2D p0,CPoint2D p1);
// static void MoveArrayHeadToEnd(int* p,int count,int movecount);
//
// static void SmoothOneNode(CPoint2D* pPointArray,BYTE* pbyteSmoothFlag,int indexl,int index0,int index1,int index2,int indexr);
};