#pragma once
#include "Mdesk.h"
#include "McGeVector2d.h"
#include "McGeContext.h"
#include "McGeCurve2d.h"
#include "McGeTol.h"
#include "McArray.h"
class McGeVector2d;
class McGeMatrix2d;
class MgeNurbCurve;
// -------------------------------------------------------------------------
// Summary:
// 		二维的样条曲线,非均匀有理的B样条曲线
// -------------------------------------------------------------------------
class MXGEDLL McGeNurbCurve2d: public McGeCurve2d
{
public:
	// -------------------------------------------------------------------------
	// Summary:
	// 		构造函数
	// -------------------------------------------------------------------------
	McGeNurbCurve2d(void);

	//:Ignore
	
	McGeNurbCurve2d(void*);
	

	McGeNurbCurve2d(const McGeNurbCurve2d& src);
	McGeNurbCurve2d&    operator=(const McGeNurbCurve2d& src);
	//:End Ignore

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

	/*
	Mdesk::Boolean  getFitData        (McGePoint2dArray& fitPoints,
		McGeTol& fitTolerance,
		Mdesk::Boolean& tangentsExist,
		McGeVector2d& startTangent, 
		McGeVector2d& endTangent) const;
		*/

	/*
	void set (
		int degree, 
		const OdGeKnotVector& knots,
		const OdGePoint2dArray& controlPoints, 
		const OdGeDoubleArray& weights, 
		bool isPeriodic = false);
		*/

	// -------------------------------------------------------------------------
	// Summary:
	// 		由节点矢量、控制点和权值建构一条2D有理的样条曲线
	// Parameters:
	// 		degree		-	输入样条曲线的阶数
	//		knots		-	输入节点值的数组,将样条曲线的域分解为多项式
	//		cntrlPnts	-	输入任意2D控制点的数组
	//		weights		-	输入权值数组
	//		isPeriodic	-	返回标志表示样条曲线是不是闭合曲线
	// -------------------------------------------------------------------------
	void set (
		int degree, 
		const McGeDoubleArray& knots,
		const McGePoint2dArray& controlPoints, 
		const McGeDoubleArray& weights, 
		bool isPeriodic = false);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回样条线的参数
	// Parameters:
	// 		degree		-	返回样条曲线的阶数
	//		knots		-	返回节点值的数组,将样条曲线的域分解为多项式
	//		cntrlPnts	-	返回任意2D控制点的数组
	//		weights		-	返回权值数组
	//		isPeriodic	-	返回标志表示样条曲线是不是闭合曲线
	// -------------------------------------------------------------------------
	void            getDefinitionData (int& degree, Mdesk::Boolean& rational,
		Mdesk::Boolean& periodic,
		McGeDoubleArray& knots,
		McGePoint2dArray& controlPoints,
		McGeDoubleArray& weights,
		double&          knotTol) const;


	// -------------------------------------------------------------------------
	// Summary:
	// 		从输入拟合点，起点和终点切向矢量和拟合偏差重新计算样条曲线
	// Parameters:
	//		fitPoints				-	输入新的拟合点
	//		startTangent			-	输入新的起点切向矢量
	//		endTangent				-	输入新的终点切向矢量
	//		fitTol					-	输入样条曲线拟合插入点的偏差
	//		isPeriodic				-	是否闭合
	//		isReCalcControlPoint	-	暂没有使用
	// Returns:
	// 		成功返回true
	// -------------------------------------------------------------------------
	McGeNurbCurve2d& setFitData       (const McGePoint2dArray& fitPoints,                                             
		const McGeVector2d& startTangent, 
		const McGeVector2d& endTangent,
		const McGeTol& fitTol=McGeContext::gTol,
		bool periodic = false,
		bool isReCalcControlPoint = true
		
		);

	
	// -------------------------------------------------------------------------
	// Summary:
	// 		返回用于建构样条曲线的所有拟合数据
	// Parameters:
	// 		fitPoints		-	输出插入点的数组
	//		fitTolerance	-	输出样条曲线拟合插入点的偏差
	//		tangentsExist	-	输出标记，表示是否存在有效的起始和终止切向输出
	//		startTangent	-	输出样条曲线的起点切向矢量
	//		endTangent		-	输出样条曲线的终点切向矢量
	// Returns:
	// 		返回该对象的引用
	// -------------------------------------------------------------------------
	Mdesk::Boolean  getFitData        (McGePoint2dArray& fitPoints,
		McGeTol& fitTolerance,
		Mdesk::Boolean& tangentsExist,
		McGeVector2d& startTangent, 
		McGeVector2d& endTangent) const;


	Mdesk::Boolean   set (const McGePoint2dArray& plPoints);

	//:Ignore
	McGeNurbCurve2d&    transformBy (const McGeMatrix2d& xfm);

	double            startParam() const;
	double            endParam() const;
	McGePoint2d       startPoint() const;
	McGePoint2d       endPoint() const;

	bool getPointAtDist_NurbCurve2d(double dDist, McGePoint2d& pt) const;

	MgeCurve* cloneImpObject() const override;

	McGeBoundBlock2d  orthoBoundBlock() const override;

	bool hasFitData() const;

	bool  isClosed() const;

	void getControlPointAt(int iIndex, McGePoint2d& point) const;

	void setControlPointAt(int iIndex, const McGePoint2d& point);

	int numControlPoints() const;
private:
	//:End Ignore
};
