找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3770|回复: 21

[ARX程序]:曲线上的垂直线!

[复制链接]
发表于 2006-7-9 12:57:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
高手们能告诉我,在程序中最简单的方法实现经过多义线(spline)上任意一点的垂直线吗?谢谢!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2006-7-9 16:39:02 | 显示全部楼层
这个可以这样做,
所求点           CurPt     确保在曲线上
前一个靠近点     BefPt    根据CurPt求出在该点前一个很小偏移量的点[有相关的函数的:
                       GetPointAtDis]
后一个靠近点     AftPt    根据CurPt求出在该点后一个很小偏移量的点
根据前后点可分析出该点在曲线上的切线角度,然后加上90度就是曲线垂直方向的角度了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-10 09:04:02 | 显示全部楼层
谢谢!这个方法方案有些复杂,不知道CAD有没有这种函数?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-10 14:32:59 | 显示全部楼层
这个方法在ARX中是比较容易实现的,但以前在VBA中那简直真是饶了好的圈子,累死人的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-11 08:53:53 | 显示全部楼层
好的,我用这种方法试一下,到时候我把函数贴出来,让你看看!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-13 15:58:47 | 显示全部楼层
spline  可不可以象 选择集 那样我用鼠标顺序的选择图上的相连实体获得啊
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-13 16:08:10 | 显示全部楼层
这是一个什么样含糊的问题啊?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-17 10:28:53 | 显示全部楼层
就cad 的图已经画好  我想把图上的相连的某些直线 圆弧变成spline  然后对他们进行整体的偏移,偏移后不需要在图上显示出来,只要能知道偏移后的各个实体的信息就可以了(因为我要用到这些信息::
POlyline 的直线顶点和圆弧顶点都只保存了直线和圆弧的起点标志,终点坐标则都保存在下一个顶点中,利用Object ARX工具可以方便地知道Polyline 各顶点的坐标值和凸度值,这样就得到了零件轮廓上直线的起点、终点坐标和圆弧的起点、终点、半径、圆心等几何信息。)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-17 11:34:38 | 显示全部楼层
这是一个什么样含糊的问题啊~~这是一个什么样含糊的问题啊
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-18 12:32:17 | 显示全部楼层
getFirstDeriv 可得角度, 有角度+PI/2 就是垂足方向
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-18 14:57:41 | 显示全部楼层
你这个函数能得出曲线上任意点的切线角度吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 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;
        }       
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-20 10:30:03 | 显示全部楼层
有一行代码错了,

if( rDisLen >0 && rDisLen < rMaxLen ) //判断垂直点是否在开始点或终止点
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-7-20 11:25:15 | 显示全部楼层
//!过三点的圆,计算圆心
其实程序到这里求出切角再90度就可以了,没有必要再去计算圆心,其实我说的方法是一个符合实际但有点不严格的方法,其实质就是非常接近你所说的那个过曲线的一次求导就是斜率的方法。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-20 12:50:07 | 显示全部楼层
还是群众力量大啊!
我现在明白你的意思了!
你用近似方法,切点附近的两个点的连线斜率就是切线的斜率!
呵呵!

现在归纳起来有三种方法了:
1,求曲线的一次导数,就是切线斜率
2,三点做圆过圆心的线就是垂直线,
3,求最近两点的连线,就是近似切线的斜率.


最后,问大侠一点私事,你是做CAD那个行业的二次开发的?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-24 12:17 , Processed in 0.470354 second(s), 60 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表