Lisp自动绘制rec
大家好,我在一家生产建筑模型的公司工作。我专门从事绘图领域的工作,在那里我使用AutoCad绘制模型的各个部分。
在我们的工作中,我们必须不断地绘制“地图”给那些把这些碎片放在一起形成模型的人
我已经开发了几个lisp例程来简化我的工作,现在我正在尝试简化(很多)这些地图的制作。
所以我现在需要的是:
1) 一种对点列表中的点进行排序的方法,以便它们相对于基点从最近到最远按顺序排列
2) 积分的数量总是不同的,因此,我如何连续存储这些积分?(如列表中有10个点,则点1为最近点,点10为最远点)
3) 在对点进行排序之前(或之后),删除彼此距离过近的点(例如,如果点2距离点3 0.02个单位,则忽略点3)
所有这一切都是为了能够自动检测窗户和门在墙中间的位置,并在地图上标出它们,而不需要手动找到它们
这是我到目前为止的代码(它要求模型中使用的材质的E压力、地图中墙的编号以及将墙的编号放置在地图中的文本高度)
P、 如果是的话,我是一个非常业余的程序员
(defun c:md ()
(setq layercorrente (getvar 'clayer))
(defun dtr (a) (* Pi (/ a 180.0)))
(defun rtd (b) (* b (/ 180.0 Pi)))
(setvar "OSNAPCOORD" 1)
(setq esp (getdist "\nDigite a espessura da parede <enter = ultima espessura>: "))
(if (= esp nil) (setq esp esptemp))
(setq esptemp esp)
(setq altura_texto (getdist "\nInsira a altura do texto <enter = ultima altura>:"))
(cond
((and (= altura_texto nil) (= altura_textotemp nil)) (setq altura_texto esp)
)
((and (= altura_texto nil) (/= altura_textotemp nil)) (setq altura_texto altura_textotemp)
)
)
(setq numero (getint "Indique o numero da próxima parede <enter = ultimo numero de parede>:"))
(cond
((and (= numero nil) (= numero_old nil))
(setq numero 1)
)
((and (= numero nil) (/= numero_old nil))
(setq numero numero_old)
)
)
(setq numero_old numero)
(setq texto (itoa numero))
(command "_-style" "loks" "txt" altura_texto "1" "" "" "" "")
(setq rotation 0)
(setq ponto1 (getpoint "\nInsira o primeiro ponto de inserção da parede levando em conta o sentido anti-horário:"))
(setq ponto2 (getpoint "\nInsira o segundo ponto de inserção:"))
(setq comprimento (distance ponto1 ponto2))
(setq ang1 (angle ponto1 ponto2))
(setq ang2 (rtd ang1))
(setq ang3 (+ ang2 90.0))
(if (>= ang3 360.0) (setq ang3 (- ang3 360)))
(setq ang4 (+ ang2 270.0))
(if (>= ang4 360.0) (setq ang4 (- ang4 360)))
(setq ponto3 (polar ponto2 (dtr ang3) esp))
(setq ponto4 (polar ponto1 (dtr ang3) esp))
(setq pontoref (polar ponto1 ang1 (/ comprimento 2)))
(cond
((<= 0 ang4 105) (setq pontotxt (polar pontoref (dtr ang4) (* 1.5 altura_texto)))
)
((and (< 105 ang4 255) (<= 0 numero 9)) (setq pontotxt (polar pontoref (dtr ang4) (* 2 altura_texto)))
)
((and (< 105 ang4 255) (<= 10 numero 99)) (setq pontotxt (polar pontoref (dtr ang4) (* 2.5 altura_texto)))
)
((and (< 105 ang4 255) (<= 100 numero)) (setq pontotxt (polar pontoref (dtr ang4) (* 3.4 altura_texto)))
)
((<= 255 ang4 300) (setq pontotxt (polar pontoref (dtr ang4) (* 2 altura_texto)))
)
((< 300 ang4 360) (setq pontotxt (polar pontoref (dtr ang4) (* 1.5 altura_texto)))
)
)
(defun c:mapadeparedes ()
(setvar 'clayer layercorrente)
(command "pline" ponto1 ponto2 ponto3 ponto4 "c")
(command "LAYER" "M" "-TEXTO_DECORADO" "C" "42" "" "")
(command "text" pontotxt rotation texto)
(setvar 'clayer layercorrente)
)
(c:mapadeparedes)
(while (/= ponto1 nil)
(setq ponto1 (getpoint "\nInsira o primeiro ponto de inserção da parede levando em conta o sentido anti-horário:"))
(cond
((/= ponto1 nil)
(setq ponto2 (getpoint "\nInsira o segundo ponto de inserção:"))
(setq comprimento (distance ponto1 ponto2))
(setq ang1 (angle ponto1 ponto2))
(setq ang2 (rtd ang1))
(setq ang3 (+ ang2 90.0))
(if (>= ang3 360.0) (setq ang3 (- ang3 360)))
(setq ang4 (+ ang2 270.0))
(if (>= ang4 360.0) (setq ang4 (- ang4 360)))
(setq ponto3 (polar ponto2 (dtr ang3) esp))
(setq ponto4 (polar ponto1 (dtr ang3) esp))
(setq pontoref (polar ponto1 ang1 (/ comprimento 2)))
(cond
((<= 0 ang4 105) (setq pontotxt (polar pontoref (dtr ang4) (* 1.5 altura_texto)))
)
((and (< 105 ang4 255) (<= 0 numero 9)) (setq pontotxt (polar pontoref (dtr ang4) (* 2 altura_texto)))
)
((and (< 105 ang4 255) (<= 10 numero 99)) (setq pontotxt (polar pontoref (dtr ang4) (* 2.5 altura_texto)))
)
((and (< 105 ang4 255) (<= 100 numero)) (setq pontotxt (polar pontoref (dtr ang4) (* 3.4 altura_texto)))
)
((<= 255 ang4 300) (setq pontotxt (polar pontoref (dtr ang4) (* 2 altura_texto)))
)
((< 300 ang4 360) (setq pontotxt (polar pontoref (dtr ang4) (* 1.5 altura_texto)))
)
)
(setq numero (+ numero 1))
(setq texto (itoa numero))
(c:mapadeparedes)
)
)
)
(setq numero_old (+ numero 1))
)
(princ "\nDIGITE MD PARA DESENHAR O MAPA DE PAREDES DE DECORADO MAIS FACILMENTE.")
(princ) 步骤#3的解决方案(Lee Mac的LM:唯一模糊子函数)。
无论如何都进行了尝试(没有看他的代码),结果是:
(setq org '(0. 0. 0.)
pts '((9. 8. 0.) (7. 6. 0.) (1. 2. 0.) (3. 4. 0.))
)
(vl-sort pts '(lambda (a b) (< (distance org a) (distance org b))))
不确定它会更快,因为尾部递归存储“v”,并且不会尝试访问vl remove if中点列表的car。
用直接递归做同样的事情——这是李证明的一个相当大的成就。 谢谢Tharwhat和Grrr u的帮助!
最后,我只使用了Tharwhat的解决方案,因为我通过替代方法达到了相同的目标,从而解决了其他问题。
然而,更多的知识永远不够,所以再次感谢=)
现在我的例程几乎完成了,我唯一真正需要的是一种更有效的方法来验证指定层是否包含在选择集中
现在我正在隔离指定的层,如果选择集为空,这意味着返回nil,否则为T,但它会消耗很多时间,因为这个过程会重复很多次
那么,有没有办法找到在选择集中是否至少有一个指定层的对象? 以下是最直接的方法:
; _$ (UQpL 0.01 '(1.0 1.1 2.0 2.01 2.2)) >> (1.0 1.1 2.0 2.2)
; _$ (UQpL 0.15 '(1.0 1.1 2.0 2.01 2.2)) >> (1.0 2.0 2.2)
(defun UQpL ( fuzz pL )
((lambda (f) (f pL fuzz))
(lambda (pL fuzz / v)
(if pL
(cons
(setq v (car pL))
(f ((lambda (pL) (vl-remove-if (function (lambda (x) (equal v x fuzz))) pL)) (cdr pL)) fuzz)
)
)
)
)
); defun UQpL
或者,如果您已经选择了项目并将其转换为搪瓷列表:
(ssget '((8 . "yourlayername")))
谢谢ronjop!
对于特定情况,第一个代码就足够了,但后一个代码也非常有用!)
我会把话题留着,以防再次出现任何问题,但我认为现在我已经准备好了!
(另外,我之前已经发布了我的代码,如果有人能分析它来验证我是否“编码正确”,比如……如果有更有效的方法来做我已经在做的事情,代码会有一点扩展,但如果有人有一点空闲时间,我将不胜感激) 大家好,在尝试继续改进我的lisp例程时,我想知道是否有一种方法可以确定要找到的对象的模式,然后在选择集中量化它们。。。喜欢我确定我想找到两条垂直线,在X轴上彼此相距0.1和0.1,然后我选择一堆对象,并希望代码返回给我在这些图案中找到的对象数量,我在前面的选择中指定了这些图案 P、 我想通过选择集而不是数字参数来指定图案 这不可能? 发布示例选择集的图形。。我不知道你在做什么。 嗨,ronjonp,谢谢你的回复!
http://ap.imagensbrasil.org/image/nq2YIG
在这张图中,你可以看到一个有窗口的蓝图片段
我开发了一个例程,可以自动识别图形中的窗口并用矩形标记它们,现在我想要的是指定一个选择模式,就像图像中标记的两个矩形一样,并在一个选区集中跟踪它们,以计算它们出现的次数
如果我能做到这一点,我不仅能确定窗口在哪里,还能确定窗口有多少叶子(在这种情况下,它会检测到窗口内的2个选择模式,因此它会知道窗口有3个叶子)
我是巴西人,如果我不太全面,请原谅我
页:
[1]
2