找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

楼主: wkai

[分享]:spline->pl的高效代码

[复制链接]
发表于 2004-1-11 00:33:13 | 显示全部楼层
最初由 wkai 发布
[B]

统统等分一千份的做法,对很短的曲线,尤其是很... [/B]

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

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-11 00:41:41 | 显示全部楼层
最初由 wkai 发布
[B]

统统等分一千份的做法,对很短的曲线,尤其是很... [/B]


不知我有没有理解错你的一楼代码的意思
下图还会继续下去吗?
(还有很多机会停下来的,只要刚好两点中点和两Param的一半处靠得很近.比如sin线cos线,没规律的也可能)

至于陌生人的方法,那是肯定不行的.



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

使用道具 举报

发表于 2004-1-11 00:41:58 | 显示全部楼层
很好的程序,能不能不用线段。用圆弧转换。谢了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-1-11 03:15:17 | 显示全部楼层
最初由 aeo 发布
[B]

不知我有没有理解错你的一楼代码的意思
下图还会继续下去吗?
(还有很多机会停下来的,只要刚好两点中点... [/B]

呵呵,我的怎么不行了。是不是依赖 fit ?这个好办(我上贴少了这部分处理的代码,不过,那是看着大伙兴致高,我凑凑热闹,随手写的,谁可补充完善?)
其实你的那段代码我也写过,后来舍弃了。因为拟合多义线点很多,用一个分段数来处理,过于死板,浪费,至少要加上后继的优化处理才有点意思。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-1-11 07:54:29 | 显示全部楼层
最初由 aeo 发布
[B]

不知我有没有理解错你的一楼代码的意思
下图还会继续下去吗?
(还有很多机会停下来的,只要刚好两点中点... [/B]


对,这种算法一直存在这个问题,需要改进~
但是,它的优点是能够自动用比较合适的节点数来模拟曲线~

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

使用道具 举报

发表于 2004-1-11 12:16:33 | 显示全部楼层
最初由 wkai 发布
[B]

对,这种算法一直存在这个问题,需要改进~
但是... [/B]

自动用比较合适的节点数来模拟曲线正是讨论的正题,大会除了以上方法,还想到什么?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2004-1-11 12:42:37 | 显示全部楼层
最初由 陌生人 发布
[B]
自动用比较合适的节点数来模拟曲线正是讨论的正题,大会除了以上方法,还想到什么? [/B]

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

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-11 14:47:51 | 显示全部楼层
我的也自动:)
还是我的老方法.(如果分1000份,最小容差为1/2000,依此类推)

  1. (defun C:TT ( / ed_par ed_par_new len n p1 p2 pmid pmid_par vlo pts)
  2.   (setq        VLO(vlax-ename->vla-object
  3.              (car(entsel "\n选择Spline,Ellipse:")))
  4.         ED_PAR             (vlax-curve-getendparam VLO)
  5.         len          (/(vlax-curve-getdistatparam VLO ED_PAR)2000.)
  6.         P1             (vlax-curve-getendpoint VLO)
  7.         n            (/ ED_PAR 1000.0)
  8.         ED_PAR_new   ED_PAR
  9.   )  
  10.   (command "_.PLINE" p1 "a")
  11.   (repeat 1000
  12.     (setq p2(vlax-curve-getpointatparam VLO(setq ED_PAR_new(- ED_PAR_new n)))
  13.           pmid_par(vlax-curve-getpointatparam VLO(/(+ ED_PAR_new ED_PAR)2.0))
  14.           pmid(mapcar '(lambda(x y)(/(+ x y)2.0))p1 p2)
  15.     )
  16.     (if(>(distance pmid pmid_par)len)
  17.          (progn(command "s" pmid_par p2)
  18.                (setq ED_PAR ED_PAR_new p1 p2)
  19.      ))         
  20.   )
  21.   (command "")
  22.   (vla-delete vlo)
  23. )


我觉得不管什么方法,最小容差是一定要给的(比如xd_api是根据显示精度来的,但还是给出了)
我的方法是从最小容差求出等分数量.


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

使用道具 举报

发表于 2004-1-11 16:57:48 | 显示全部楼层
“!!!我上面的好像少最后一点!!! ”
repeat 多一个可否?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-1-11 20:40:38 | 显示全部楼层
最初由 aeo 发布
[B]我的也自动:)
还是我的老方法.(如果分1000份,最小容差为1/2000,依此类推)
[/B]


斑竹的这段增加了判断代码很不错~
但是较真一些的话,也就意味着新生成的pl的顶点数不可能超过1000个~对于很长很复杂的曲线,可能模拟的精度是有限的~
如果增大等分份数的话,对于简单的曲线就显得太过迂回~


还有为了减少节点,程序中要求所有子线段的中点到spline的距离都大于[/COLOR] 预设的最小容差的!!使最小容差失去意义~

受你的启发,我也修改了代码~



  1.   [FONT=courier new]
  2. ;__2004.01.11.23.16_____________________________________
  3. ;__样条曲线--〉复义线___BY__WKAI__晓东CAD论坛___________
  4. (defun *error* (msg)
  5.   (print st_pt)
  6.   (print st_p)
  7.   (print mid_pt)
  8.   (print ed_pt)
  9.   (print ed_p)

  10. )
  11. (defun c:tt (/ pts min_distacne vlo st_par ed_par ent n)
  12.   (setq        vlo             (vlax-ename->vla-object (setq ent (car (entsel "\n选择spline:"))))
  13.         st_par             (vlax-curve-getstartparam vlo)
  14.         ed_par             (vlax-curve-getendparam vlo)
  15.         pts             (list (vlax-curve-getstartpoint vlo))
  16.         min_distacne (/ (vlax-curve-getdistatparam vlo ed_par) 10000.0)
  17. ;;;_拟合精度,即拟合复义线与spline的最大距离。默认为spline长度的千分一
  18.         n             0
  19.   )
  20.   (t1 vlo st_par ed_par)
  21.   (command "pline")
  22.   (foreach n pts (command "non" n))
  23.   (command)
  24.   (princ (strcat "\n创建一条顶点数为" (itoa (length pts)) "的复义线。"))
  25.   (princ)
  26. )
  27. ;________________________________________________________
  28. ;________________________________________________________
  29. (defun t1 (vl_obj start_par end_par / dis_m_m ed_p ed_pt mid_p mid_pt mid_pt_vlo st_p st_pt)
  30.   (setq        st_p           start_par
  31.         ed_p           end_par
  32.         st_pt           (vlax-curve-getpointatparam vl_obj st_p)
  33.         ed_pt           (if (vlax-curve-getpointatparam vl_obj ed_p)
  34.                      (vlax-curve-getpointatparam vl_obj ed_p)
  35.                      (vlax-curve-getendpoint vl_obj)
  36.                    )
  37.         mid_p           (/ (+ st_p ed_p) 2.0)
  38.         mid_pt           (mapcar '(lambda (x y) (/ (+ x y) 2.0)) st_pt ed_pt)
  39.         mid_pt_vlo (vlax-curve-getpointatparam vl_obj mid_p)
  40.         dis_m_m           (distance mid_pt_vlo mid_pt)
  41.   )
  42.   (if (or (> dis_m_m min_distacne) (t2 vl_obj start_par end_par st_pt ed_pt))
  43.     (progn
  44.       (t1 vl_obj st_p mid_p)
  45.       (t1 vl_obj mid_p ed_p)
  46.     )
  47.     (setq pts (append pts (list mid_pt_vlo) (list ed_pt)))
  48.   )
  49. )
  50. ;_____________________________________________________________
  51. (defun t2 (vl st_par ed_par s_pt e_pt / run delta_p delta_pt)
  52.   (setq        run         t
  53.         delta_p         (/ (- ed_par st_par) 5.0)
  54.         delta_pt (mapcar '(lambda (x y) (/ (- x y) 5.0)) e_pt s_pt)
  55.   )
  56.   (while (and run (< (setq st_par (+ st_par delta_p)) ed_par))   
  57.       (if (> (distance (vlax-curve-getpointatparam vl st_par)
  58.                        (setq s_pt (mapcar '(lambda (x y) (+ x y)) s_pt delta_pt))
  59.              )
  60.              min_distacne
  61.           )
  62.         (setq run nil)      
  63.     )
  64.   )
  65.   (not run)
  66. )
  67. ;________________________________________________________
  68. ;________________________________________________________
  69. (princ "\n样条曲线--〉复义线___BY__WKAI__晓东CAD论坛")
  70.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-1-11 23:40:14 | 显示全部楼层
对版主的程序,可以这样:spline越复杂,控制点越多。在每段spline控制点之间进行固定精度的模拟
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-11 23:43:33 | 显示全部楼层
你可能没看明白:
真要写的话,应该是先给精度(a),就是你的千分之一长,(线长l)
然后,根据精度求出等分数.(l/2a)

因为如果每一份为2a时,这时弓高比已经很大了.(说明分的不细,还要减小a)
如果你的千分之一可行,我的也可行.

精度:你的是小那么一点,我是大那么一点.
各有优点,你的也可能太细
靠给精度调节.


repeat 多一个可否?
不行!
为什么少:是因为最后一点有可能没满足精度(还不到画的时候),应该硬加上去.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-1-11 23:58:10 | 显示全部楼层
或者这么说,
对于特别复杂的曲线,你的代码得到的顶点数最多为你设定的值(上例为1000),对么?
我的代码则不然,可以根据曲线的复杂程度得到足够满足精度的合适的顶点数,~

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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2004-1-12 00:07:09 | 显示全部楼层
用PL模拟SPLINE,最好用“玄高距离”小于一个适当的数值,这样才能对“缓的”,“陡的”SPLINE都能模拟,用顶点数等分不合适,在曲率变化急剧处,就模拟不好了。

玄高距离一般应用用用屏幕显示高度作为一个比较参数较好,可以符合视觉误差。保证眼睛看起来符合就足够了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-12 00:11:31 | 显示全部楼层
to wkai :
你的如果是给千分之一长,也不可能超过1000点的,
如果超过1000点,那这线一定是折了1000下,并且每折的高弦比大于1,就算出来,也是个四不象.

我的次数是根据给的精度来的.再算出次数.
我要求的精度就是xd说的玄高距离(a)
n= l / 2a ,这样分已经足够细了.


  1. [php]
  2. (defun C:TT ( / ed_par ed_par_new len n p1 p2 pmid pmid_par vlo pts no)
  3. (setq        VLO(vlax-ename->vla-object
  4.              (car(entsel "\n选择Spline,Ellipse:")))
  5.         ED_PAR             (vlax-curve-getendparam VLO)
  6.         len         (getreal "\n偏多少为假定在曲线上:");原来的1/2000 * l
  7.         ;;;len          (/(vlax-curve-getdistatparam VLO ED_PAR)2000.)
  8.         P1             (vlax-curve-getendpoint VLO)
  9.         no           (/(vlax-curve-getdistatparam VLO ED_PAR) 2 len) ;次数
  10.         ;;;n            (/ ED_PAR 1000.0)
  11.         n            (/ ED_PAR no);原来的1000
  12.         ED_PAR_new   ED_PAR
  13.   )
  14.   
  15.   (command "_.PLINE" p1 "a")
  16.   (repeat (1- no) ;原来的1000
  17.     (setq p2(vlax-curve-getpointatparam VLO(setq ED_PAR_new(- ED_PAR_new n)))
  18.           pmid_par(vlax-curve-getpointatparam VLO(/(+ ED_PAR_new ED_PAR)2.0))
  19.           pmid(mapcar '(lambda(x y)(/(+ x y)2.0))p1 p2)
  20.     )
  21.     (if(>(distance pmid pmid_par)len)
  22.          (progn(command "s" pmid_par p2)
  23.                (setq ED_PAR ED_PAR_new p1 p2)
  24.      ))         
  25.   )
  26.   
  27.   (setq pmid_par(vlax-curve-getpointatparam VLO (/ ED_PAR 2.) )) ; 最后一点
  28.   (command "s" pmid_par (vlax-curve-getstartpoint VLO))
  29.   
  30.   (command "")
  31.   (vla-delete vlo)
  32. ) [/php]

我仔细想来应该可以,就是最后一点不匀称.
如果认为不细:n= l / a ,其实出来结果是一样的.

你上面的还不行,应该“每一次”判断是不是中点落在param/2上
因为分了一半,那"一半"还可能是我画的那种情况.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-8 12:17 , Processed in 0.396482 second(s), 53 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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