找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1314|回复: 4

[研讨] XDGE几何库应用(23)--精度对Ge模型影响

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2014-10-2 11:06:47 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 st788796 于 2014-11-1 07:55 编辑

一个求两个曲线首尾连接后闭合区域的测试,Ge 的 AcGeCompositeCurve3d 和 AcDbRegion 对比,在 xdrxapi 中默认长度精度是 0.01 ,在 ARX 内部模式 Tol  是 1e-10 (Provides a "global" default tolerance object. This is an AcGeTol object that contains the default AcGeTol tolerance values (equalPoint and equalVector tolerances set to 1.e-10). ,这个应用中可以看到 面积 差在 5% 左右,长度差不大,不过即使用直线段测试也存在误差,搞不懂 Ge 是怎么算的

原帖地址 http://bbs.xdcad.net/forum.php?m ... 4025&extra=page%3D1

  1. (defun c:tt (/ e1 e2 ge1 ge2 sp1 ep1 sp2 ep2 tmp pl ge3d1 ge3d2 gcc gel1
  2.                gel2 in endparam lst region old
  3.             )                               ; (setq old (xdrx_document_getprec))
  4.                                        ; (xdrx_document_setprec 1e-8 (cadr
  5.                                        ; old));_单纯提高长度精度会造成 area
  6.                                        ; 为nil
  7.   (if (and
  8.         (setq e1 (car (xdrx_entsel "\nPicks Pline: " '((0 . "*Polyline,Line,Arc,Ellipse,Spline")))))
  9.         (setq e2 (car (xdrx_entsel "\nPicks Pline: " '((0 . "*Polyline,Line,Arc,Ellipse,Spline"))))) ; _两条单一线两端直连形成的闭合区域投影面积
  10.         (setq ge1 (xdge::constructor e1))
  11.         (not (xdge::getpropertyvalue ge1 "isClosed"))
  12.         (setq ge2 (xdge::constructor e2))
  13.         (not (xdge::getpropertyvalue ge2 "isClosed"))
  14.         (setq gcc (xdge::constructor "kCurveCurveInt3d" ge1 ge2))
  15.         (zerop (xdge::getpropertyvalue gcc "numIntPoints"))
  16.       )
  17.     (progn
  18.       (mapcar
  19.         'set
  20.         '(sp1 ep1)
  21.         (xdge::getpropertyvalue ge1 "hasStartPoint" "hasEndPoint")
  22.       )
  23.       (mapcar
  24.         'set
  25.         '(sp2 ep2)
  26.         (xdge::getpropertyvalue ge2 "hasStartPoint" "hasEndPoint")
  27.       )
  28.       (if (inters
  29.             ep1
  30.             sp2
  31.             ep1
  32.             sp1
  33.           )                               ; _检查方向,交叉时对其中之一换方向
  34.         (progn
  35.           (xdge::getpropertyvalue ge2 "reverseParam")
  36.           (setq tmp sp2
  37.                 sp2 ep2
  38.                 ep2 tmp
  39.           )
  40.         )
  41.       )
  42.       (grvecs (list -1 ep1 sp2 -1 ep2 sp1))
  43.       (setq ln1 (xdge::constructor "kLineSeg3d" ep1 sp2)
  44.             ln2 (xdge::constructor "kLineSeg3d" ep2 sp1)
  45.       )                                       ; _两端封口
  46.                                        ; 构建符合线的 Ge
  47.                                        ; 须是简单线,不能复合线与简单线混合
  48.       (if (eq (xdge::type ge1) "kCompositeCrv3d")
  49.         (setq gel1 (xdge::getpropertyvalue ge1 "getCurveList"))
  50.         (setq gel1 (list ge1))
  51.       )
  52.       (if (eq (xdge::type ge2) "kCompositeCrv3d")
  53.         (setq gel2 (xdge::getpropertyvalue ge2 "getCurveList"))
  54.         (setq gel2 (list ge2))
  55.       )
  56.       (setq pl (xdge::constructor "kCompositeCrv3d" (append
  57.                                                       gel1
  58.                                                       (list ln1)
  59.                                                       gel2
  60.                                                       (list ln2)
  61.                                                     ) ; _简单线表
  62.                )
  63.             in (car (xdge::getpropertyvalue pl "getInterval")) ; _要用
  64.                                        ; Interval 查询 endparam
  65.             endparam (xdge::getpropertyvalue in "upperBound") ; _上限
  66.             lst (xdge::getpropertyvalue pl "area" 0.0 endparam "length" 0.0
  67.                                         endparam
  68.                 )
  69.       )                                       ; _构建连续复合线
  70.       (princ "\nCompositeCurve Area = ")
  71.       (princ (rtos (car lst) 2 4))     ; _此处和 Region测得的面积有误差
  72.       (princ "\nCompositeCurve Length = ")
  73.       (princ (rtos (cadr lst) 2 4))
  74.       (setq region (xdrx_getpropertyvalue (ssname
  75.                                                   (xdrx_curve->region
  76.                                                                       (xdge::entity:make ge1 ge2 ln1 ln2)
  77.                                                   ) 0
  78.                                           ) "area" "Perimeter"
  79.                    )
  80.       )
  81.       (princ "\n---------------------------------")
  82.       (princ "\nRegion Area = ")
  83.       (princ (rtos (car region) 2 4))  ; _此处和 Region测得的面积有误差
  84.       (princ "\nRegion Length = ")
  85.       (princ (rtos (cadr region) 2 4))
  86.       (princ "\n---------------------------------")
  87.       (princ "\n")
  88.       (princ (mapcar
  89.                '-
  90.                region
  91.                lst
  92.              )
  93.       )
  94.       (princ "\n---------------------------------")
  95.       (princ "\n")
  96.       (princ (mapcar
  97.                '/
  98.                (mapcar
  99.                  'abs
  100.                  (mapcar
  101.                    '-
  102.                    region
  103.                    lst
  104.                  )
  105.                )
  106.                region
  107.              )
  108.       )
  109.       (princ)
  110.     )
  111.   )                                       ; (apply 'xdrx_document_setprec old)
  112.   (xdge::free)
  113.   (princ)
  114. )

forum.php?mod=attachment&aid=ODU4NXwxY2ZkYTJkM3wxNDEyMjA3Nzg4fDE4NjA4fDY3NDAyNQ%3D%3D.gif

本帖被以下淘专辑推荐:

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

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-10-2 11:09:23 | 显示全部楼层
命令: tt
Picks Pline:
Picks Pline:
CompositeCurve Area = 3943111.9298
CompositeCurve Length = 8778.0769
---------------------------------
Region Area = 3963976.0667

Region Length = 8778.0667
---------------------------------
(20864.1 -0.010213)
---------------------------------
(0.00526344 1.16346e-006)
20141002110834.jpg
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2014-10-2 11:14:37 | 显示全部楼层
AcGeCompositeCurve 的结束参数可以这样求得
  1. (setq glst     (xdge::getpropertyvalue gcom "getCurveList")
  2.       endparam (xdge::getpropertyvalue
  3.                  gcom
  4.                  "localToGlobalParam"
  5.                  1.0
  6.                  (1- (length glst))
  7.                )
  8. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-10-2 12:16:59 | 显示全部楼层
本帖最后由 csharp 于 2014-10-2 12:27 编辑

在 Net 中用系统默认精度这样测试了下,误差没有二楼那么大

然后又在 Autocad 中试着将 API 内部 prec 两个值设置一致后 Ge 模型和 Region 误差就很小了,和 net  测试结果基本一致

  (xdrx_document_setprec 1e-10 1e-10)

命令: tt
Picks Pline:
Picks Pline:
CompositeCurve Area = 1916591.5121
CompositeCurve Length = 5770.6397
命令:
命令: aa AREA
指定第一个角点或 [对象(O)/加(A)/减(S)]: e
选择对象:
面积 = 1916591.5440,周长 = 6404.5092

构造 CompositeCurve 时省略了最后一段, area 自动将首尾连接计算

Net 简单测试代码,三条首尾相接 Curve

  1.         [CommandMethod("test1")]
  2.         public void Test01()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             Transaction tr = db.TransactionManager.StartTransaction();
  8.             PromptSelectionResult psr = ed.GetSelection();
  9.             if (psr.Status != PromptStatus.OK) return;
  10.             using (tr)
  11.             {
  12.                 BlockTableRecord btr = (BlockTableRecord) tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  13.                 ObjectId[] ids = psr.Value.GetObjectIds();
  14.                 Curve3d[] cc3ds = ids.Select(c => ((Curve)c.GetObject(OpenMode.ForRead)).GetGeCurve()).ToArray();
  15.                 CompositeCurve3d cc = new CompositeCurve3d(cc3ds);
  16.                 double area = cc.GetArea(cc.GetParameterOf(cc.StartPoint),
  17.                     cc.GetParameterOf(cc.EndPoint),
  18.                     Tolerance.Global);
  19.                 ed.WriteMessage(area.ToString());
  20.                 tr.Commit();
  21.             }
  22.         }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 264个

财富等级: 日进斗金

发表于 2014-10-2 12:56:45 来自手机 | 显示全部楼层
哪个准确只有AutoDESK知道,差一点点可以接受,反正在AutoCAD里面也没有别的方法测量
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 13:19 , Processed in 0.269510 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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