- UID
- 96106
- 积分
- 0
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2003-11-20
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2006-7-20 10:26:47
|
显示全部楼层
这几天比较忙,所以一直没有把我写的函数贴出来,让大家看看!
我这种方法比较笨,是找曲线最近三点画圆,过圆心就是垂线,
我以前也想过曲线的一次求导就是斜率的方法,但是我没有确定那个函数!
#define E1 0.0000000000001
//!计算曲线上一点的垂直线
Acad::ErrorStatus ZCADBaseFun::CalcuUprightLine(AcDbObjectId idObj,AcGePoint3d ptPoint,double& rRetK,double& rRetC)
{
char cMsg[200]={0};
Acad::ErrorStatus es;
AcDbEntity *pEditiy = NULL;
//!获得对象
acdbOpenObject(pEditiy,idObj,AcDb::kForRead);
if( !pEditiy)
{
acedAlert("Not open Object!");
return Acad::eNullObjectPointer;
}
//!判断类型
if( pEditiy->isKindOf(AcDbSpline::desc()) != Adesk::kTrue )
{
acedAlert("Object Is Not AcDbSpline!");
pEditiy->close();//!关闭对象
return Acad::eUnknownHandle;
}
AcDbSpline* pSpline = (AcDbSpline* ) pEditiy;
double param;
//!判断垂直点是否在管线上
// pSpline->isOn()
es = pSpline->getParamAtPoint(ptPoint,param);
if(es==Acad::eInvalidInput)
{
pSpline->close();//!关闭对象
return Acad::eInvalidInput;
}
//!获得曲线最大长度
AcGePoint3d ptEnd;
double rMaxLen=0;
pSpline->getEndPoint(ptEnd);//!获得终点
pSpline->getDistAtPoint(ptEnd,rMaxLen);
AcGePoint3d ptFirstPoint;
AcGePoint3d ptSecondPoint;
//!获得起始点到垂直点的距离
double rDisLen=0;
double rFirstDis=0;
double rSecondDis =0;
const double rMinDis=0.1;//!微小偏离量
es = pSpline->getDistAtPoint(ptPoint,rDisLen);//!获得垂直点到开始点的距离
if(es!=Acad::eOk)
{
pSpline->close();//!关闭对象
return Acad::eInvalidInput;
}
sprintf(cMsg,"距离为:%.3f\n",rDisLen);
// acedAlert(cMsg);
if( rDisLen >0 && rDisLen <rMaxLen ) //判断垂直点是否在开始点或终止点
{
rFirstDis = rDisLen-rMinDis;
rSecondDis = rDisLen+rMinDis;
}else if( rDisLen<=0 ) //!在开始点上
{
rFirstDis = rDisLen+rMinDis;
rSecondDis = rDisLen+2*rMinDis;
}else //!在终止点上
{
rFirstDis = rDisLen-rMinDis;
rSecondDis = rDisLen-2*rMinDis;
}
//!计算垂直点左偏量点
es = pSpline->getPointAtDist(rFirstDis,ptFirstPoint);
if(es==Acad::eInvalidInput)
{
pSpline->close();//!关闭对象
return Acad::eInvalidInput;
}
//!计算垂直点右偏量点
es = pSpline->getPointAtDist(rSecondDis,ptSecondPoint);
if(es==Acad::eInvalidInput)
{
pSpline->close();//!关闭对象
return Acad::eInvalidInput;
}
pSpline->close();//!关闭对象
//!过三点的圆,计算圆心
//!过圆心的点就是垂直线。
//!判断三点是否在一条直线上,
double rL = GetDis(ptPoint,ptFirstPoint)+GetDis(ptPoint,ptSecondPoint);
if( fabs(rL -GetDis(ptSecondPoint,ptFirstPoint))<E1 )//!
{
GetUprightLine(ptFirstPoint,ptSecondPoint,ptPoint,rRetK,rRetC);
}else
{ //!计算过两点的中点的垂直线,
AcGePoint3d ptMidPoint;
AcGePoint3d ptCent;
double rK1=0;
double rC1=0;
ptMidPoint.x = (ptSecondPoint.x + ptPoint.x)/2;
ptMidPoint.y = (ptSecondPoint.y + ptPoint.y)/2;
GetUprightLine(ptSecondPoint,ptPoint,ptMidPoint,rK1,rC1);//!获得垂直线
double rK2=0;
double rC2=0;
ptMidPoint.x = (ptFirstPoint.x + ptPoint.x)/2;
ptMidPoint.y = (ptFirstPoint.y + ptPoint.y)/2;
GetUprightLine(ptFirstPoint,ptPoint,ptMidPoint,rK2,rC2);//!获得垂直线
//!求两条垂直线的交点就是圆弧的圆心.
double rX =(rC2-rC1)/(rK1-rK2);//!圆心X坐标
double rY =rK1*rX+rC1; //!圆心Y坐标
ptCent.x = rX;
ptCent.y = rY;
/* DrawCross(ptCent);
AcDbObjectId idObj1;
DrawLine(ptCent,ptPoint,0,idObj1);*/
rRetK = (rY-ptPoint.y)/(rX-ptPoint.x);//!计算斜率
rRetC = rY-rX*rRetK;//!计算方程常项
}
return Acad::eOk;
}
//!计算直线上一点的垂直线
void ZCADBaseFun::GetUprightLine(AcGePoint3d ptStartPoint,AcGePoint3d ptEndPoint,AcGePoint3d ptPoint,double& rRetK,double& rRetC)//!过两点上一点的垂直线
{
double rX = ptEndPoint.x - ptStartPoint.x;
double rY = ptEndPoint.y - ptStartPoint.y;
if( fabs(rY)<E1)//!直线是水平线
{
rRetK = 0;
rRetC = ptPoint.y;
}else if( fabs(rX)<E1 ) //!直线是垂直线
{
rRetK = -1;
rRetC = ptPoint.x;
}
else//!直线是斜线
{
rRetK = 0-rX/rY;//!计算垂直线斜率
rRetC= ptPoint.y-rRetK*ptPoint.x;
}
} |
|