找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 10498|回复: 27

[求助]:如何判断闭合曲线是顺时针还是逆时针方向

[复制链接]
发表于 2003-2-20 11:21:27 | 显示全部楼层 |阅读模式

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

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

×
如何判断闭合曲线是顺时针还是逆时针方向?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 145个

财富等级: 日进斗金

发表于 2003-2-20 18:11:20 | 显示全部楼层
最初由 binbin 发布
[B]getPointAtParam取三点,构造AcGeCircArc2d用isClockWise判断,这样会快一点!! [/B]


对于圆和椭圆,直接使用几何库AcGeCircArc2d::isClockWise ,AcGeEllipArc2d::isClockWise 就可以判断,BINBIN说的方法,对任意曲线,任意凹凸的不适合,不能判断出所有的情况。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2003-2-20 12:35:13 | 显示全部楼层

Re: [求助]:如何判断闭合曲线是顺时针还是逆时针方向

最初由 hothua 发布
[B]如何判断闭合曲线是顺时针还是逆时针方向? [/B]


以前探讨过,可以用行列式求曲线面积的方法,根据正负号,来判断曲线时针,你搜索下论坛,用 时针 做关键字。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 70个

财富等级: 招财进宝

发表于 2003-2-20 15:33:19 | 显示全部楼层
判断的方法如图所示,首先找到最西边的点,在图中是3号点,则从该点前一个点开始的连续三个点(在图中是2、3、4三个点)的排序就代表了整个拐点序列的排序;而这三个点的排序可以通过比较坐标方位角判断出来:若中间点到前点的坐标方位角小于中间点到后点的坐标方位角,则为逆时针排列,反之为顺时针排列。在图中α32小于α34,因此为逆时针排列。

注:“坐标方位角”是测量学名词,指从坐标系北方向顺时针转向有向直线的夹角。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-2-20 15:46:49 | 显示全部楼层
问一下:“闭合曲线是顺时针还是逆时针方向”在什么情况下用的着?还有,如何确定起点和终点,如gyl 用提供的图中,1到6的编号是随意的吗?
先学着,未雨筹谋。谢谢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

发表于 2003-2-20 17:19:35 | 显示全部楼层
getPointAtParam取三点,构造AcGeCircArc2d用isClockWise判断,这样会快一点!!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-2-20 17:51:30 | 显示全部楼层
照gyl的思路写的代码
//判断简单闭合曲线是顺时针(返回true),逆时针返回false
bool getCurveDirect(const AcGePoint3dArray& ptArray)
{
        ASSERT(ptArray.length()>=4 && ptArray.first().isEqualTo(ptArray.last())==Adesk::kTrue);

        double miny=ptArray[0].y;
        int pos=0;
        for(int i=1;i<ptArray.length();++i)
        {
                if(ptArray.y<miny)
                {
                        miny=ptArray.y;
                        pos=i;
                }
        }
        int prePos=pos-1;
        int nextPos=pos+1;
        if(prePos<0)
                prePos=ptArray.length()-1;
        if(nextPos>=ptArray.length())
                nextPos=0;       
        AcGeLine2d L2d1(ptArray[pos].convert2d(AcGePlane())
                ,ptArray[prePos].convert2d(AcGePlane()));
        AcGeLine2d L2d2(ptArray[pos].convert2d(AcGePlane())
                ,ptArray[nextPos].convert2d(AcGePlane()));
        AcGeVector2d v2d1=L2d1.direction();
        AcGeVector2d v2d2=L2d2.direction();
        ASSERT(v2d1.angle()!=v2d2.angle());
        if(v2d1.angle()<v2d2.angle())
                return true;//顺时针
        else
                return false;//逆时针       
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2003-2-20 18:05:16 | 显示全部楼层
我把XDRX_API里面的求任何曲线实体或者给定点表判断时针的代码贴出来(用行列式求面积的方法,修改下本函数,可以求任意曲线或者点表组成的面积),下面的函数适合“任意形状的凹凸曲线”

下面是定义的LISP调用的外部函数,逆时针返回T
  1. <normalfont>
  2. int isAntiClockWise()
  3. {
  4.         resbuf *rb=ads_getargs();
  5.         Acad::ErrorStatus es;
  6.         if (rb==NULL)
  7.                 return RTNORM;
  8.         AcGePoint3dArray nPts;
  9.         if (rb->restype==RTENAME){
  10.                 if (XdDbUtils::isAntiClockWise(rb->resval.rlname)){
  11.                         ads_rett();
  12.                         return RTNORM;
  13.                 }
  14.         }
  15.         resbuf *tail=NULL;
  16.         es=XdRbUtils::getPtArrayFromRbList(nPts,rb,tail);
  17.         if (es!=Acad::eOk)
  18.                 return RTNORM;
  19.         if (XdDbUtils::isAntiClockWise(nPts))
  20.                 ads_rett();
  21.         return RTNORM;
  22. }
  23. </normalfont>
复制代码


下面是通用的库
  1. <normalfont>
  2. BOOL XdDbUtils::isAntiClockWise(AcGePoint3dArray nPts)
  3. {
  4.         double area=0;
  5.         area=XdGeUtils::getPtArrayArea(&nPts);
  6.         if (area>0)
  7.                 return TRUE;
  8.         else if (area<0)
  9.                 return FALSE;
  10.         else return FALSE;
  11. }
  12. BOOL XdDbUtils::isAntiClockWise(ads_name ent)
  13. {
  14.         AcDbCurve *pCurve;
  15.         pCurve=isAcDbCurveEnt(ent);
  16.         if (pCurve==NULL)
  17.                 return FALSE;
  18.         AcGePoint3dArray nPts;
  19.         double tol=XdDbUtils::getScreenHigh()/40;
  20.         if ((XdDbUtils::getPolyVertxFromCurve(pCurve,nPts,tol))&&(isAntiClockWise(nPts))){
  21.                 return TRUE;
  22.         }
  23.         return FALSE;
  24. }
  25. BOOL XdDbUtils::isAntiClockWise(AcDbCurve *pCurve)
  26. {
  27.         if (pCurve==NULL)
  28.                 return FALSE;
  29.         AcGePoint3dArray nPts;
  30.         double tol=XdDbUtils::getScreenHigh()/40;
  31.         if ((XdDbUtils::getPolyVertxFromCurve(pCurve,nPts,tol))&&(isAntiClockWise(nPts))){
  32.                 return TRUE;
  33.         }
  34.         return FALSE;
  35. }
  36. </normalfont>
复制代码


下面是求封闭多边形面积的通用库(利用行列式算法,如果逆时针,面积为正,顺时针,面积为负)
  1. <normalfont>
  2. double XdGeUtils::getPtArrayArea(AcGePoint3dArray *nPts)
  3. {
  4.         int len=nPts->length();
  5.         double area=0.0;
  6.         if (len<3)
  7.                 return FALSE;
  8.         AcGePoint3d  spt,p1,p2;
  9.         spt=nPts->at(0);
  10.         for (int i=0;i<len-1;i++){
  11.                 p1=nPts->at(i);
  12.                 p2=nPts->at(i+1);
  13.                 area+=(p1.x*p2.y-p2.x*p1.y);
  14.         }
  15.         area=(area+(p2.x*spt.y-spt.x*p2.y))/2.0;
  16.         return area;
  17. }
  18. double XdGeUtils::getPtArrayArea(AcGePoint2dArray *nPts)
  19. {
  20.         int len=nPts->length();
  21.         double area=0.0;
  22.         if (len<3)
  23.                 return 0;
  24.         AcGePoint2d  spt,p1,p2;
  25.         spt=nPts->at(0);
  26.         for (int i=0;i<len-1;i++){
  27.                 p1=nPts->at(i);
  28.                 p2=nPts->at(i+1);
  29.                 area+=(p1.x*p2.y-p2.x*p1.y);
  30.         }
  31.         area=(area+(p2.x*spt.y-spt.x*p2.y))/2.0;
  32.         return area;
  33. }
  34. </normalfont>
复制代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-2-20 18:36:17 | 显示全部楼层
楼上几位大哥的方法各有千秋,但我有一个不用装什么程序的老方法,就是:
点选闭合线,右键编辑多段线--编辑顶点--下一个看点是什么方向走的就知是顺还是逆
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-2-20 19:48:29 | 显示全部楼层
谢谢XD,你的代码很值得拷贝一份,你以前上学好像学过类似计算面积的公式,没有在意.原来的书都不知道丢到哪里去了.
LQQ的回话很有意思,可以品味.
BINBIN的方法对所得的三点要求不能共线,在某些应用上可能有用
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 70个

财富等级: 招财进宝

发表于 2003-2-20 22:37:12 | 显示全部楼层
最初由 cssanhui 发布
[B]问一下:“闭合曲线是顺时针还是逆时针方向”在什么情况下用的着?还有,如何确定起点和终点,如gyl 用提供的图中,1到6的编号是随意的吗?
先学着,未雨筹谋。谢谢 [/B]


我不知道hothua 为什么要判断曲线方向,我以前在干地籍测量时,用AutoCAD绘制宗地图,要求拐点编号必须从西北角点开始,按顺时针方向排列,所以就研究过这个问题。图中1到6的编号从任意点开始连续排列就可以了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-2-21 11:23:52 | 显示全部楼层
晓东的方法是比较 顺时针的面积和逆时针的面积的大小.哪个大就认为是哪个.
其实我认为:对于有凹凸的情况是很难说的,因为他在某区域内是顺时针,在某区域内是逆时针.(请看图A,B),而对于情况C,就难说了!!(也就是说,时针问题对于凸多边形才有意义.)
还有,对于求面积,可以根据AcGePoint3dArray构造AcDbPolyline,然后用getArea得到.对于AcDbCurve直接用getArea得到.对于情况C,是得不到面积的,请教谁有好的方法!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-2-22 12:30:05 | 显示全部楼层
晓东求面积并不是比较大小,其实是比较正负,顺时针和逆时针所得到面积的绝对值是相等的.
图形C自相交,不属于简单多边形,复杂多变形比较难处理,你有兴趣可以深入研究,心得可以发表到图形图像学报上去.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2003-2-22 12:52:32 | 显示全部楼层
最初由 binbin 发布
[B]晓东的方法是比较 顺时针的面积和逆时针的面积的大小.哪个大就认为是哪个.
其实我认为:对于有凹凸的情况是很难说的,因为他在某区域内是顺时针,在某区域内是逆时针.(请看图A,B),而对于情况C,就难说了!!(也就是说,时?.. [/B]


hothua 说的对,面积绝对值是一样的,顺指针和逆时针得到的面积正负号不同。

其实只有圆(弧)、椭圆(弧)才有明确的时针方向,这也是为什么ARX几何库只提供了圆和椭圆的判断时针方向的方法,其他没有的原因。

对于复杂的凹凸,我们只能靠判断最后一个顶点到起点的方向来判断时针。(上面的行列式的面积正负能正确反映结果)

你的的C 行列式应该能计算出来,你把顶点依次做参数代入上面的函数,就用我上面提供的代码就可以。这也是我说的我提供的代码可以适合“任何凹凸曲线”的原因。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-14 21:58 , Processed in 0.218500 second(s), 59 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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