/*
文件名：Appfun.cpp
描述：  用于实现构件库的各项功能
*/
	
// WZH modified.  2000年11月3日.

#include "StdAfx.h"
#include "FuncDef.h"
#include "Resource.h"
#include "eb_api.h"
#include "math.h"

#define   EQU 1
#define   NOTEQU 0
#define   ZERO   0.00001
#define   ZERO1  -0.00001

void GenGrooveByPickEdge(const double paraL,const double paraH,
						 EB_NODE &firstline,EB_NODE &secondline);

void GenGrooveOnSingleEdge(const double paraL,const double paraH,
						   EB_NODE &firstline,EB_NODE &secondline);

void GenHoleByTwoEdge(EB_NODE &firstline,EB_NODE &secondline,
					  const double paraH);

void GenHoleByOneEdge(EB_NODE &firstline,EB_NODE &secondline,
					  const double paraH);

void GenHoleGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
				   const double paraH,const double paraL,const double paraW=0.0);

void GenHoleArcGroove(EB_NODE firstline,EB_NODE secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraR);

void GenHoleArcGroove_s(EB_NODE firstline,EB_NODE secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraR);

void GenAxisGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraW=0.0);

void GenAxisArcGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraR);

void GenAxisArcGroove_s(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
						const double paraH,const double paraL,const double paraR);

void GenAxisAngGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					  const double paraH,const double paraL,double paraA,const double paraT);

int DecideLineEndPoint(const EB_NODE firstline,const EB_NODE secondline,
						EB_POINT &p1,EB_POINT &p2,EB_POINT &p3);

BOOL DecideEndPoint(const EB_NODE firstline,const EB_NODE secondline,const EB_NODE endline,
                    EB_POINT &p2,EB_POINT &p4,EB_POINT &p7,EB_POINT &p8);

static EB_POINT pk1,pk2;     //用鼠标交互拾取的第一和第二点,全局变量

/*
函数名：AppGenerateGrooveByTwoEdge
描述：  此函数用于实现通过拾取的两条相交的边
        来生成槽功能的交互拾取部分。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateGrooveByTwoEdge(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraD=15.0;//paraD是槽的深度参数
	static double paraW=15.0;//paraW是槽的宽度参数
	int ret=0;
	static EB_POINT sp1,ep1,sp2,ep2;//sp为边始端点,ep为边终点.
	static EB_NODE firstline;
	static EB_NODE secondline;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebGetMenuReal("槽宽度W:",&paraW,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取第一条边：");
		break;
	case 1://交互拾取第一条边
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)  //用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//无效拾取，退回上一步；
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取第二条边：");
		ebRegisterPopMenu();
		break;
	case 2://交互拾取第二条边
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//无效拾取，退回上一步
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO

		GenGrooveByPickEdge(paraD,paraW,firstline,secondline);//生成槽		
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
}
/*
函数名：GenGrooveByPickEdge
描述：  此函数是实现通过拾取的边来生成槽。
参数说明：paraL，paraH是槽的两个参数值，firstline是第一条边，
          secondline是拾取的第二条边。
返回值： 无
*/

void GenGrooveByPickEdge(const double paraL,const double paraH,
				EB_NODE &firstline,EB_NODE &secondline)
{
//p1记录两线交点，p2记录第一条边另一端点,p3记录第二条边另一端点
	EB_POINT p1,p2,p3;
//angl为两线夹角,angl1为第一条边与X轴夹角,angl2为第二条边与X轴夹角;
	double angl,angl1,angl2;
//point1,point2,point3,point4为槽的四个角点
	EB_POINT point1,point2,point3,point4;
//line1,line2,line3为槽的三条边，orgline1，orgline2为原来的交线
	static EB_NODE line1,line2,line3,orgline1,orgline2;
    int ret=0;  //返回值
	ret=DecideLineEndPoint(firstline,secondline,p1,p2,p3);
	if(ret!=1)    //无交点时
	{
		if(ret==2)
		{
			AfxMessageBox("出错：两直线不能相交！",0,0);
		}
		else if(ret==3)
		{
			AfxMessageBox("出错：拾取的是同一条直线！",0,0);
		}
		else if(ret==4)
		{
			AfxMessageBox("内存不足！",0,0);

		}
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);  //恢复正常显示
		ebEndCommand();
		return;
	}
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p1,p3);
	angl=angl1-angl2;
	if(angl<0) angl=fabs(angl);
	double dist=0.0;
	dist=(paraH/2.0)/sin(angl/2.0);
//计算槽的角点。
	point1.x=p1.x+dist*cos(angl1);point1.y=p1.y+dist*sin(angl1);
	point2.x=p1.x+dist*cos(angl2);point2.y=p1.y+dist*sin(angl2);
	double angle=(angl1+angl2)/2.0;//angle为两线夹角平分线与X轴夹角
	if(angl<PI) angle=angle+PI;
	else if(angl>PI) angle=angle;
//计算角点
	point3.x=point1.x+paraL*cos(angle);point3.y=point1.y+paraL*sin(angle);
	point4.x=point2.x+paraL*cos(angle);point4.y=point2.y+paraL*sin(angle);
//将原拾取的边从系统链中删除
	ebDelNodeFromSys(firstline,FALSE);
	ebDelNodeFromSys(secondline,FALSE);
//生成新的边，并添加进系统链
	orgline1=ebBuildLine(p2,point1);
	ebInsNodeToSys(orgline1);
	orgline2=ebBuildLine(p3,point2);
	ebInsNodeToSys(orgline2);
	line1=ebBuildLine(point1,point3);
	ebInsNodeToSys(line1);
	line2=ebBuildLine(point2,point4);
	ebInsNodeToSys(line2);
	line3=ebBuildLine(point3,point4);
	ebInsNodeToSys(line3);
	
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}

/*
函数名： AppGenerateGrooveByOneEdge
描述：   此函数实现通过拾取两条相交的边，在第一条边上开槽中的
         交互拾取与参数填写功能。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateGrooveByOneEdge(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraD=5.0;//paraD 是深度参数
	static double paraW=5.0;//paraW 是宽度参数
	int ret=0;
	static EB_POINT sp1,ep1,sp2,ep2;//sp为边始端点,ep为边终点.
	static EB_NODE firstline;
	static EB_NODE secondline;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebGetMenuReal("槽宽度W:",&paraW,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取开槽边：");
		break;
	case 1://交互拾取第一条边
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//无效拾取退回上一步
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取参考边：");
		break;
	case 2://交互拾取第二条边
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenGrooveOnSingleEdge(paraD,paraW,firstline,secondline);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
}
/*
函数名：GenGrooveOnSingleEdge
描述：  此函数实现拾取了两条边，而在第一条边上开槽的功能。
参数描述：paraL,paraH 是槽的深度和宽度参数，firstline 是开槽边
          secondline 是参考边；
返回值： 无
*/
void GenGrooveOnSingleEdge(const double paraL,const double paraH,
						   EB_NODE &firstline,EB_NODE &secondline)
{
//p1记录两线交点，p2记录第一条边另一端点,p3记录第二条边另一端点
	EB_POINT p1,p2,p3;
//angl1为第一条边与X轴夹角,angl2为第二条边与X轴夹角;
	double angl1,angl2;
//point1,point2,point3为槽的三个角点
	EB_POINT point1,point2,point3;
//line1,line2,line3为槽的三条边，orgline1，orgline2为原来的交线
	static EB_NODE line1,line2,orgline1,orgline2;
    int ret=0;  //返回值
	ret=DecideLineEndPoint(firstline,secondline,p1,p2,p3);
	if(ret!=1)    //无交点时
	{
		if(ret==2)
		{
			AfxMessageBox("出错：两直线不能相交！",0,0);
		}
		else if(ret==3)
		{
			AfxMessageBox("出错：拾取的是同一条直线！",0,0);
		}
		else if(ret==4)
		{
			AfxMessageBox("内存不足！",0,0);

		}
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);  //恢复正常显示
		ebEndCommand();
		return;
	}
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p1,p3);
//计算槽的位置点
	point1.x=p1.x-paraL*cos(angl2);point1.y=p1.y-paraL*sin(angl2);
	point2.x=p1.x+paraH*cos(angl1);point2.y=p1.y+paraH*sin(angl1);
	point3.x=point2.x-paraL*cos(angl2);point3.y=point2.y-paraL*sin(angl2);
//将原边从系统链中删除
	ebDelNodeFromSys(firstline,FALSE);
	ebDelNodeFromSys(secondline,FALSE);
//生成新的边并添加入系统链
	orgline1=ebBuildLine(p2,point2);
	ebInsNodeToSys(orgline1);
	orgline2=ebBuildLine(p3,point1);
	ebInsNodeToSys(orgline2);
	line1=ebBuildLine(point1,point3);
	ebInsNodeToSys(line1);
	line2=ebBuildLine(point2,point3);
	ebInsNodeToSys(line2);
//		
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：AppGenerateHoleByTwoEdge
描述：  此函数实现在拾取的两条边上产生双面止锁空的
        交互拾取与参数的填写部分。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateHoleByTwoEdge(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraR=5.0;//槽的半径参数
	static EB_POINT sp1,ep1,sp2,ep2;//sp为边始端点,ep为边终点.
	static EB_NODE firstline;
	static EB_NODE secondline;
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("孔半径R:",&paraR,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取第一条边：");
		break;
	case 1://交互拾取第一条边
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		
		ebClearPrompt();
		ebPrompt("请拾取第二条边：");
		break;
	case 2://交互拾取第二条边
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenHoleByTwoEdge(firstline,secondline,paraR);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
}
/*
函数名：GenHoleByTwoEdge
描述：  此函数是通过拾取两条边在两边上产生两边止锁孔的实现部分。
参数说明：firstline 是拾取的第一条边，secondline 是拾取的第二
          条边，paraH 是孔的半径参数。
返回值：无
*/
void GenHoleByTwoEdge(EB_NODE &firstline,EB_NODE &secondline,
					  const double paraH)
{
//p1记录两线交点，p2记录第一条边另一端点,p3记录第二条边另一端点
	EB_POINT p1,p2,p3;
//angl1为第一条边与X轴夹角,angl2为第二条边与X轴夹角;
	double angl1,angl2;
//point1,point2孔的两个角点,point3为三点方式建立园弧的中间点
	EB_POINT point1,point2,point3;
//holearc为孔轮廓，orgline1，orgline2为原来的交线
	static EB_NODE holearc,orgline1,orgline2;
    int ret=0;  //返回值
	ret=DecideLineEndPoint(firstline,secondline,p1,p2,p3);
	if(ret!=1)    //无交点时
	{
		if(ret==2)
		{
			AfxMessageBox("出错：两直线不能相交！",0,0);
		}
		else if(ret==3)
		{
			AfxMessageBox("出错：拾取的是同一条直线！",0,0);
		}
		else if(ret==4)
		{
			AfxMessageBox("内存不足！",0,0);

		}
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);  //恢复正常显示
		ebEndCommand();
		return;
	}
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p1,p3);
//计算槽的角点
	point1.x=p1.x+paraH*cos(angl1);point1.y=p1.y+paraH*sin(angl1);
	point2.x=p1.x+paraH*cos(angl2);point2.y=p1.y+paraH*sin(angl2);
	point3.x=p1.x-paraH*cos(angl1);point3.y=p1.y-paraH*sin(angl1);
//将原边从系统链中删除
	ebDelNodeFromSys(firstline,FALSE);
	ebDelNodeFromSys(secondline,FALSE);
//生成新的边并添加入系统链
	orgline1=ebBuildLine(p2,point1);
	ebInsNodeToSys(orgline1);
	orgline2=ebBuildLine(p3,point2);
	ebInsNodeToSys(orgline2);
	holearc=ebBuildPsP2PeArc(point1,point3,point2);
	ebInsNodeToSys(holearc);
//		
	ebRedraw();
	ebClearMenu();
	ebEndCommand();	
}
/*
函数名：AppGenerateHoleByOneEdge
描述：  此函数是实现通过拾取两条边在一条边上产生
        单边止锁孔的交互拾取与参数填写部分。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateHoleByOneEdge(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraR=5.0;//槽的半径参数
	static EB_POINT sp1,ep1,sp2,ep2;//sp为边始端点,ep为边终点.
	static EB_NODE firstline;
	static EB_NODE secondline;
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("孔半径R:",&paraR,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取开孔边：");
		break;
	case 1://交互拾取第一条边
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//无效拾取
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取参考条边：");
		break;
	case 2://交互拾取第二条边
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenHoleByOneEdge(firstline,secondline,paraR);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;	
}
/*
函数名：GenHoleByOneEdge
描述：  此函数是拾取两条边在一边产生单边止锁孔的实现部分。
参数说明：firstline 是开孔边，secondline 是参考边。paraH是
          孔的半径参数。
返回值：无
*/
void GenHoleByOneEdge(EB_NODE &firstline,EB_NODE &secondline,
					  const double paraH)
{
//p1记录两线交点，p2记录第一条边另一端点,p3记录第二条边另一端点
	EB_POINT p1,p2,p3;
//angl1为第一条边与X轴夹角,angl2为第二条边与X轴夹角;
	double angl1,angl2;
//point1,point2孔的两个角点,point3为三点方式建立圆弧的中间点
	EB_POINT point1,point2,point3;
//holearc为孔轮廓，orgline1，orgline2为原来的交线
	static EB_NODE holearc,orgline1,orgline2;
    int ret=0;  //返回值
	ret=DecideLineEndPoint(firstline,secondline,p1,p2,p3);
	if(ret!=1)    //无交点时
	{
		if(ret==2)
		{
			AfxMessageBox("出错：两直线不能相交！",0,0);
		}
		else if(ret==3)
		{
			AfxMessageBox("出错：拾取的是同一条直线！",0,0);
		}
		else if(ret==4)
		{
			AfxMessageBox("内存不足！",0,0);

		}
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);  //恢复正常显示
		ebEndCommand();
		return;
	}
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p1,p3);
//计算槽的角点
	point1.x=p1.x+2.0*paraH*cos(angl1);point1.y=p1.y+2.0*paraH*sin(angl1);
	point2.x=p1.x;point2.y=p1.y;
	point3.x=(point1.x+point2.x)/2.0-paraH*cos(angl2);point3.y=(point1.y+point2.y)/2.0-paraH*sin(angl2);
//将开槽边从系统链中删除
	ebDelNodeFromSys(firstline,FALSE);
	ebDelNodeFromSys(secondline,FALSE);
//生成新的边，并添加入系统链
	orgline1=ebBuildLine(p2,point1);
	ebInsNodeToSys(orgline1);
	orgline2=ebBuildLine(p3,point2);
	ebInsNodeToSys(orgline2);
	holearc=ebBuildPsP2PeArc(point1,point3,point2);
	ebInsNodeToSys(holearc);
//		
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：AppGenerateGrooveOnEndSurface
描述：  此函数是实现在孔的端部开槽的交互拾取与参数填写部分。
        具体是先拾取孔的两轮廓，再拾取孔的端面线。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateGrooveOnEndSurface(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraW=75.0;//槽的宽度参数
	static double paraD=15.0;//槽的深度参数
	EB_POINT pk3;  //鼠标拾取的第三点
	static EB_NODE firstline;
	static EB_NODE secondline;
//孔的端面线
	static EB_NODE endline;
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽直径W:",&paraW,ZERO,1000.0);
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取孔的一条轮廓线：");
		ebRegisterPopMenu();
		break;
	case 1://交互拾取第一条边
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取孔的另一条轮廓线：");
		break;
	case 2://交互拾取第二条边
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取孔的端面线：");
		break;
	case 3://交互拾取端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenHoleGroove(firstline,secondline,endline,
			           paraW,paraD);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
	
}
/*
函数名：GenHoleGroove
描述：  此函数是孔中开槽的实现部分。
参数说明：firstline, secondline 是孔的两条轮廓边，endline 是孔的端面线
          paraH,paraL 是槽的参数，paraW 是槽距离，当 paraW=0 时，表示是
		  槽在孔的端面。
返回值：无
*/
void GenHoleGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
				   const double paraH,const double paraL,const double paraW)				   
{
//三直线与X夹角
	double angl1,angl2,angl3;
//轮廓线与端面线夹角
	double angle1,angle2;
//两轮廓线夹角
	double angl;
//sp 为起点，ep 为终点
	EB_POINT sp1,ep1,sp2,ep2;
	//p1,p3,p5,p6 为槽的角点，p2,p4,p7.p8 为新的边的顶点。
	EB_POINT p1,p2,p3,p4;
	EB_POINT p5,p6,p7,p8;//paraW 不为零时有用；
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;

	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数判断拾取的部分是不是为孔
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	//通过判断p7为第一条边与端面交点,p2为第一条轮廓另一端点
	p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	//通过判断p8为第一条边与端面交点
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p1,p3);
	double dist1=ebCalTwoPtDis(p1,p2);
	if(dist>paraH||dist1<paraL)//判断参数是否合适
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//判断轮廓线与端面线成角度来判断是不是为孔
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO) //两直线平行且不重合
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//miopoint,midpoint1 为槽两端面线中点，point1,point2,point3,point4 为槽的角点
	EB_POINT midpoint,midpoint1,point1,point2,point3,point4;
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);
	angle=fabs((angl1+angl2)/2.0);
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
//if paraW!=0，将对轴心点平移；
	midpoint.x=midpoint.x+paraW*cos(angle);midpoint.y=midpoint.y+paraW*sin(angle);
//计算槽的角点
	point1.x=midpoint.x+paraH*cos(angl3)/2.0;point1.y=midpoint.y+paraH*sin(angl3)/2.0;
	point3.x=midpoint.x-paraH*cos(angl3)/2.0;point3.y=midpoint.y-paraH*sin(angl3)/2.0;
	point2.x=point1.x+paraL*cos(angle);point2.y=point1.y+paraL*sin(angle);
	point4.x=point3.x+paraL*cos(angle);point4.y=point3.y+paraL*sin(angle);
	
	midpoint1.x=(point2.x+point4.x)/2.0;midpoint1.y=(point2.y+point4.y)/2.0;
//line1,line2,line3 为新添加的边,orgline1,orgline2 作为取代原轮廓边的新边	
	EB_NODE line1,line2,line3,orgline1,orgline2;
	EB_NODE line4,orgline3,orgline4;//只在paraW不为零时起作用
//生成新的边
	line3=ebBuildLine(point2,point4);
	line4=ebBuildLine(point1,point3);
//判断槽端面与孔的轮廓线交点的距离与槽宽比较，如果距离大于槽宽则无法开槽。
	int count1;
	pisp1=ebInterSection(line3,firstline,&count);
	dist=ebCalTwoPtDis(pisp1[0],midpoint1);
	pisp2=ebInterSection(line4,firstline,&count1);
	dist1=ebCalTwoPtDis(pisp2[0],midpoint);
	if(dist>paraH/2.0||dist1>paraH/2.0)//判断paraL参数是否合适
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	p1=pisp1[0];
	p5=pisp2[0];
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	count=1;count1=1;
	pisp1=ebInterSection(line3,secondline,&count);
	dist=ebCalTwoPtDis(pisp1[0],midpoint1);
	pisp2=ebInterSection(line4,secondline,&count1);
	dist1=ebCalTwoPtDis(pisp2[0],midpoint);
	if(dist>paraH/2.0||dist1>paraH/2.0)//判断paraL参数是否合适
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	p3=pisp1[0];
	p6=pisp2[0];
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	if(paraW!=0.0)//在孔的中部开槽
	{
		ebInsNodeToSys(orgline3);
		ebInsNodeToSys(orgline4);
		ebInsNodeToSys(line4);
	}
//生成新的边
	line1=ebBuildLine(point1,point2);
	line2=ebBuildLine(point3,point4);
//将原轮廓边从系统链中删除，并将新的边入链
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(line1);
	ebInsNodeToSys(line2);
	ebInsNodeToSys(line3);
	if(fabs(paraW-0.0)<ZERO)
	{
		EB_NODE surfaceline;
		surfaceline=ebBuildLine(point1,point3);
		ebInsNodeToSys(surfaceline);
	}
//
	ebDrawNode(endline,NORMAL);
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：AppGenerateGrooveOnMid
描述：  此函数是实现在孔的中部开槽中的轮廓交互拾取和参数填写部分。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateGrooveOnMid(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraW=75.0;//槽宽度
	static double paraD=15.0;//槽深度
	static double paraL=20.0;//槽距端面距离
	EB_POINT pk3;
	static EB_NODE firstline;
	static EB_NODE secondline;
//孔的端面线
	static EB_NODE endline;
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽直径W:",&paraW,ZERO,1000.0);
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebGetMenuReal("槽端距L:",&paraL,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取孔的一条轮廓线：");
		break;
	case 1://交互拾取第一条轮廓
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取孔的另一条轮廓线：");
		break;
	case 2://交互拾取第二条轮廓
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取孔的端面线：");
		break;
	case 3://拾取孔的端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenHoleGroove(firstline,secondline,endline,
			          paraW,paraD,paraL);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
}
/*
函数名：AppGenerateArcGrooveOnMid
描述：  此函数是实现在孔中部开圆弧槽的轮廓交互拾取与参数填写
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateArcGrooveOnMid(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraL=20.0;//槽距端面距离
	static double paraD=10.0;//槽的深度
	static double paraR=5.0;//圆弧半径
	EB_POINT pk3;  //鼠标拾取的第三点
	static EB_NODE firstline;
	static EB_NODE secondline;
//孔的端面线
	static EB_NODE endline;
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽端距L:",&paraL,ZERO,500.0);
		ebGetMenuReal("槽深度D:",&paraD,ZERO,500.0);
		ebGetMenuReal("圆弧半径R:",&paraR,ZERO,500.0);
		ebClearPrompt();
		ebPrompt("请拾取孔的一条轮廓线：");
		break;
	case 1://交互拾取第一条轮廓
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取孔的另一条轮廓线：");
		break;
	case 2://交互拾取第二条轮廓
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取孔的端面线：");
		break;
	case 3://交互拾取端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		if(paraD>paraR)//当槽深度大于槽的圆弧半径
			GenHoleArcGroove(firstline,secondline,endline,
				          paraL,paraD,paraR);
		else if(paraD<=paraR)//当槽的深度不大于槽的圆弧半径
			GenHoleArcGroove_s(firstline,secondline,endline,
			               paraL,paraD,paraR);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
	
}
/*
函数名：GenHoleArcGroove
描述：  此函数实现在孔的中部生成弧型退刀槽功能。但此函数只实现当
        paraL 参数大于 paraR 参数时的功能。(paraL>paraR)
参数说明：firstline,secondline 是孔的两个轮廓边，endline 是孔的端面边，
          paraH 是槽距离孔端面的距离，paraL 是槽的深度，paraR 是槽的圆弧半径。
返回值：无
*/
void GenHoleArcGroove(EB_NODE firstline,EB_NODE secondline,const EB_NODE endline,
					 const double paraH,const double paraL,const double paraR)
{
	double angl1,angl2,angl3;//三直线与X夹角
	double angle1,angle2;//轮廓线与端面线夹角
	double angl;//两轮廓夹角
	EB_POINT sp1,ep1,sp2,ep2;//sp 为起点 ep 为终点
	EB_POINT p1,p2,p3,p4;//新边的起点与终点
	EB_POINT p5,p6,p7,p8;//新边的起点与终点
	EB_POINT arcp1,arcp2;
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数来判断拾取部分是不是孔
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
    p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
  //
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p1,p3);
	double dist1=ebCalTwoPtDis(p1,p2);
	if(dist1<2.0*paraR)//如果轮廓线小于圆弧直径则无法开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//判断轮廓线与端面线成角度来判断拾取部分是不是孔
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	//midpoint,midpoint1,midpoint2 为槽的端面线的中点，
	//point1,point2,point3,point4 为槽的角点
	EB_POINT midpoint,midpoint1,midpoint2,point1,point2,point3,point4;
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);//求出两轮廓夹角
	angle=fabs((angl1+angl2)/2.0);//两轮廓夹角平分线
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
//if paraH!=0，将对轴心点平移；
	midpoint.x=midpoint.x+paraH*cos(angle);midpoint.y=midpoint.y+paraH*sin(angle);

	EB_POINT temppoint1,temppoint2;
	EB_NODE templine;
	temppoint1.x=midpoint.x+500.0*cos(angl3);temppoint1.y=midpoint.y+500.0*sin(angl3);
	temppoint2.x=midpoint.x-500.0*cos(angl3);temppoint2.y=midpoint.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p5=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p6=pisp1[0];
	dist=ebCalTwoPtDis(p5,p6);
//求出槽的角点
	point1.x=midpoint.x+(paraL+dist/2.0-paraR)*cos(angl3);point1.y=midpoint.y+(paraL+dist/2.0-paraR)*sin(angl3);
	point3.x=midpoint.x-(paraL+dist/2.0-paraR)*cos(angl3);point3.y=midpoint.y-(paraL+dist/2.0-paraR)*sin(angl3);
	point2.x=point1.x+2.0*paraR*cos(angl1);point2.y=point1.y+2.0*paraR*sin(angl1);
	point4.x=point3.x+2.0*paraR*cos(angl2);point4.y=point3.y+2.0*paraR*sin(angl2);

	midpoint1.x=(point2.x+point4.x)/2.0;midpoint1.y=(point2.y+point4.y)/2.0;
	midpoint2.x=(midpoint1.x+midpoint.x)/2.0;midpoint2.y=(midpoint1.y+midpoint.y)/2.0;
//新线
	EB_NODE arc1,arc2,line3,orgline1,orgline2;
	EB_NODE line4,orgline3,orgline4;
//生成新的边
	line3=ebBuildLine(point2,point4);
	line4=ebBuildLine(point1,point3);
	int count1;
	pisp1=ebInterSection(line3,firstline,&count);
	p1=pisp1[0];
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	count=1;count1=1;
	pisp1=ebInterSection(line3,secondline,&count);
	dist=ebCalTwoPtDis(pisp1[0],midpoint1);
	p3=pisp1[0];
	dist1=ebCalTwoPtDis(p3,p1);
//生成新的边，并入系统链
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	ebInsNodeToSys(orgline3);
	ebInsNodeToSys(orgline4);
	ebInsNodeToSys(line4);
	
	dist=ebCalTwoPtDis(p1,p3);dist1=ebCalTwoPtDis(p5,p6);
	dist=(dist+dist1)/2.0;
	arcp1.x=midpoint2.x+(dist/2.0+paraL)*cos(angl3);arcp1.y=midpoint2.y+(dist/2.0+paraL)*sin(angl3);
	arcp2.x=midpoint2.x-(dist/2.0+paraL)*cos(angl3);arcp2.y=midpoint2.y-(dist/2.0+paraL)*sin(angl3);
//生成圆弧边并入链。删除原轮廓边
	arc1=ebBuildPsP2PeArc(point1,arcp1,point2);
	arc2=ebBuildPsP2PeArc(point3,arcp2,point4);
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(arc1);
	ebInsNodeToSys(arc2);
	ebInsNodeToSys(line3);
//
	ebDrawNode(endline,NORMAL);
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：GenHoleArcGroove_s
描述：  此函数实现在孔的中部生成弧型退刀槽功能。但此函数只实现当
        paraL 参数小于 paraR 参数时的功能。(paraL<paraR)
参数说明：firstline,secondline 是孔的两个轮廓边，endline 是孔的端面边，
          paraH 是槽距离孔端面的距离，paraL 是槽的深度，paraR 是槽的圆弧半径。
返回值：无
*/
void GenHoleArcGroove_s(EB_NODE firstline,EB_NODE secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraR)
{
	double angl1,angl2,angl3;//三直线与X夹角
	double angle1,angle2;//轮廓线与端面线夹角
	double angl;//两轮廓夹角
	EB_POINT sp1,ep1,sp2,ep2;//sp 为起点，ep 为终点
	EB_POINT p1,p2,p3,p4;//新边端点
	EB_POINT p5,p6,p7,p8;//新边端点
	EB_POINT arcp1,arcp2;
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数判断拾取部分是不是孔
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
    p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
  //
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p1,p3);
	double dist1=ebCalTwoPtDis(p1,p2);
	//如果轮廓小于圆弧直径或槽宽度小于开槽处的孔径则无法开槽
	if(0.5*dist<paraL||dist1<2.0*paraR)
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//判断轮廓线与端面线成角度来判断拾取部分是不是孔
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO)
	{
		AfxMessageBox("错误：拾取的部分不为孔或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//
	EB_POINT midpoint,midpoint1,midpoint2;//为孔的端面中点
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);
	angle=fabs((angl1+angl2)/2.0);//两轴夹角平分线
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
//if paraW!=0，将对轴心点平移；
	midpoint.x=midpoint.x+paraH*cos(angle);midpoint.y=midpoint.y+paraH*sin(angle);
	double offsetdist;
	offsetdist=sqrt(pow(paraR,2.0)-pow((paraR-paraL),2.0));
	midpoint1.x=midpoint.x+2.0*offsetdist*cos(angle);midpoint1.y=midpoint.y+2.0*offsetdist*sin(angle);
	midpoint2.x=midpoint.x+offsetdist*cos(angle);midpoint2.y=midpoint.y+offsetdist*sin(angle);
	
	EB_POINT temppoint1,temppoint2;
	EB_NODE templine;
	temppoint1.x=midpoint.x+500.0*cos(angl3);temppoint1.y=midpoint.y+500.0*sin(angl3);
	temppoint2.x=midpoint.x-500.0*cos(angl3);temppoint2.y=midpoint.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p5=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p6=pisp1[0];
	dist1=ebCalTwoPtDis(p5,p6);
	if(0.5*dist1<paraL)//开槽处孔径小于槽深度无法开孔
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	
	temppoint1.x=midpoint1.x+500.0*cos(angl3);temppoint1.y=midpoint1.y+500.0*sin(angl3);
	temppoint2.x=midpoint1.x-500.0*cos(angl3);temppoint2.y=midpoint1.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p1=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p3=pisp1[0];
	dist=ebCalTwoPtDis(p1,p3);
	ebFreeNode(templine);
	if(0.5*dist<paraL)//开槽处孔径小于槽深度无法开孔
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	
	dist=(dist+dist1)/2.0;
	arcp1.x=midpoint2.x+(dist/2.0+paraL)*cos(angl3);arcp1.y=midpoint2.y+(dist/2.0+paraL)*sin(angl3);
	arcp2.x=midpoint2.x-(dist/2.0+paraL)*cos(angl3);arcp2.y=midpoint2.y-(dist/2.0+paraL)*sin(angl3);

	EB_NODE arc1,arc2,line3,orgline1,orgline2;//新边
	EB_NODE line4,orgline3,orgline4;
//生成新边并入系统链
	line4=ebBuildLine(p5,p6);
	line3=ebBuildLine(p1,p3);
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	ebInsNodeToSys(orgline3);
	ebInsNodeToSys(orgline4);
	ebInsNodeToSys(line4);
//生成圆弧边并入链。将原轮廓边从系统链中删除
	arc1=ebBuildPsP2PeArc(p5,arcp1,p1);
	arc2=ebBuildPsP2PeArc(p6,arcp2,p3);
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(arc1);
	ebInsNodeToSys(arc2);
	ebInsNodeToSys(line3);
	ebDrawNode(endline,NORMAL);
//	
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：AppGenerateGrooveOnAxisEnd
描述：  此函数是实现在轴端部生成退刀槽的交互拾取和参数填写功能。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateGrooveOnAxisEnd(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraD=5.0;//槽深度
	static double paraW=15.0;//槽宽度
	EB_POINT pk3;
    //轴轮廓线
	static EB_NODE firstline;
	static EB_NODE secondline;
	static EB_NODE endline;//轴的端面线
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebClearMenu();
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebGetMenuReal("槽宽度W:",&paraW,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取轴的一条轮廓线：");
		break;
	case 1://交互拾取第一条轮廓
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的另一条轮廓线：");
		break;
	case 2://交互拾取第二条轮廓
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的端面线：");
		break;
	case 3://交互拾取端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenAxisGroove(firstline,secondline,endline,
			           paraD,paraW);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;	
}
/*
函数名：GenAxisGroove
描述：  此函数是实现在轴上生成退刀槽。
参数说明：firstline,secondline 是轴的两个轮廓边，endline 是轴的端面边，
          paraH,paraL 是退刀槽的宽度和深度参数，paraW 是退刀槽距离端面的距离
		  当paraW 为零时，表示为轴的端面退刀槽。
返回值：无
*/
void GenAxisGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					 const double paraH,const double paraL,const double paraW)
{
	double angl1,angl2,angl3;//三直线与X夹角
	double angle1,angle2;//轮廓线与端面线夹角
	double angl;//两轮廓夹角
	EB_POINT sp1,ep1,sp2,ep2;//sp起点,ep终点
	EB_POINT p1,p2,p3,p4;//新边端点
	EB_POINT p5,p6,p7,p8;//新边端点，paraW 不为零时有用；
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数判断拾取部分是不是轴
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
    p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
  //
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p2,p4);
	double dist1=ebCalTwoPtDis(p1,p2);
	//如果开槽处的轴径小于槽深度或轮廓长度小于槽宽度，则无法开槽
	if(paraH>=0.5*dist||paraL>=dist1)
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}	
//判断轮廓线与端面线成角度判断拾取部分是否为轴
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	//midpoint,midpoint1 为槽的两端面中点，
	//point1,point2,point3,point4 为槽的角点
	EB_POINT midpoint,midpoint1,point1,point2,point3,point4;
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;//轴轮廓的夹角平分线
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);
	angle=fabs((angl1+angl2)/2.0);
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
//if paraW!=0，将对轴心点平移；
	midpoint.x=midpoint.x+paraW*cos(angle);midpoint.y=midpoint.y+paraW*sin(angle);

	EB_POINT temppoint1,temppoint2;
	EB_NODE templine;
	temppoint1.x=midpoint.x+500.0*cos(angl3);temppoint1.y=midpoint.y+500.0*sin(angl3);
	temppoint2.x=midpoint.x-500.0*cos(angl3);temppoint2.y=midpoint.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p5=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p6=pisp1[0];
	dist=ebCalTwoPtDis(p5,p6);
	if(0.5*dist<paraH)//如果开槽处的轴径小于槽深度则无法开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//计算槽的角点
	point1.x=midpoint.x+(dist-paraH)*cos(angl3)/2.0;point1.y=midpoint.y+(dist-paraH)*sin(angl3)/2.0;
	point3.x=midpoint.x-(dist-paraH)*cos(angl3)/2.0;point3.y=midpoint.y-(dist-paraH)*sin(angl3)/2.0;
	point2.x=point1.x+paraL*cos(angle);point2.y=point1.y+paraL*sin(angle);
	point4.x=point3.x+paraL*cos(angle);point4.y=point3.y+paraL*sin(angle);
	
	midpoint1.x=(point2.x+point4.x)/2.0;midpoint1.y=(point2.y+point4.y)/2.0;
	temppoint1.x=midpoint1.x+500.0*cos(angl3);temppoint1.y=midpoint1.y+500.0*sin(angl3);
	temppoint2.x=midpoint1.x-500.0*cos(angl3);temppoint2.y=midpoint1.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p1=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p3=pisp1[0];
	dist=ebCalTwoPtDis(p1,p3);
	ebFreeNode(templine);
	if(0.5*dist<paraH)//如果开槽处的轴径小于槽深度则无法开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	EB_NODE line1,line2,line3,orgline1,orgline2;//新边
	EB_NODE line4,orgline3,orgline4;//新边，只在paraW不为零时起作用
	//生成新边，并入系统链
	line3=ebBuildLine(p5,p6);
	line4=ebBuildLine(p1,p3);
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	//
	if(paraW!=0.0)//在轴的中部开槽
	{
		ebInsNodeToSys(orgline3);
		ebInsNodeToSys(orgline4);
		ebInsNodeToSys(line3);
	}
//生成新的轮廓边入链，删除原轮廓边
	line1=ebBuildLine(point1,point2);
	line2=ebBuildLine(point3,point4);
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(line1);
	ebInsNodeToSys(line2);
	ebInsNodeToSys(line4);
	ebDrawNode(endline,NORMAL);
	
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：AppGenerateGrooveOnAxisMid
描述：  此函数实现在轴的中部生成退刀槽的交互拾取部分和参数填写部分。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateGrooveOnAxisMid(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraD=5.0;//槽深度
	static double paraW=15.0;//槽宽度
	static double paraL=50.0;//槽距轴端面的距离
	EB_POINT pk3;
    //轴轮廓线
	static EB_NODE firstline;
	static EB_NODE secondline;
	static EB_NODE endline;//轴的端面线
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebClearMenu();
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebGetMenuReal("槽宽度W:",&paraW,ZERO,1000.0);
		ebGetMenuReal("槽端距L:",&paraL,ZERO,1000.0);
		ebClearPrompt();
		ebPrompt("请拾取轴的一条轮廓线：");
		break;
	case 1://交互拾取轴的第一条轮廓线
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的另一条轮廓线：");
		break;
	case 2://交互拾取轴的第二条轮廓线
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的端面线：");
		break;
	case 3://交互拾取轴的端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenAxisGroove(firstline,secondline,endline,
			           paraD,paraW,paraL);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
}
/*
函数名：AppGenerateArcGrooveOnAxisMid
描述：  此函数是实现在轴的中部生成圆弧退刀槽的交互拾取和参数填写功能。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateArcGrooveOnAxisMid(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraD=10.0;//槽深度
	static double paraL=50.0;//槽距端面距离
	static double paraR=5.0;//圆弧半径
	EB_POINT pk3;
	//轴轮廓线
	static EB_NODE firstline;
	static EB_NODE secondline;
	static EB_NODE endline;//轴的端面线
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽深度D:",&paraD,.0,500.0);
		ebGetMenuReal("槽端距L:",&paraL,0.0,500.0);
		ebGetMenuReal("圆弧半径R:",&paraR,0.0,500.0);
		ebClearPrompt();
		ebPrompt("请拾取轴的一条轮廓线：");
		break;
	case 1://交互拾取第一条轮廓
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的另一条轮廓线：");
		break;
	case 2://交互拾取轴的第二条轮廓线
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的端面线：");
		break;
	case 3://交互拾取端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		if(paraD>=paraR)//当开槽的深度不小于槽圆弧半径
			GenAxisArcGroove(firstline,secondline,endline,
						     paraD,paraL,paraR);
		else if(paraD<paraR)//当开槽的深度小于槽圆弧半径
			GenAxisArcGroove_s(firstline,secondline,endline,
						     paraD,paraL,paraR);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
}
/*
函数名：GenAxisArcGroove
描述：  此函数是实现在轴上生成圆弧退刀槽的功能。但只实现当paraH参数
        不小于paraR参数时的功能。(paraH>=paraR)
参数说明：firstline,secondline 是轴的两轮廓，endline 是轴的端面线，
		  paraH 是退刀槽的深度参数，paraL 是退刀槽与端面的距离，
		  paraR 是退刀槽的圆弧半径参数。
返回值：无
*/
void GenAxisArcGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraR)
{
	double angl1,angl2,angl3;//三直线与X夹角
	double angle1,angle2;//轮廓线与端面线夹角
	double angl;//两轮廓线夹角
	EB_POINT sp1,ep1,sp2,ep2;//sp 为起点，ep 为终点
	EB_POINT p1,p2,p3,p4;//新线端点
	EB_POINT p5,p6,p7,p8;//新线端点
	EB_POINT arcp1,arcp2;
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数判断拾取部分是否为轴
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
  //
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p1,p3);
	double dist1=ebCalTwoPtDis(p1,p2);
	//当开槽处的轴半径小于槽深或轮廓长度小于圆弧直径时不能开槽
	if(0.5*dist<paraH||dist1<2.0*paraR)
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}	
//判断轮廓线与端面线成角度来判断拾取部分是否为轴
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	//midpoint,midpoint1为槽的端面线终点，
	//point1,point2,point3,point4 是槽的角点
	EB_POINT midpoint,midpoint1,midpoint2,point1,point2,point3,point4;
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);
	angle=fabs((angl1+angl2)/2.0);
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
//if paraW!=0，将对轴心点平移；
	midpoint.x=midpoint.x+paraL*cos(angle);midpoint.y=midpoint.y+paraL*sin(angle);

	EB_POINT temppoint1,temppoint2;
	EB_NODE templine;
	temppoint1.x=midpoint.x+500.0*cos(angl3);temppoint1.y=midpoint.y+500.0*sin(angl3);
	temppoint2.x=midpoint.x-500.0*cos(angl3);temppoint2.y=midpoint.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p5=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p6=pisp1[0];
	dist=ebCalTwoPtDis(p5,p6);
	if(0.5*dist<paraH)//当开槽处的轴半径小于槽深时不能开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//计算槽角点
	point1.x=midpoint.x+(dist/2.0-paraH+paraR)*cos(angl3);point1.y=midpoint.y+(dist/2.0-paraH+paraR)*sin(angl3);
	point3.x=midpoint.x-(dist/2.0-paraH+paraR)*cos(angl3);point3.y=midpoint.y-(dist/2.0-paraH+paraR)*sin(angl3);
	point2.x=point1.x+2.0*paraR*cos(angle);point2.y=point1.y+2.0*paraR*sin(angle);
	point4.x=point3.x+2.0*paraR*cos(angle);point4.y=point3.y+2.0*paraR*sin(angle);
	
	midpoint1.x=(point2.x+point4.x)/2.0;midpoint1.y=(point2.y+point4.y)/2.0;
	midpoint2.x=(midpoint1.x+midpoint.x)/2.0;midpoint2.y=(midpoint1.y+midpoint.y)/2.0;
	arcp1.x=midpoint2.x+(dist/2.0-paraH)*cos(angl3);arcp1.y=midpoint2.y+(dist/2.0-paraH)*sin(angl3);
	arcp2.x=midpoint2.x-(dist/2.0-paraH)*cos(angl3);arcp2.y=midpoint2.y-(dist/2.0-paraH)*sin(angl3);
	
	temppoint1.x=midpoint1.x+500.0*cos(angl3);temppoint1.y=midpoint1.y+500.0*sin(angl3);
	temppoint2.x=midpoint1.x-500.0*cos(angl3);temppoint2.y=midpoint1.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p1=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p3=pisp1[0];
	dist=ebCalTwoPtDis(p1,p3);
	ebFreeNode(templine);
	if(0.5*dist<paraH)//当开槽处的轴半径小于槽深时不能开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	EB_NODE arc1,arc2,line3,orgline1,orgline2;//新线
	EB_NODE line4,orgline3,orgline4;//新线
//生成新线并入系统链
	line4=ebBuildLine(p5,p6);
	line3=ebBuildLine(p1,p3);
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	ebInsNodeToSys(orgline3);
	ebInsNodeToSys(orgline4);
	ebInsNodeToSys(line4);
//生成圆弧边入链并将原轮廓线从系统链中删除
	arc1=ebBuildPsP2PeArc(point1,arcp1,point2);
	arc2=ebBuildPsP2PeArc(point3,arcp2,point4);
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(arc1);
	ebInsNodeToSys(arc2);
	ebInsNodeToSys(line3);
//
	ebDrawNode(endline,NORMAL);
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：GenAxisArcGroove_s
描述：  此函数是实现在轴上生成圆弧退刀槽的功能。但只实现当paraH参数
        小于paraR参数时的功能。(paraH<paraR)
参数说明：firstline,secondline 是轴的两轮廓，endline 是轴的端面线，
		  paraH 是退刀槽的深度参数，paraL 是退刀槽与端面的距离，
		  paraR 是退刀槽的圆弧半径参数。
返回值：无
*/
void GenAxisArcGroove_s(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					  const double paraH,const double paraL,const double paraR)
{
	double angl1,angl2,angl3;//三直线与X夹角
	double angle1,angle2;//轮廓线与端面线夹角
	double angl;//两轮廓线夹角
	EB_POINT sp1,ep1,sp2,ep2;//sp 为起点，ep 为终点
	EB_POINT p1,p2,p3,p4;//新线端点
	EB_POINT p5,p6,p7,p8;//新线端点
	EB_POINT arcp1,arcp2;
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数来判断拾取部分是否为轴
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
    p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
  //
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p1,p3);
	double dist1=ebCalTwoPtDis(p1,p2);
	//当开槽处的轴半径小于槽深或轮廓长度小于圆弧直径时不能开槽
	if(0.5*dist<paraH||dist1<2.0*paraR)
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//判断轮廓线与端面线成角度来判断拾取部分是否为轴
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	EB_POINT midpoint,midpoint1,midpoint2;//槽的端面线的中点
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);
	angle=fabs((angl1+angl2)/2.0);
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
//if paraW!=0，将对轴心点平移；
	midpoint.x=midpoint.x+paraL*cos(angle);midpoint.y=midpoint.y+paraL*sin(angle);
	double offsetdist;
	offsetdist=sqrt(pow(paraR,2.0)-pow((paraR-paraH),2.0));
	midpoint1.x=midpoint.x+2.0*offsetdist*cos(angle);midpoint1.y=midpoint.y+2.0*offsetdist*sin(angle);
	midpoint2.x=midpoint.x+offsetdist*cos(angle);midpoint2.y=midpoint.y+offsetdist*sin(angle);
	
	EB_POINT temppoint1,temppoint2;
	EB_NODE templine;
	temppoint1.x=midpoint.x+500.0*cos(angl3);temppoint1.y=midpoint.y+500.0*sin(angl3);
	temppoint2.x=midpoint.x-500.0*cos(angl3);temppoint2.y=midpoint.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p5=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p6=pisp1[0];
	dist1=ebCalTwoPtDis(p5,p6);
	if(0.5*dist1<paraH)//当开槽处的轴半径小于槽深时不能开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	temppoint1.x=midpoint1.x+500.0*cos(angl3);temppoint1.y=midpoint1.y+500.0*sin(angl3);
	temppoint2.x=midpoint1.x-500.0*cos(angl3);temppoint2.y=midpoint1.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p1=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p3=pisp1[0];
	dist=ebCalTwoPtDis(p1,p3);
	ebFreeNode(templine);
	if(0.5*dist<paraH)//当开槽处的轴半径小于槽深时不能开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}	
	dist=(dist+dist1)/2.0;
	arcp1.x=midpoint2.x+(dist/2.0-paraH)*cos(angl3);arcp1.y=midpoint2.y+(dist/2.0-paraH)*sin(angl3);
	arcp2.x=midpoint2.x-(dist/2.0-paraH)*cos(angl3);arcp2.y=midpoint2.y-(dist/2.0-paraH)*sin(angl3);

	EB_NODE arc1,arc2,line3,orgline1,orgline2;//新线
	EB_NODE line4,orgline3,orgline4;//新线
//生成新线并入链
	line4=ebBuildLine(p5,p6);
	line3=ebBuildLine(p1,p3);
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	ebInsNodeToSys(orgline3);
	ebInsNodeToSys(orgline4);
	ebInsNodeToSys(line4);
//生成圆弧线入链并从系统链中删除原轮廓线
	arc1=ebBuildPsP2PeArc(p5,arcp1,p1);
	arc2=ebBuildPsP2PeArc(p6,arcp2,p3);
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(arc1);
	ebInsNodeToSys(arc2);
	ebInsNodeToSys(line3);
//
	ebDrawNode(endline,NORMAL);
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}
/*
函数名：AppGenerateAngGrooveOnAxisMid
描述：  此函数是实现在轴的中部生成角度退刀槽的交互拾取和参数填写功能。
参数说明：step 记录操作的是第几步，flag 记录操作的标志。
返回值：是一些常量。RT_NOTOVER表示交互尚未完成或交互失败返回
             RT_ISOVER 表示交互已经完成返回。
*/
int AppGenerateAngGrooveOnAxisMid(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	static double paraL=50.0;//槽距端面距离
	static double paraD=5.0;//槽深
	static double paraW=15.0;//槽宽
	static double paraA=45.0;//开槽角度(角度值)
    EB_POINT pk3;
	//轮廓线
	static EB_NODE firstline;
	static EB_NODE secondline;
	static EB_NODE endline;//轴的端面线
	int ret=0;
	switch(step)
	{
	case 0://交互填写参数 
		ebClearPrompt();
		ebPrompt("请输入参数值：");
		ebClearMenu();
		ebGetMenuReal("槽端距L:",&paraL,ZERO,1000.0);
		ebGetMenuReal("槽深度D:",&paraD,ZERO,1000.0);
		ebGetMenuReal("槽宽度W:",&paraW,ZERO,1000.0);
		ebGetMenuReal("开槽角度A:",&paraA,ZERO,90.0);
		ebClearPrompt();
		ebPrompt("请拾取轴的一条轮廓线：");
		break;
	case 1://拾取轴的第一条轮廓线
		ret=ebGetPoint(&pk1);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		firstline=ebGetNode(pk1,LINE);
		if(firstline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的另一条轮廓线：");
		break;
	case 2://拾取轴的第二条轮廓线
		ret=ebGetPoint(&pk2);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebDrawNode(firstline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		secondline=ebGetNode(pk2,LINE);
		if(secondline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebClearPrompt();
		ebPrompt("请拾取轴的端面线：");
		break;
	case 3://拾取端面线
		ret=ebGetPoint(&pk3);
		if(ret==RT_FINISH||ret==RT_USERBRK)//用户终止交互
		{
			ebDrawNode(firstline,NORMAL);
			ebDrawNode(secondline,NORMAL);
			ebClearMenu();
			ebEndCommand();
			return RT_NOTOVER;
		}
		endline=ebGetNode(pk3,LINE);
		if(endline==NULL)//拾取失败
		{
			step=step-1;
			flag=flag;
			return RT_NOTOVER;
		}
		ebInitUndo();//初始化UNDO
		GenAxisAngGroove(firstline,secondline,endline,
						     paraL,paraD,paraA,paraW);
		return RT_ISOVER;
		break;
	}
	flag=flag;
	return RT_NOTOVER;
	
}
/*
函数名：GenAxisAngGroove
描述：  此函数是实现在轴上生成角度退刀槽的功能。
参数说明：firstline,secondline 是轴的两个轮廓边，endline 是轴的端面轮廓边，
          paraT,paraL 是退刀槽的宽度和深度参数，paraA 是退刀槽的侧边与轴线的
		  角度参数，paraH 是退刀槽与轴端面的距离。
返回值：无
*/
void GenAxisAngGroove(EB_NODE &firstline,EB_NODE &secondline,const EB_NODE endline,
					  const double paraH,const double paraL,double paraA,const double paraT)
					  
{
	paraA=paraA*PI/180.0;//将输入的角度值转换为弧度值；
	double angl1,angl2,angl3;//三直线与X夹角
	double angle1,angle2;//轮廓线与端面线夹角
	double angl;//两轮廓夹角
	EB_POINT sp1,ep1,sp2,ep2;//sp为起点，ep为终点
	EB_POINT p1,p2,p3,p4;//新线端点
	EB_POINT p5,p6,p7,p8;//新线端点
	EB_POINT *pisp1,*pisp2;
	pisp1=pisp2=NULL;
	int count=0;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
//通过判断交点个数来判断拾取部分是否为轴
	pisp1=ebInterSection(firstline,endline,&count);
	if(pisp1==NULL)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
    p1=pisp1[0];
	count=0;
	pisp2=ebInterSection(secondline,endline,&count);
	if(pisp2==NULL||DecideEndPoint(firstline,secondline,endline,p2,p4,p7,p8)==FALSE)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误或拾取位置不对！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
  //
	p3=pisp2[0];
	count=0;
	double dist=ebCalTwoPtDis(p1,p3);
	double dist1=ebCalTwoPtDis(p1,p2);
	//当开槽处的轴半径小于槽深或轮廓长度小于槽宽度时不能开槽
	if(0.5*dist<paraL||dist1<paraH)
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
//判断轮廓线与端面线成角度来判断拾取部分是否为轴
	angl1=ebCalXAxisAngle(p1,p2);
	angl2=ebCalXAxisAngle(p3,p4);
	angl3=ebCalXAxisAngle(p3,p1);
	angle1=angl1-angl3;
	angle2=angl2-angl3;
	angle1=angle1>0.0?angle1:fabs(angle1);
	angle1=angle1>PI?angle1-PI:angle1;
	angle2=angle2>0.0?angle2:fabs(angle2);
	angle2=angle2>PI?angle2-PI:angle2;
	if(fabs(angle1+angle2-PI)>ZERO&&fabs(angle1-angle2)>ZERO)
	{
		AfxMessageBox("错误：拾取的部分不为轴或者是拾取顺序错误！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	//midpoint,midpoint1,midpoint2 为槽端面线的中点
	//point1,point2,point3,point4 为槽的角点
	EB_POINT midpoint,midpoint1,midpoint2,point1,point2,point3,point4;
	midpoint.x=(p1.x+p3.x)/2.0;midpoint.y=(p1.y+p3.y)/2.0;
	double angle;
	angl=(angl1-angl2)>0.0?(angl1-angl2):fabs(angl1-angl2);
	angle=fabs((angl1+angl2)/2.0);
	if(angl<PI) angle=angle;
	else if(angl>PI) angle=angle+PI;
	midpoint.x=midpoint.x+paraH*cos(angle);midpoint.y=midpoint.y+paraH*sin(angle);
	EB_POINT temppoint1,temppoint2;
	EB_NODE templine;
	temppoint1.x=midpoint.x+500.0*cos(angl3);temppoint1.y=midpoint.y+500.0*sin(angl3);
	temppoint2.x=midpoint.x-500.0*cos(angl3);temppoint2.y=midpoint.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p5=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p6=pisp1[0];
	dist=ebCalTwoPtDis(p5,p6);
	if(0.5*dist<paraL)//当开槽处的轴半径小于槽深时不能开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	midpoint1.x=midpoint.x+paraT*cos(angle);midpoint1.y=midpoint.y+paraT*sin(angle);
	temppoint1.x=midpoint1.x+500.0*cos(angl3);temppoint1.y=midpoint1.y+500.0*sin(angl3);
	temppoint2.x=midpoint1.x-500.0*cos(angl3);temppoint2.y=midpoint1.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	p1=pisp1[0];
	pisp1=ebInterSection(templine,secondline,&count);
	p3=pisp1[0];
	dist=ebCalTwoPtDis(p1,p3);
	if(0.5*dist<paraL)//当开槽处的轴半径小于槽深时不能开槽
	{
		AfxMessageBox("错误：参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	double OffsetparaL1=paraL*paraH/(paraH+paraT/2.0);
	double OffsetparaL2=paraL*(paraH+paraT)/(paraH+paraT/2.0);
	//当槽宽度过窄时无法满足角度或角度过大无法满足宽度时无法开槽
	if((OffsetparaL1*tan(paraA)+OffsetparaL2*tan(paraA)-paraT)>ZERO)
	{
		AfxMessageBox("错误：W参数和A参数不合适！",0,0);
		ebClearMenu();
		ebClearPrompt();
		ebDrawNode(firstline,NORMAL);
		ebDrawNode(secondline,NORMAL);
		ebDrawNode(endline,NORMAL);
		ebEndCommand();
		return;
	}
	double Offsetdist1=OffsetparaL1/tan(paraA);
	double Offsetdist2=paraT-OffsetparaL2/tan(paraA)-OffsetparaL1/tan(paraA);
	midpoint2.x=midpoint.x+Offsetdist1*cos(angle);midpoint2.y=midpoint.y+Offsetdist1*sin(angle);
	EB_POINT pt1,pt2;
	temppoint1.x=midpoint2.x+500.0*cos(angl3);temppoint1.y=midpoint2.y+500.0*sin(angl3);
	temppoint2.x=midpoint2.x-500.0*cos(angl3);temppoint2.y=midpoint2.y-500.0*sin(angl3);
	templine=ebBuildLine(temppoint1,temppoint2);
	pisp1=ebInterSection(templine,firstline,&count);
	pt1=pisp1[0];
	pisp2=ebInterSection(templine,secondline,&count);
	pt2=pisp2[0];
	dist=ebCalTwoPtDis(pt1,pt2);
	ebFreeNode(templine);
	double OffsetparaL=paraL*(paraH+Offsetdist1)/(paraH+paraT/2.0);
	point1.x=midpoint2.x+(dist/2.0-OffsetparaL)*cos(angl3);point1.y=midpoint2.y+(dist/2.0-OffsetparaL)*sin(angl3);
	point4.x=midpoint2.x-(dist/2.0-OffsetparaL)*cos(angl3);point4.y=midpoint2.y-(dist/2.0-OffsetparaL)*sin(angl3);
	point2.x=point1.x+Offsetdist2*cos(angle);point2.y=point1.y+Offsetdist2*sin(angle);
	point3.x=point4.x+Offsetdist2*cos(angle);point3.y=point4.y+Offsetdist2*sin(angle);
//新线
	EB_NODE line3,orgline1,orgline2;
	EB_NODE line4,orgline3,orgline4;
	EB_NODE line5,line6,line7,line8,line9,line10,line11,line12;
//生成新线并入链
	line4=ebBuildLine(p5,p6);
	line3=ebBuildLine(p1,p3);
	line5=ebBuildLine(p1,point2);
	ebInsNodeToSys(line5);
	line6=ebBuildLine(p6,point4);
	ebInsNodeToSys(line6);
	line7=ebBuildLine(p3,point3);
	ebInsNodeToSys(line7);
	line8=ebBuildLine(p5,point1);
	ebInsNodeToSys(line8);
	line9=ebBuildLine(point1,point2);
	ebInsNodeToSys(line9);
	line10=ebBuildLine(point2,point3);
	ebInsNodeToSys(line10);
	line11=ebBuildLine(point3,point4);
	ebInsNodeToSys(line11);
	line12=ebBuildLine(point4,point1);
	ebInsNodeToSys(line12);
	orgline1=ebBuildLine(p1,p2);
	orgline3=ebBuildLine(p5,p7);
	orgline2=ebBuildLine(p3,p4);
	orgline4=ebBuildLine(p6,p8);
	ebInsNodeToSys(orgline1);
	ebInsNodeToSys(orgline2);
	ebInsNodeToSys(orgline3);
	ebInsNodeToSys(orgline4);
	ebInsNodeToSys(line4);
//将原轮廓线从系统链中删除并将新的轮廓线入链
	ebDelNodeFromSys(firstline);
	ebDelNodeFromSys(secondline);
	ebInsNodeToSys(line3);
///////////////////
	ebDrawNode(endline,NORMAL);
	ebRedraw();
	ebClearMenu();
	ebEndCommand();
}

/*
函数名：DecideLineEndPoint
描述：  此函数用于决定直线有效端点
参数说明：firstline，secondline分别为顺序拾取的两条直线，p1为交点,p2和p3分别为第一和第二条直线有效端点。
返回值：反映有关情况。
*/

int DecideLineEndPoint(const EB_NODE firstline,const EB_NODE secondline,
					   EB_POINT &p1,EB_POINT &p2,EB_POINT &p3)
{
//sp 为边的起点，ep 为边的终点。
	EB_POINT sp1,ep1;
	EB_POINT sp2,ep2;
//slope为直线斜率,equation1和equation2为直线方程式,用来判断拾取线两端点是否在交点同侧
	double slope,equation1,equation2; 
//ISPoint为拾取两直线交点数组，count交点个数
	EB_POINT *ISPoint;
	ISPoint=NULL;
	int count=0;
	ISPoint=ebInterSection(firstline,secondline,&count); //求交点
	if(count==0)    //无交点时
	{
		return 2;
	}
	else if(count>1)  //拾取的是同一条直线
	{
		return 3;
	}
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);  //获得端点
	p1=ISPoint[0];
	double* length=new double[4];
	if(length==0)    //内存分配失败
	{
		return 4;
	}
	length[0]=ebCalTwoPtDis(sp1,p1);    //一端点到交点的距离
	length[1]=ebCalTwoPtDis(pk1,p1);    //拾取点到交点的距离
	length[2]=ebCalTwoPtDis(ep1,p1);    //另一端点到交点的距离
	length[3]=ebCalTwoPtDis(ep1,pk1);   //另一端点到拾取点的距离
	if(fabs(sp2.x-ep2.x)<ZERO)          //拾取的第一条线竖直（斜率无穷大）时
	{
		equation1=sp1.x-sp2.x;          //直线方程为x=b
		equation2=ep1.x-sp2.x;
		if(equation1*equation2>0)      //为虚交点
		{
			p2=length[0]>length[2]?sp1:ep1;
		}
		else
		{
			if(length[0]>=length[1]&&length[3]>=length[2])  //确定有用端点
			{
				p2=sp1;
			}
			else
			{
				p2=ep1;
			}
		}
	}
	else
	{
		slope=(sp2.y-ep2.y)/(sp2.x-ep2.x);    //直线斜率
		equation1=sp1.y-slope*sp1.x-sp2.y+slope*sp2.x;  //直线方程为y=kx+b
		equation2=ep1.y-slope*ep1.x-ep2.y+slope*ep2.x;
		if(equation1*equation2>0)      //为虚交点
		{
			p2=length[0]>length[2]?sp1:ep1;
		}
		else
		{
			if(length[0]>=length[1]&&length[3]>=length[2])  //确定有用端点
			{
				p2=sp1;
			}
			else
			{
				p2=ep1;
			}
		}
	}
	length[0]=ebCalTwoPtDis(sp2,p1);
	length[1]=ebCalTwoPtDis(pk2,p1);
	length[2]=ebCalTwoPtDis(ep2,p1);  //计算另一条直线有关长度
	length[3]=ebCalTwoPtDis(ep2,pk2);
	if(fabs(sp1.x-ep1.x)<ZERO)        //拾取的第二条线竖直（斜率无穷大）时
	{
		equation1=sp2.x-sp1.x;          //直线方程为x=b
		equation2=ep2.x-sp1.x;
		if(equation1*equation2>0)      //为虚交点
		{
			p3=length[0]>length[2]?sp2:ep2;
		}
		else                           //为实交点
		{
			if(length[0]>=length[1]&&length[3]>=length[2])  //确定有用端点
			{
				p3=sp2;
			}
			else
			{
				p3=ep2;
			}
		}
	}
	else
	{
		slope=(sp1.y-ep1.y)/(sp1.x-ep1.x);    //直线斜率
		equation1=sp2.y-slope*sp2.x-sp1.y+slope*sp1.x;  //直线方程为y=kx+b
		equation2=ep2.y-slope*ep2.x-ep1.y+slope*ep1.x;
		if(equation1*equation2>0)      //为虚交点
		{
			p3=length[0]>length[2]?sp2:ep2;
		}
		else
		{
			if(length[0]>=length[1]&&length[3]>=length[2])  //确定有用端点
			{
				p3=sp2;
			}
			else
			{
				p3=ep2;
			}
		}
	}
	delete []length;  //清除动态分配的内存
	return 1;
}

/*
函数名：DecideEndPoint
描述：  此函数用于决定轴和孔有效端点，并且若拾取的前两点不在端面线同侧，说明拾取错误。
参数说明：firstline，secondline，endline分别为顺序拾取的三条直线，p2和p4分别为第一和第二条直线有效端点。
返回值：TRUE说明拾取的前两点在端面线同侧，FALSE则说明拾取的前两点分布在端面线两侧。
*/

BOOL DecideEndPoint(const EB_NODE firstline,const EB_NODE secondline,const EB_NODE endline,
                    EB_POINT &p2,EB_POINT &p4,EB_POINT &p7,EB_POINT &p8)
{
//slope为端面线斜率,equation1和equation2为直线方程式,用来判断拾取点相对于端面线的位置
	double slope,equation1,equation2; 
//sp,ep为直线的起点和终点
    EB_POINT sp1,ep1,sp2,ep2,sp3,ep3;
	ebGetLineData(firstline,&sp1,&ep1);
	ebGetLineData(secondline,&sp2,&ep2);
	ebGetLineData(endline,&sp3,&ep3);
	if(fabs(sp3.x-ep3.x)<ZERO)          //端面线竖直（斜率无穷大）时
	{
		equation1=pk1.x-sp3.x;          //直线方程为x=b
		equation2=pk2.x-sp3.x;
		if(equation1>0)
		{
			 p2=(ep1.x>sp1.x)?ep1:sp1;   //选端面线最右侧的点
			 p4=(ep2.x>sp2.x)?ep2:sp2;
			 p7=(ep1.x>sp1.x)?sp1:ep1;   //选端面线最左侧的点
		     p8=(ep2.x>sp2.x)?sp2:ep2;
		}
		else
		{
			 p2=(ep1.x>sp1.x)?sp1:ep1;   //选端面线最左侧的点
		     p4=(ep2.x>sp2.x)?sp2:ep2;
			 p7=(ep1.x>sp1.x)?ep1:sp1;   //选端面线最右侧的点
			 p8=(ep2.x>sp2.x)?ep2:sp2;
		}
	}
	else                                 //端面线不竖直时
	{
		slope=(sp3.y-ep3.y)/(sp3.x-ep3.x);    //端面线斜率
		equation1=pk1.y-slope*pk1.x-sp3.y+slope*sp3.x;  //直线方程为y=kx+b
		equation2=pk2.y-slope*pk2.x-sp3.y+slope*sp3.x;
		if(slope>0)
		{
			if(equation1>0)
			{
				p2=(ep1.x>sp1.x)?sp1:ep1;          //选端面线最左侧点
			    p4=(ep2.x>sp2.x)?sp2:ep2;
			    p7=(ep1.x>sp1.x)?ep1:sp1;          //选端面线最右侧点
				p8=(ep2.x>sp2.x)?ep2:sp2;
			}
			else
			{	
			    p2=(ep1.x>sp1.x)?ep1:sp1;          //选端面线最右侧点
				p4=(ep2.x>sp2.x)?ep2:sp2;
				p7=(ep1.x>sp1.x)?sp1:ep1;          //选端面线最左侧点
			    p8=(ep2.x>sp2.x)?sp2:ep2;
			}
		}
		else
		{
			if(equation1>0)
			{
				p2=(ep1.x>sp1.x)?ep1:sp1;        //选端面线最右侧点
			    p4=(ep2.x>sp2.x)?ep2:sp2;
			    p7=(ep1.x>sp1.x)?sp1:ep1;         //选端面线最左侧点
				p8=(ep2.x>sp2.x)?sp2:ep2;
			}
			else
			{	
			    p2=(ep1.x>sp1.x)?sp1:ep1;         //选端面线最左侧点
				p4=(ep2.x>sp2.x)?sp2:ep2;
				p7=(ep1.x>sp1.x)?ep1:sp1;        //选端面线最右侧点
			    p8=(ep2.x>sp2.x)?ep2:sp2;
			}
		}
	}

	if((equation1>0&&equation2>0)||(equation1<0&&equation2<0))
    {
		return TRUE;       //拾取的前两点在端面线同侧
	}
	else
	{
		return FALSE;     //拾取的前两点不在端面线同侧
	}
}

//  End.