实体相交和someth
您好,我想寻求一些帮助,如果有一种方法可以更快地实现与下面的LISP相同的结果,我需要的是在圆柱体对象停止与基础对象相交时获得其尖端的Z坐标(可以有任何形式)。它将精确到用户选择的分辨率(res)。我已经减少了代码,把它贴在这里,但基本上这需要在几个X,Y坐标重复。获取坐标很容易,但不确定是否有更好的方法获取交点。我也不需要显示圆柱体,正如我所说,我只需要坐标。一、 e:我还试图生成两个实体的STL,并获得一个浊点来寻找交点,但似乎很复杂
谢谢你的帮助。
(defun c:test1 ( / )
(vl-load-com)
(setq thisdrawing (vla-get-activedocument (vlax-get-acad-object)))
; This makes the Undo command erase only what's drawn in this lisp
(vla-StartUndoMark thisdrawing)
; This makes the Undo command erase only what's drawn in this lisp
(setq cmdsave (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq objsnap (getvar "osmode"))
(setvar "osmode" 0)
(setq res 0.001);Final resolution to test for interference, will be user selected
(setq init_res 1.0);Initial resolution to speed up movement on z-axis
(command "cylinder" "0,0,0" 6 40)
(setq cyl (entlast))
(setq pt2 (list 0 0 6))
(command "move" cyl "" "0,0,0" pt2)
(command "sphere" "0,0,0" 6)
(setq sph (entlast))
(command "move" sph "" "0,0,0" pt2)
(command "union" sph cyl "")
(setq tool (entlast))
(command "sphere" "0,10,0" 25) ;This could be any solid of any shape
(setq 3dent (entlast))
(vinter)
(setq temp_res init_res)
(setq pt1 (list 0 0 0))
(setq pt2 (list 0 0 ptz))
(command "move" tool "" pt1 pt2)
(setq pt1 pt2)(vinter)
(while (and (= interferes "f") (>= temp_res res))
(setq pt2 (list 0 0 ptz))
(command "move" tool "" pt1 pt2)
(vinter)
(if (= interferes "t")
(progn
(command "move" tool "" pt2 pt1)
(setq temp_res (* temp_res 0.1))
(vinter)
(setq ptz (- (caddr pt1) temp_res))
) ;_ end of progn
(progn
(setq pt1 pt2)
(setq ptz (- ptz temp_res))
) ;_ end of progn
) ;_ end of if
) ;_ end of while
(setvar "cmdecho" cmdsave)
(setvar "osmode" objsnap)
(vla-EndUndoMark thisdrawing)
(princ)
) ;_ end of defun
;This will return "t" if the solids intersect
(defun vinter (/ rest key vlaobject2)
(setq key t)
(setq
rest (vla-CheckInterference
(vlax-ename->vla-object tool)
(vlax-ename->vla-object 3dent)
key
) ;_ end of vla-CheckInterference
) ;_ end of setq
; Curiously, if on last line I put 3dent before tool, intesect fails when it tests a tool against
; a flat box. The same happens if done by hand in AutoCAD, try it.
(if rest
(progn
(setq interferes "t")
(setq vlaobject2 (vlax-ename->vla-object (entlast)))
(vla-GetBoundingBox vlaobject2 'minb 'maxb)
(setq maxb (vlax-safearray->list maxb))
(setq ptz (caddr maxb))
) ;_ end of progn
(setq interferes "f")
) ;_ end of if
(if (= interferes "t")
(entdel (entlast))
) ;_ end of if
) ;_ end of defun
我不确定geomcal。arx,但我只是认为ILP接近您的解决方案,但它可能是错误的,只是我的0.02 嗨,谢谢你的回答。
作为一名“自学”的LISP用户/程序员,我在AutoCAD帮助文件中快速搜索了“cal”函数,但找不到3dsolids的任何内容。我确实发现了一些有用的东西,以防我使用“浊点”方法。出于同样的原因,不是一个程序员本身,我不确定ILP首字母缩略词代表什么,你能详细解释一下吗?
再次感谢你的帮助
谢天谢地,我有足够的时间和愿望为自己学习,只需要朝着正确的方向努力 ILP的首字母缩写代表(线和平面的相交)。。。您可以使用(cal“ilp(p1、p2、t1、t2、t3)”,在此之前,您必须为较新的CAD版本加载“geomcal.arx”或“geomcal.crx”,但您也有此函数的lisp版本。。。它可以在页面底部的这个链接上找到。。。
虽然我不确定它如何帮助你解决你的问题。。。
http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/m-p/5243795#M325627
M、 R。 谢谢hanhphuc和Marko!
出于某种原因,我认为ILP是一种编程技术
如果我使用生成点云选项,我相信geomcal中的“ilp”选项可以帮助我,但这将涉及导出到STL格式、读取创建的文件以生成巨大的顶点列表、查找直线和STL平面之间的交点等漫长过程。。。我相信这比我上面发布的方法需要更长的时间来处理,所以在深入研究之前,我会继续寻找其他选择 到目前为止,这是我能使其运行的最快速度,在这种情况下,沿着x轴移动,如果您熟悉cnc,您将了解我试图实现的目标:
*编辑时,我添加了一个非常基本的计时器来跟踪性能,它在程序退出时将秒数打印到命令行
(defun c:test2 (/)
(vl-load-com)
(setq stopwatch (float (getvar "millisecs")))
(setq thisdrawing (vla-get-activedocument (vlax-get-acad-object)))
; This makes the Undo command erase only what's drawn in this lisp
(vla-StartUndoMark thisdrawing)
; This makes the Undo command erase only what's drawn in this lisp
(setq cmdsave (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq objsnap (getvar "osmode"))
(setvar "osmode" 0)
(setq res 0.005) ; 0.005 lasts about 6 secs, 0.001 7 secs and 0.0001 8 secs, at least in my machine
;Resolution for each move along roughing path or each height test in finishing
(setq init_res 1.0) ;starting with 5 instead of 1 makes almost no difference
;Initial resolution to speed up movement along path or height
(command "_.cylinder" "0,0,0" 6 40)
(setq cyl (entlast))
(setq pt2 (list 0 0 6))
(command "_.move" cyl "" "0,0,0" pt2)
(command "_.sphere" "0,0,0" 6)
(setq sph (entlast))
(command "_.move" sph "" "0,0,0" pt2)
(command "_.union" sph cyl "")
(setq tool (entlast))
;;;(setq mylist (append mylist (list tool)))
(setq move_dist 0)
(command "_.sphere" "24,24,0" 24)
;This could be any solid of any shape, will be user selected
(setq 3dent (entlast))
(repeat 48
(setq pt2 (list 0 0 0))
(vinter)
(if (= interferes "t")
(progn
(setq temp_res init_res)
(setq pt1 (list 0 0 0))
(setq pt2 (list 0 0 ptz))
(command "_.move" tool "" pt1 pt2)
(setq pt1 pt2)
(vinter)
(while (and (= interferes "f") (>= temp_res res))
(setq pt2 (list 0 0 ptz))
(command "_.move" tool "" pt1 pt2)
(vinter)
(if (= interferes "t")
(progn
(command "_.move" tool "" pt2 pt1)
(setq temp_res (* temp_res 0.1)) ;using 0.1 is faster than 0.5 by about 20%
(vinter)
(setq ptz (- (caddr pt1) temp_res))
) ;_ end of progn
(progn
(setq pt1 pt2)
(setq ptz (- ptz temp_res))
) ;_ end of progn
) ;_ end of if
) ;_ end of while
) ;_ end of progn
) ;_ end of if
(command "_.move" tool "" "0,0,0" "1,0,0")
(command "_.move" tool "" pt2 (list (car pt2) (cadr pt2) 0.0))
) ;_ end of repeat
(setvar "cmdecho" cmdsave)
(setvar "osmode" objsnap)
(vla-EndUndoMark thisdrawing)
(princ)
(setq stopwatch (/ (- (float (getvar "millisecs")) stopwatch) 1000))
) ;_ end of defun
;This will return "t" if the solids intersect
(defun vinter (/ rest key vlaobject2)
(setq key t)
(setq
rest (vla-CheckInterference (vlax-ename->vla-object tool) (vlax-ename->vla-object 3dent) key)
) ;_ end of setq
; Curiously, if on last line I put 3dent before tool, intesect fails when it tests a tool
; against a flat box. The same happens if done by hand in AutoCAD, try it.
(if rest
(progn
(setq interferes "t")
(setq vlaobject2 (vlax-ename->vla-object (entlast)))
(vla-GetBoundingBox vlaobject2 'minb 'maxb)
(setq maxb (vlax-safearray->list maxb))
(setq ptz (caddr maxb))
) ;_ end of progn
(setq interferes "f")
) ;_ end of if
(if (= interferes "t")
(entdel (entlast))
) ;_ end of if
) ;_ end of defun
很明显,我没有看到:
用vla取代了命令调用,时间减少了20%!!
例子:
(vla-move (vlax-ename->vla-object tool) (vlax-3d-point pt1)(vlax-3d-point pt2))而不是:
(command "move" tool "" pt1 pt2)和
(vla-addline mspace (vlax-3d-point pt1)(vlax-3d-point pt2))而不是:
(command "_line" pt1 pt2 "")
谢谢大家的帮助,希望这能帮助其他想要改善日常生活的人
欢迎提出任何其他建议 感谢Marko的分享,arx的ILP之前已经过测试,测试速度最慢。
自定义LISP的ILP很好
谢谢,韩。。。对于类似ILP的简单CAL函数,不需要检查交点是否在三角形t1、t2、t3。。。这就是ILP真正应该如何运作。。。顺便说一句,我不知道LISP版本是否更快,但它可能有一些用处,因为不需要检查共面性和其他关系。。。
(defun _ilpp ( p1 p2 t1 t2 t3 / v^v unit _ilp nor o )
(defun v^v ( u v )
(list
(- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
(- (* (carv) (caddr u)) (* (caru) (caddr v)))
(- (* (caru) (cadrv)) (* (carv) (cadru)))
)
)
(defun unit ( v )
(mapcar '(lambda ( x ) (/ x (distance '(0.0 0.0 0.0) v))) v)
)
(defun _ilp ( p1 p2 o nor / p1p p2p op tp pp p )
(if (not (equal (v^v nor (unit (mapcar '- p2 p1))) '(0.0 0.0 0.0) 1e-7))
(progn
(setq p1p (trans p1 0 (v^v nor (unit (mapcar '- p2 p1))))
p2p (trans p2 0 (v^v nor (unit (mapcar '- p2 p1))))
op(trans o 0 (v^v nor (unit (mapcar '- p2 p1))))
op(list (car op) (cadr op) (caddr p1p))
tp(polar op (+ (* 0.5 pi) (angle '(0.0 0.0 0.0) (trans nor 0 (v^v nor (unit (mapcar '- p2 p1)))))) 1.0)
)
(if (inters p1p p2p op tp nil)
(progn
(setq p (trans (inters p1p p2p op tp nil) (v^v nor (unit (mapcar '- p2 p1))) 0))
p
)
nil
)
)
(progn
(setq pp (list (car (trans p1 0 nor)) (cadr (trans p1 0 nor)) (caddr (trans o 0 nor))))
(setq p (trans pp nor 0))
p
)
)
)
(setq nor (unit (v^v (mapcar '- t3 t1) (mapcar '- t2 t1))))
(setq o t1)
(if (_ilp p1 p2 o nor)
(_ilp p1 p2 o nor)
nil
)
)
P、 若你们想得到“获得直线和三角形的交点”的代码,就像引用的那个样——若直线穿过三角形,你们可以在这里找到代码。。。
http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/to-get-intersection-between-a-line-and-a-3dface/m-p/5338005/highlight/true#M326785
M、 R。 再次感谢各位!
使用visual lisp方法与autocad命令相比,该例程现在只需2分钟即可运行,而不是12分钟!!我不敢相信这会有多大的不同:哦
我将尝试使用line-plane接口例程测试一种方法,看看它是否适用于我的目的
页:
[1]