#pragma once
#include "McDbEntity.h"
// -------------------------------------------------------------------------
// Summary:
// 		曲线类型，实现了曲线的相关操作，如求曲线的长度，最近点，面积，曲线上任一点在曲线上的长度
//		切向方向，曲线交点，坐标变换，打断，偏移，离散等功能
// Remarks:
// 		例如:偏移曲线代码
// 		<code>
// 			void CTestCommands::OffsetPolyline()
// 			{
// 				ads_name entName;
// 				ads_point pt;
// 				if(acedEntSel(_T("需要偏移的PL线:"),entName,pt) != RTNORM)
// 				{
// 					return;
// 				}
// 
// 				AcDbObjectId objId;
// 				if(acdbGetObjectId(objId,entName) != Acad::eOk)
// 					return;
// 
// 				McDbObjectPointer<McDbPolyline> spPolyline(objId,AcDb::kForRead);
// 				if(spPolyline.openStatus() != Acad::eOk)
// 				{
// 					acutPrintf(_T("\n 请选择Polyline"));
// 					return;
// 				}
// 
// 
// 				ads_point tmpPt1;
// 				if(acedGetPoint(NULL,_T("\n 点取偏移点："),tmpPt1) != RTNORM)
// 				{
// 					return;
// 				}
// 
// 				ads_point tmpPt2;
// 				if(acedGetPoint(tmpPt1,_T("\n 点取偏移距离："),tmpPt2) != RTNORM)
// 				{
// 					return;
// 				}
// 
// 				McGePoint3d pt1 = asPnt3d(tmpPt1);
// 				McGePoint3d pt2 = asPnt3d(tmpPt2);
// 
// 				mxreal dDis = pt1.distanceTo(pt2);
// 				if(fabs(dDis) < 0.01)
// 				{
// 					acutPrintf(_T("\n 偏移距离为太小"));
// 					return;
// 				}
// 
// 				McGePoint3d ptRef = pt1;
// 				McDbVoidPtrArray offsetCurves;
// 
// 				if(spPolyline->getOffsetCurvesEx(dDis,offsetCurves,ptRef) != Mcad::eOk)
// 				{
// 					acutPrintf(_T("\n 未知原因，偏移失败"));
// 					return;
// 				}
// 
// 				// 对偏移后的PL线，按偏移距离，把突出的角导圆角。
// 				McGePoint3d startPt;
// 				spPolyline->getStartPoint(startPt);
// 
// 				for(int i = 0 ; i < offsetCurves.length();i++)
// 				{
// 					McDbEntity* pEnt = (McDbEntity*)(offsetCurves[i]);
// 					ASSERT(pEnt != NULL);
// 
// 					if(McDbPolyline::cast(pEnt) != NULL)
// 					{
// 						McDbPolyline* pNewPolyline = GetNewPolyline(startPt,McDbPolyline::cast(pEnt),dDis );
// 						if(pNewPolyline != NULL)
// 						{
// 							MrxDbgUtils::addToCurrentSpace(pNewPolyline);
// 							pNewPolyline->close();
// 							delete pEnt;
// 							pEnt = NULL;
// 						}
// 
// 					}
// 
// 					if(pEnt != NULL)
// 					{
// 						MrxDbgUtils::addToCurrentSpaceAndClose(pEnt);
// 					}
// 				}
// 			}
// 		</code>
//		求曲线的长度
// 		<code>
// 			void GetCurveLenght()
// 			{
// 				ads_name entName;
// 				ads_point pt;
// 				if(acedEntSel(_T("选择曲线:"),entName,pt) != RTNORM)
// 				{
// 					return;
// 				}
// 
// 				AcDbObjectId objId;
// 				if(acdbGetObjectId(objId,entName) != Acad::eOk)
// 					return;
// 
// 				McDbObjectPointer<McDbCurve> spCurve(objId,AcDb::kForRead);
// 				if(spCurve.openStatus() != Acad::eOk)
// 				{
// 					acutPrintf(_T("\n 请选择曲线"));
// 					return;
// 				}
// 
// 				mxreal dEndParam = 0.0;
// 				spCurve->getEndParam(dEndParam);
// 
// 				mxreal dist = 0.0;
// 				spCurve->getDistAtParam(dEndParam,dist);
// 
// 				MxString sT;
// 				sT.Format(_T("曲线的上度:%lf"),dist);
// 				AfxMessageBox(sT);
// 			}
// 		</code>
// -------------------------------------------------------------------------
class ARXDLL McDbCurve : public McDbEntity
{
protected:

	McDbCurve(McDbEntityImp* pImp);
public:
	// -------------------------------------------------------------------------
	// Summary:
	// 		申明类型信息
	// -------------------------------------------------------------------------
	MCDB_DECLARE_MEMBERS(McDbCurve);

	// -------------------------------------------------------------------------
	// Summary:
	// 		构造函数
	// -------------------------------------------------------------------------
	McDbCurve();

	// -------------------------------------------------------------------------
	// Summary:
	// 		析构函数
	// -------------------------------------------------------------------------
	virtual ~McDbCurve();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的开始参数
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getStartParam(mxreal&) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的结束参数
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getEndParam  (mxreal&) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的开始点
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getStartPoint(McGePoint3d&) const;


	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线的结束点
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getEndPoint  (McGePoint3d&) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到指定参数在曲线上的点坐标
	// Parameters:
	// 		param	-		曲线上的参数
	//		pt		-		返回曲线的点
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getPointAtParam(mxreal param, McGePoint3d& pt) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线上一点在曲线上的参数
	// Parameters:
	// 		param	-		返回曲线上的参数
	//		pt		-		曲线的点
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getParamAtPoint(const McGePoint3d& pt, mxreal& param)const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回指定参数在曲线上，到开始点的曲线上长度
	// Parameters:
	// 		param		-	曲线参数
	//		dist		-	返回到开始点的曲线上长度
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getDistAtParam (mxreal param, mxreal& dist) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线上到开始点的曲线长度对应的曲线参数
	// Parameters:
	// 		dist	-	到开始点的曲线上长度
	//		param	-	返回曲线参数
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getParamAtDist (mxreal dist, mxreal& param) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		由曲线上的一点返回该点到曲线开始点的长度
	// Parameters:
	// 		pt		-	曲线上的一点
	//		dist	-	返回到开始点的曲线上长度
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getDistAtPoint (const McGePoint3d& pt, mxreal& dist)const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线上到开始点的曲线长度对应的在曲线上的点
	// Parameters:
	// 		pt		-	返回曲线上的一点
	//		dist	-	到开始点的曲线上长度
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getPointAtDist (mxreal dist, McGePoint3d& pt) const;


	// -------------------------------------------------------------------------
	// Summary:
	// 		求曲线参数所在位置的一价导数,这就是切向方向
	// Parameters:
	// 		param		-	曲线参数
	//		firstDeriv	-	返回切向方向
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getFirstDeriv  (mxreal param,
		McGeVector3d& firstDeriv) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		给一个点位置求一价导数,这就是切向方向
	// Parameters:
	// 		pt			-	曲线上的点
	//		firstDeriv	-	返回切向方向
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getFirstDeriv  (const McGePoint3d& pt,
		McGeVector3d& firstDeriv) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		求曲线周围一点到曲线上的最近点
	// Parameters:
	// 		givenPnt		-	任一点
	//		pointOnCurve	-	曲线上的最近点
	//		extend			-	暂没有使用,现在曲线不会延伸
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getClosestPointTo(const McGePoint3d& givenPnt,
		McGePoint3d& pointOnCurve,
		Mdesk::Boolean extend
		= Mdesk::kFalse) const;

	//:Ignore

	virtual Mcad::ErrorStatus getClosestPointTo(const McGePoint3d& givenPnt,
		const McGeVector3d& direction,
		McGePoint3d& pointOnCurve,
		Mdesk::Boolean extend
		= Mdesk::kFalse) const;



	virtual Mcad::ErrorStatus getOffsetCurves(mxreal offsetDist,
		McDbVoidPtrArray& offsetCurves) const;
	//:End Ignore

	// -------------------------------------------------------------------------
	// Summary:
	// 		曲线偏移
	// Parameters:
	// 		offsetDist		-	偏移距离
	//		offsetCurves	-	返回偏移后生成的新曲线
	//		ptOffsetRef		-	偏移方向参考点，曲线向该点所在位置偏移
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getOffsetCurvesEx(mxreal offsetDist,
		McDbVoidPtrArray& offsetCurves,McGePoint3d ptOffsetRef) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		打断曲线
	// Parameters:
	// 		params			-	打断位置数组
	//		curveSegments	-   返回打断后生成的新曲线
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getSplitCurves (const McGeDoubleArray& params,
		McDbVoidPtrArray& curveSegments) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		打断曲线
	// Parameters:
	// 		points			-	打断位置点数组
	//		curveSegments	-   返回打断后生成的新曲线
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getSplitCurves (const McGePoint3dArray& points,
		McDbVoidPtrArray& curveSegments) const;


	// -------------------------------------------------------------------------
	// Summary:
	// 		返回曲线组成的闭合区域的面积
	// Parameters:
	// 		dArea		-	返回面积
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	virtual Mcad::ErrorStatus getArea(mxreal& dArea) const;

	//:Ignore

	virtual Mcad::ErrorStatus dwgInFields (McDbDwgFiler* pFiler);

	virtual Mcad::ErrorStatus dwgOutFields(McDbDwgFiler* pFiler) const;

	virtual Mcad::ErrorStatus getSamplePoints(
		mxreal approxEps, McGePoint3dArray& pointArray,
		McGeDoubleArray& paramArray) const;
	//:End Ignore
};