找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1950|回复: 17

[求助] [求助]:如何让程序计算出的点优先于捕捉点?

[复制链接]
发表于 2005-8-6 23:38:38 | 显示全部楼层 |阅读模式

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

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

×
请看:

(defun mpt (/ a b mx my mz)

(initget 1)
(setq a (getpoint "\nFirst Point: "))
(initget 1)
(setq b (getpoint "\nSecond Point: "))

(setq mx (/ (+ (car b) (car a)) 2.0))
(setq my (/ (+ (cadr b) (cadr a)) 2.0))
(setq mz (/ (+ (caddr b) (caddr a)) 2.0))
(setq pt (list mx my mz))

)

以上是一个计算两选取点之间的中点的小程序。可作为一种补充的捕捉方式, 用于在需要输入一个点时捕捉一个另外两点的中间点, 如矩形房间的中心点等。

程序本身是没问题的,但是想实现上述应用时会有问题:

如果点捕捉状态[osmode]打开并且有预设的捕捉方式时,就有可能捕捉到别的点。 比如说想捕捉矩形房间的中心点, 程序的确是计算出了该点, 而如果图中该中心点处(或附近)有一个其它实体,autocad就会按照预设的捕捉方式捕捉到该实体的某个点上。
也就是说autocad的捕捉方式覆盖了计算点。

不要告诉我说在运行这个程序前先按F3关闭点捕捉模式,运行完再按F3打开之。这么简单的话我就不来这问这个问题了,呵呵。因为我希望在程序运行时点捕捉模式仍然处于打开状态,以便我点取两个点的时候还能用自动捕捉的方式捕捉如矩形框的对角点等。

也不要告诉我说在那两个getpoint 语句后加一个关闭点捕捉模式的语句。因为我不想计算完中点后再人工方式来恢复点捕捉模式。

难者不会,会者不难,高手快来帮忙啊。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2005-8-7 01:13:39 | 显示全部楼层
不会再用vlr-command-reactor 函数吧?!
你这个函数根本没必要考虑捕捉问题:
[php](defun mpt (/ a b mx my mz)
  (while(not(setq a (getpoint "\nFirst Point : "))))
  (while(not(setq b (getpoint a "\nSecond Point: "))))
  (setq mx (/ (+ (car b) (car a)) 2.0))
  (setq my (/ (+ (cadr b) (cadr a)) 2.0))
  (setq mz (/ (+ (caddr b) (caddr a)) 2.0))
  (setq pt (list mx my mz))
  pt   
)[/php]

通常情况:
[php](setq os(getvar"osmode"));程序开始时
……
……
(setvar"osmode" 0);程序中间
……
……
(setvar"osmode" os);程序结束前[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2005-8-7 12:02:07 | 显示全部楼层
呵呵,可能是我的语文水平有限, 没把问题表达清楚。

首先,(mpt)程序是一点问题也没有的, 当然xyp1964的程序更标准更完美些。

其次, 问题在于用这个(mpt)程序去捕捉一个点(某两个选取点的中间点)时,会受到autocad捕捉设置的影响。

请先加载xyp1964的程序(mpt),然后试试这个极为简单的例子:

第一步, 设置autocad捕捉仅为 “端点捕捉”(也就是仅自动捕捉end点);

第二步,画一条line线段(两个端点的线段);

第三步,我们来试一下(mpt)函数,打算以刚画的线段的中点为起点再画一条线,于是在command: 提示符下输入:

command: line [回车]
Specify first point: (mpt) [回车]
First point : [点取刚画的第一条线段的一个端点]
Second point : [点取刚画的第一条线段的另一个端点]

注意了, 这第二条线的起始点并没有按希望的那样从第一条线段的中点开始, 而是从第一条线段的一个端点开始的。

道理很简单, (mpt)确实计算出了中点, 但是在这个中点上刚好有一条线段经过, 而autocad的自动捕捉是端点,所以最后的结果跑到了那条线段的端点上。


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

使用道具 举报

发表于 2005-8-7 14:20:51 | 显示全部楼层
我觉得这里面有一个概念问题。mpt程序本身没有问题,他计算出了中点并且返回了点坐标,他的任务就完成了,至于这个中点坐标会被用来干什么就不是他的事情了。当你在line命令中调用mpt时,他确实返回了中点坐标,只不过在仅仅端点捕捉的情况下,这个中点被用来捕捉到了线段的端点,这不是mpt的错,是捕捉的问题。如果在mpt程序里面解决这个问题,不符合编制程序的原则,因为他“越权”了。
办法有两个:
1。使用mpt前手动设置捕捉方式。
2。在mpt中检查捕捉方式,并对用户给出提示信息。

如果你还是、一定、非得实现你的想法,如下试试:
[php]
;;;下面的程序在调用mpt的命令结束后才恢复捕捉状态
(defun recover_snap ( reactor_object cmd_list / )
        (setvar "osmode" $$mpt_osmode)
        (vlr-remove $$mptReactor)
)

(defun mpt ( / a b mx my mz )
        (while (not (setq a (getpoint "\nFirst Point : "))))
        (while (not (setq b (getpoint a "\nSecond Point: "))))
        (setq mx (/ (+ (car b) (car a)) 2.0))
        (setq my (/ (+ (cadr b) (cadr a)) 2.0))
        (setq mz (/ (+ (caddr b) (caddr a)) 2.0))
        (setq $$mpt_osmode (getvar "osmode"))
        (setvar "osmode" 0)
        (setq $$mptReactor (vlr-command-reactor data '((:vlr-commandEnded . recover_snap))))
        (setq pt (list mx my mz))
)


;;;下面的程序在mpt结束以后就可以恢复捕捉状态
(defun recover_snap ( reactor_object lisp_list / )
        (setvar "osmode" $$mpt_osmode)
        (vlr-remove $$mptReactor)
)

(defun mpt ( / a b mx my mz )
        (while (not (setq a (getpoint "\nFirst Point : "))))
        (while (not (setq b (getpoint a "\nSecond Point: "))))
        (setq mx (/ (+ (car b) (car a)) 2.0))
        (setq my (/ (+ (cadr b) (cadr a)) 2.0))
        (setq mz (/ (+ (caddr b) (caddr a)) 2.0))
        (setq $$mpt_osmode (getvar "osmode"))
        (setvar "osmode" 0)
        (setq $$mptReactor (vlr-lisp-reactor data '((:vlr-lispEnded . recover_snap))))
        (setq pt (list mx my mz))
)
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-7 21:09:37 | 显示全部楼层
最初由 doubao 发布
[B]呵呵,可能是我的语文水平有限, 没把问题表达清楚。

首先,(mpt)程序是一点问题也没有的, 当然xyp1964的程序更标准更完美些。

其次, 问题在于用这个(mpt)程序去捕捉一个点(某两个选取点的中间点)时?.. [/B]

仅仅画画线,也要用反应器,就象大炮打蚊子!呵呵……
看看这个例子:
  1. [FONT=courier new]
  2. (defun c:test ()
  3.   (setq os (getvar "osmode"))
  4.   (command "line")
  5.   (while (setq pt1 (getpoint "\nFirst Point : "))
  6.     (setq pt2 (getpoint pt1 "\nSecond Point : "))
  7.     (if        pt2
  8.       (progn
  9.         (setvar "osmode" 0)
  10.         (setq pt (mpt pt1 pt2))
  11.         (command pt)
  12.         (setvar "osmode" os)
  13.       )
  14.     )
  15.   )
  16.   (command "")
  17.   (setvar "osmode" os)
  18.   (princ)
  19. )

  20. (defun mpt (a b / mx my mz)
  21.   (setq        mx (/ (+ (car b) (car a)) 2.0)
  22.         my (/ (+ (cadr b) (cadr a)) 2.0)
  23.         mz (/ (+ (caddr b) (caddr a)) 2.0)
  24.         pt (list mx my mz)
  25.   )
  26.   pt
  27. )[/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-7 21:20:13 | 显示全部楼层
版主呀,看来你还没理解楼主的意思,呵呵
人家的mpt要适用于任何命令中的,不仅仅一个line。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-7 21:20:50 | 显示全部楼层
非常感谢5楼的程序。

试了一下好像还是不行。 不过我觉得思路还是可行的。

呵呵,我还是、一定、非得实现我的想法的。因为这是一个很实际的问题。 我想用mpt程序捕捉一个两点间的中点,结果老是捕捉到别的点, 您说烦不烦呀。 如果在制图过程中来回手动设置捕捉,那就失去了我编这个程序的目的了。

使用mpt前手动设置捕捉方式也不理想, 因为我希望在点取两个端点时还用得上autocad的自动捕捉。

再举个类比的例子可能大家会更明白我的意思:

autocad的捕捉功能里有个“snap from”的捕捉项大家都知道吧, 人家这个捕捉为什么就不会受osnap设置的影响呢? 它在选取from点时仍然可以自动捕捉, 计算出offset点后决不会被osnap设置所覆盖而跑到其他点上。

我也想把mpt作为一个捕捉功能来用。好,咱先别提这个mpt了, 免得大家老是在mtp程序里面转圈圈。我们面对的是这样一个问题:


怎样实现捕捉一个两点取点中间点的功能而完全不受osnap设置的影响?


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

使用道具 举报

发表于 2005-8-7 21:41:14 | 显示全部楼层
你试了有什么问题?我这里没问题呀?
你得说清楚一些。

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

使用道具 举报

 楼主| 发表于 2005-8-7 21:55:09 | 显示全部楼层
最初由 ohmylove 发布
[B]你试了有什么问题?我这里没问题呀?

第二种程序就能实现你的要求。 [/B]


我只是照搬了您的程序,并且是在autocad2006 里试的。

问题的现象之一是还只捉到端点, 之二是似乎没法恢复osmode了, 不论我怎么设osmode, 总是关闭状态, 另开一张新图就没事了。不好意思, 我对反应器其实很陌生, 所以不明其原因。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-7 21:56:03 | 显示全部楼层
最初由 ohmylove 发布
[B]版主呀,看来你还没理解楼主的意思,呵呵
人家的mpt要适用于任何命令中的,不仅仅一个line。 [/B]

这个mpt才是真正的通用子程序:
[php](defun mpt (a b / mx my mz)
  (setq        mx (/ (+ (car b) (car a)) 2.0)
        my (/ (+ (cadr b) (cadr a)) 2.0)
        mz (/ (+ (caddr b) (caddr a)) 2.0)
        pt (list mx my mz)
  )
  pt
)[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-7 22:01:48 | 显示全部楼层
最初由 doubao 发布
[B]非常感谢5楼的程序。

试了一下好像还是不行。 不过我觉得思路还是可行的。

呵呵,我还是、一定、非得实现我的想法的。因为这是一个很实际的问题。 我想用mpt程序捕捉一个两点间的中点,结果老是捕捉到别的点,... [/B]

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

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2005-8-7 22:18:23 | 显示全部楼层
最初由 xyp1964 发布
[B]
这个mpt才是真正的通用子程序:
[php](defun mpt (a b / mx my... [/B]


您给出的这个mpt的确可以作为真正的通用子程序, 不过问题只解决了一部分, 接下来怎样实现我所需要的捕捉功能呢?


--------------------
另:

再次感谢ohmylove提供的程序, 可是我下载有点问题, 可能是我的日均在线时间还太少的缘故吧。我会继续努力的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-8-7 23:32:25 | 显示全部楼层
最初由 doubao 发布
[B]

您给出的这个mpt的确可以作为真正的通用子程序, 不过问题只解决了一部分, 接下来怎样... [/B]

一个波浪线的程序,可以看看osmode是如何根据需要设置的:
  1. [FONT=courier new]
  2. (load "xyp_lib")
  3. ;|加载通用函数(可在签名栏直接下载)
  4. 如果已经下载xyp_lib并放到搜索路径下可以不再下载!
  5. 利用以下任何一种方式即可加载和运行通用函数内的所有子程序:
  6. 1.在acad.lsp中增加(load"xyp_lib")
  7. 2.在每个程序内增加(load"xyp_lib")
  8. 3.在command下,输入(load"xyp_lib")
  9. 4.在菜单.mnl中增加(load"xyp_lib")
  10. 5.将xyp_lib.vlx文件直接拽到cad屏幕
  11. [COLOR=red] ★通用函数下载地址:[/COLOR]
  12. [url]http://www.xdcad.net/forum/attachment.php?s=&postid=1606661[/url]
  13. [url]http://www.mjtd.com/bbs/dispbbs.asp?boardID=3&ID=37554&page=1[/url]|;

  14. ;_midP相当于mpt:两点之中点
  15. (defun c:blx ()
  16.   (cmdla0)
  17.   (setq        osm (getvar "osmode")
  18.         NO1 (ureal 7 "" "\波长(数值)" NO1)
  19.         NO2 (ureal 7 "" "\波峰(数值)" NO2)
  20.         NOa (/ NO1 2.0)
  21.   )
  22.   (setq ss1 (ssget "X"))
  23.   (MKLA "波浪线" 100)
  24.   (setq pt1 (getpoint "\n起点<退出> : "))
  25.   (while (setq ptn (getpoint pt1 "\n终点<退出> : "))
  26.     (grdraw pt1 ptn 1 3)
  27.     (setq ang (angle pt1 ptn))
  28.     (setq pt3 (polar pt1 ang NOa)
  29.           pt5 (polar pt3 ang NOa)
  30.           pt2 (polar (_midP pt1 pt3) (- ang (/ pi 2)) NO2)
  31.           pt4 (polar (_midP pt3 pt5) (+ ang (/ pi 2)) NO2)
  32.     )
  33.     (setq nn (fix (abs (/ (distance pt1 ptn) (* NOa 2))))
  34.           n  0
  35.     )
  36.     (setq ss (ssadd))
  37.     (repeat nn
  38.       (SETVaR "osmode" 0)
  39.       (command "_arc" pt1 pt2 pt3)
  40.       (setq ss (ssadd (entlast) ss))
  41.       (command "copy" (entlast) "" pt1 pt5)
  42.       (setq ss (ssadd (entlast) ss))
  43.       (command "_arc" pt3 pt4 pt5)
  44.       (setq ss (ssadd (entlast) ss))
  45.       (command "copy" (entlast) "" pt1 pt5)
  46.       (setq ss (ssadd (entlast) ss))
  47.       (setq pt1 pt5)
  48.       (setq pt3        (polar pt1 ang NOa)
  49.             pt5        (polar pt3 ang NOa)
  50.             pt2        (polar (_midP pt1 pt3) (- ang (/ pi 2)) NO2)
  51.             pt4        (polar (_midP pt3 pt5) (+ ang (/ pi 2)) NO2)
  52.       )
  53.     )
  54.     (command "pedit" (entlast) "y" "j" ss "" "")
  55.     (command "erase" ss "")
  56.     (setq pt1 pt5)
  57.     (SETVAR "osmode" osm)
  58.   )
  59.   (setq ss2 (ssget "X"))
  60.   (setq ssa (ssdiff ss2 ss1))
  61.   (command "pedit" (entlast) "j" ssa "" "")
  62.   (cmdla1)
  63. )
  64. [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-18 02:44 , Processed in 0.486231 second(s), 60 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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