找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1380|回复: 0

[ARX程序]:构造自己的射线算法,测试点是否在曲线内的ARX完整代码 by XDSoft

[复制链接]

已领礼包: 444个

财富等级: 日进斗金

发表于 2002-1-24 18:45:03 | 显示全部楼层 |阅读模式

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

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

×

  1. // includes from ObjectARX Wizard
  2. #include "acdb.h"          // acdb definitions
  3. #include "adslib.h"          // ads defs
  4. #include "aced.h"          // aced stuff
  5. #include "dbsymtb.h"          // symboltables
  6. #include "rxregsvc.h"          // unlock application
  7. #include "dbcurve.h"
  8. #include "gevec3d.h"
  9. #include "dbray.h"
  10. #include "dbautil.h"
  11. #include "geassign.h"
  12. #include "dbents.h"

  13. // entry point for this application
  14. extern "C" AcRx::AppRetCode acrxEntryPoint( AcRx::AppMsgCode msg, void* );
  15. // message handlers

  16. // helper functions
  17. static void initApp  (void);
  18. static void unloadApp(void);

  19. void utilsisinside    (void );


  20. // end of declaration

  21. /////////////////////////////////////////////////////////////////////
  22. // acrxEntryPoint(internal)
  23. // This function is the entry point for your application.
  24. /////////////////////////////////////////////////////////////////////
  25. AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* ptr)
  26. {
  27.   switch (msg) {
  28.     case AcRx::kInitAppMsg:
  29.       acrxUnlockApplication(ptr);
  30.       initApp();
  31.       break;
  32.     case AcRx::kUnloadAppMsg:
  33.       unloadApp();
  34.       break;
  35.     default:
  36.       break;
  37.   }
  38.   return AcRx::kRetOK;
  39. }

  40. static void initApp(void)
  41. {
  42.   // register your autocad commands
  43.   acedRegCmds->addCommand("UTILS", "ISINSIDE", "ISINSIDE", ACRX_CMD_MODAL,
  44. utilsisinside);

  45. } // END initApp()

  46. static void unloadApp(void)
  47. {
  48.   // unregister your autocad commands
  49.   acedRegCmds->removeGroup("UTILS");
  50.   // END unloadApp()
  51. }


  52. enum IncidenceType {
  53.     kIncidenceToLeft = 0,
  54.     kIncidenceToRight = 1,
  55.     kIncidenceToFront =2,
  56.     kIncidenceUnknown };

  57. IncidenceType CurveIncidence(AcDbCurve*pCurve, double param, AcGeVector3d
  58. dir, AcGeVector3d normal )
  59. {
  60.     AcGeVector3d deriv1;

  61.     pCurve->getFirstDeriv( param, deriv1 );
  62.     if( deriv1.isParallelTo( dir )) {
  63.      // need second degree analysis
  64.      AcGeVector3d deriv2;
  65.      pCurve->getSecondDeriv( param, deriv2 );
  66.      if( deriv2.isZeroLength() ||  deriv2.isParallelTo( dir ) ) {
  67.         return kIncidenceToFront;
  68.      } else if(deriv2.crossProduct( dir ).dotProduct( normal ) < 0 ) {
  69.         return kIncidenceToRight;
  70.      } else {
  71.         return kIncidenceToLeft;

  72.      }
  73.     }
  74.      
  75.     if( deriv1.crossProduct( dir ).dotProduct( normal ) < 0 ) {
  76.      return kIncidenceToLeft;
  77.     } else {
  78.      return kIncidenceToRight;
  79.     }
  80. }

  81. Adesk::Boolean IsInsideCurve(AcDbCurve*pCurve, AcGePoint3d testPt )
  82. {
  83.     if(!pCurve->isClosed() || !pCurve) {
  84.      // cannot be inside
  85.      return Adesk::kFalse;
  86.     }

  87.     Acad::ErrorStatus es;

  88.     AcDb2dPolyline*p2dPoly = AcDb2dPolyline::cast(pCurve);
  89.     if( p2dPoly != NULL && p2dPoly->polyType() != AcDb::k2dSimplePoly ) {
  90.         // Not supported
  91.         return Adesk::kFalse;
  92.     }

  93.     AcGePoint3d ptOnCurve;
  94.     es = pCurve->getClosestPointTo(testPt, ptOnCurve  );
  95.     if( testPt == ptOnCurve ) {
  96.      return Adesk::kTrue;
  97.     }

  98.     // check its planar
  99.     AcGePlane plane;
  100.     AcDb::Planarity planarity;
  101.     es = pCurve->getPlane(plane, planarity );
  102.     if( es != Acad::eOk || planarity != AcDb::kPlanar ) {
  103.      return Adesk::kFalse;
  104.     }

  105.     // make the test ray from the plane
  106.     AcGeVector3d normal = plane.normal();
  107.     AcGeVector3d testVector = normal.perpVector();
  108.     AcDbRay ray;
  109.     ray.setBasePoint(testPt);
  110.     ray.setUnitDir(testVector);

  111.     AcGePoint3dArray IntersectionPoints;

  112.     // fire the ray at the curve
  113.     es = pCurve->intersectWith(&ray, AcDb::kOnBothOperands,
  114. IntersectionPoints);
  115.     if(es != Acad::eOk) {
  116.      return Adesk::kFalse;
  117.     }
  118.     int numberOfInters = IntersectionPoints.length();

  119.     if(numberOfInters == 0) {
  120.      // must be outside
  121.      return Adesk::kFalse;
  122.     }
  123.     int nGlancingHits = 0;
  124.     double epsilon = 2e-6; // ( trust me on this )
  125.     for( int i=0;i < numberOfInters; i++ ) {

  126.      // get the first point, and get its parameter
  127.      AcGePoint3d hitPt = IntersectionPoints[i];
  128.      double hitParam;
  129.      es = pCurve->getParamAtPoint(hitPt, hitParam );
  130.      if(es != Acad::eOk) {
  131.         return Adesk::kFalse;
  132.      }
  133.      double inParam = hitParam - epsilon;
  134.      double outParam = hitParam + epsilon;

  135.      IncidenceType inIncidence = CurveIncidence(pCurve, inParam,
  136. testVector, normal );
  137.      IncidenceType outIncidence = CurveIncidence(pCurve, outParam,
  138. testVector, normal );

  139.      if( ( inIncidence == kIncidenceToRight && outIncidence ==
  140. kIncidenceToLeft ) ||
  141.         ( inIncidence == kIncidenceToLeft && outIncidence ==
  142. kIncidenceToRight ) )
  143.      {
  144.         nGlancingHits ++;
  145.      }
  146.     }

  147.     return (( numberOfInters + nGlancingHits) % 2 == 1);
  148. }

  149. void utilsisinside()
  150. {
  151.     ads_name eName;
  152.     ads_point pt;

  153.     if( RTNORM != ads_entsel( "\nPlease pick a curve ", eName, pt ) ) {
  154.      return;
  155.     }

  156.     AcDbObjectId curveId;

  157.     acdbGetObjectId( curveId, eName );

  158.     AcDbCurve*pCurve = NULL;
  159.     acdbOpenObject(pCurve, curveId, AcDb::kForRead );
  160.     if( pCurve == NULL ) {
  161.      return;
  162.     }

  163.     while( RTNORM == ads_getpoint( NULL, "\nPlease pick a point ", pt ) ) {

  164.      acdbUcs2Wcs( pt, pt, Adesk::kFalse );
  165.      
  166.      Adesk::Boolean isIn;
  167.      isIn = IsInsideCurve( pCurve, asPnt3d( pt ) );
  168.      ads_printf("\n%s", isIn ? "INSIDE OR ON" : "OUTSIDE" );

  169.    
  170.     }

  171.     pCurve->close();
  172. }
复制代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-5-1 07:35 , Processed in 0.236525 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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