首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Autolisp实体数据检索

Autolisp实体数据检索
EN

Stack Overflow用户
提问于 2016-04-25 23:07:10
回答 2查看 1.6K关注 0票数 0

我正在试用autocad,我想在矩形和直线之间建立一条“高速公路”。我需要矩形的2分。有什么想法吗?

代码语言:javascript
复制
(setq en(car(entsel"\Get rectangle : ")))
 (entget en)

我的全部代码

代码语言:javascript
复制
    (defun temaLisp(/  )
  ;HIGHWAY BUILDER
  ;My project is a highwaybulder
  ;How does it work?
  ;Select a rectangle and draw from there to a distance the highway where it meets a stop(Line)
      (princ "TemaLisp ")
   ;get rectangle (prompt "\nSelect the ends of a station")
  (setq en(car(entsel"\Get rectangle : ")))
  (entget en)
  ;get the stop (Line)


     (setq line2 (car (entsel "\nSelect the second line: ")))
            (setq p3 (cdr (assoc 10 (entget line2))))
            (setq p4 (cdr (assoc 11 (entget line2))))

  ;of the highway &optional (size 50)
  (setq mid1 (midpt pt3 pt4)) ; midpoint for dotted line

  ; Draw the lines
  (command "line" mid1 mid2)
)       
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-19 00:07:54

在AutoCAD中,矩形(使用AutoCAD RECTANG命令创建)使用关闭的2D轻量级polyline (LWPOLYLINE)实体表示。

LWPOLYLINE实体包含以下DXF数据:

代码语言:javascript
复制
(
    (-1 . <Entity name: 7ffff706880>)  ;; Pointer to self
    (0 . "LWPOLYLINE")                 ;; Entity Type
    (330 . <Entity name: 7ffff7039f0>) ;; Point to parent
    (5 . "FFF")                        ;; Handle
    (100 . "AcDbEntity")               ;; Class
    (67 . 0)                           ;; Tilemode
    (410 . "Model")                    ;; Layout
    (8 . "0")                          ;; Layer
    (100 . "AcDbPolyline")             ;; Subclass
    (90 . 4)                           ;; Vertices
    (70 . 1)                           ;; Bitwise flag (1=Closed)
    (43 . 0.0)                         ;; Constant width
    (38 . 0.0)                         ;; Elevation
    (39 . 0.0)                         ;; Thickness
    (10 18.9133 17.6315)               ;; Vertex coordinate (OCS)

    < ... additional vertex data ... >

    (10 18.9133 12.7863)               ;; Vertex coordinate (OCS)
    (40 . 0.0)                         ;; Segment starting width
    (41 . 0.0)                         ;; Segment ending width
    (42 . 0.0)                         ;; Segment bulge
    (91 . 0)                           ;; Vertex identifier
    (210 0.0 0.0 1.0)                  ;; Extrusion (normal) vector
)

这里,每个顶点的2D OCS坐标使用DXF组10项存储在DXF数据中。

有许多方法可以获得DXF数据中DXF组多次出现的值列表(因此获得了polyline的顶点列表)。

由于assoc AutoLISP函数返回关联列表中键的第一次出现,所以我将这些函数称为massoc函数(即multiple assoc)。

1.前额

代码语言:javascript
复制
(defun massoc1 ( key lst / rtn )
    (foreach x lst
        (if (= key (car x))
            (setq rtn (cons (cdr x) rtn))
        )
    )
    (reverse rtn)
)

第一个示例简单地迭代所提供的关联列表中的每一项,并且如果该项的c内容ad究竟register (car)等于所需的key,则该函数返回的列表中添加与键(或cE 220内容)相关联的值(或c<代码>E 220/代码>ddE 222请求E 123>re 224egister-d25)。

这个列表在返回之前被反转,因为列表是反向构造的,每个项目都被推到列表的前面--这比使用append/list组合按顺序构建列表要高效得多。

2.附录/地图

代码语言:javascript
复制
(defun massoc2 ( key lst )
    (apply 'append
        (mapcar
            (function
                (lambda ( x ) (if (= key (car x)) (list (cdr x))))
            )
            lst
        )
    )
)

但是,迭代列表的另一种方法是,因为mapcar返回为每个列表项提供的函数的计算结果,如果if语句将导致“`mapcar”返回的列表中出现nil,则这些项不符合标准。

这些nil值是通过利用nil的对偶性和AutoLISP中的空列表()来删除的,方法是应用append函数来追加mapcar返回的列表中的所有子列表&零值。

3. vl-删除-如果-如果-不

代码语言:javascript
复制
(defun massoc3 ( key lst )
    (mapcar 'cdr
        (vl-remove-if-not
            (function (lambda ( x ) (= key (car x))))
            lst
        )
    )
)

它在tin上说:如果提供给vl-remove-if-not函数的谓词函数返回nil (vl-remove-if也可以与一个否定的谓词函数一起使用),条目就会被移除--因此删除了第一个元素不等于所需键的项。

然后使用mapcar函数返回与vl-remove-if-not返回的每个关联列表项相关联的值。

4.时间/助理/成员

代码语言:javascript
复制
(defun massoc4 ( key lst / itm rtn )
    (while (setq itm (assoc key lst))
        (setq rtn (cons (cdr itm) rtn) lst (cdr (member itm lst)))
    )
    (reverse rtn)
)

该方法比前面的方法效率要高得多,因为assocmember函数用于直接跳转到提供列表中的目标项,而不是迭代和测试每个项。

assoc返回关联列表中键的第一次出现,member返回列表的尾部,第一项等于提供的参数。

通过这种方式,assoc函数检索目标项,member函数返回从该项开始的列表的其余部分,并且通过使用cdr重复地重新定义列表以包含该目标项后面的所有项。

5.递归/ assoc /成员

代码语言:javascript
复制
(defun massoc5 ( key lst / itm )
    (if (setq itm (assoc key lst))
        (cons (cdr itm) (massoc5 key (cdr (member itm lst))))
    )
)

但是,在这种情况下,上面的变化不是为找到的每一项重新定义列表,而是将列表的其余部分作为函数的递归计算的参数传递。

6. acet-list-m-assoc (快递工具)

代码语言:javascript
复制
(defun massoc6 ( key lst )
    (mapcar 'cdr (acet-list-m-assoc key lst))
)

该函数的这个版本使用了定义为快捷工具库的一部分的acet-list-m-assoc函数,该库是对AutoCAD的完整版本的可选添加。

但这是欺骗!:)

7.基本递归

代码语言:javascript
复制
(defun massoc7 ( key lst )
    (if lst
        (if (= key (caar lst))
            (cons (cdar lst) (massoc7 key (cdr lst)))
            (massoc7 key (cdr lst))
        )
    )
)

最后一个示例本质上是上面演示的foreach示例的递归版本。函数只查看提供的列表中的第一项,如果第一个元素与key参数匹配,则它是递归调用返回的列表的consd和列表的其余部分,否则列表的其余部分将传递给递归调用,而不添加返回项。

示例

既然我们已经讨论了定义这样一个函数的各种方法,该如何使用这个函数呢?

上面的每个函数都接受两个参数:'key‘和一个关联列表。这在语法上与标准的AutoLISP assoc函数相同。

这样的函数可以使用语法获得DXF关联列表中与DXF组10关联的所有值:

代码语言:javascript
复制
(massoc 10 <dxf-data>)

例如(在Visual控制台):

代码语言:javascript
复制
;; Obtain a LWPOLYLINE entity
_$ (setq ent (car (entsel)))
<Entity name: 7ffff706880>

;; Retrieve the DXF data
_$ (setq dxf (entget ent))
((-1 . <Entity name: 7ffff706880>) (0 . "LWPOLYLINE") ... (91 . 0) (210 0.0 0.0 1.0))

;; Obtain the values associated with all DXF group 10 entries
_$ (massoc 10 dxf)
((13.0161 12.4807) (25.727 12.4807) (25.727 18.6426) (13.0161 18.6426))

这可以通过以下方式在示例程序中使用:

代码语言:javascript
复制
(defun c:test ( / dxf ent )
    (if
        (and
            (setq ent (car (entsel "\nSelect rectangle: ")))
            (setq dxf (entget ent))
            (= "LWPOLYLINE" (cdr (assoc 0 dxf)))
        )
        (print (massoc 10 dxf))
    )
    (princ)
)

(defun massoc ( key lst / rtn )
    (foreach x lst
        (if (= key (car x))
            (setq rtn (cons (cdr x) rtn))
        )
    )
    (reverse rtn)
)

业绩考虑

就性能而言,相同函数的上述变化并不相等--对提供的列表中的每一项进行迭代的变化都不如直接跳到目标项(使用内置函数(如assocmember ))的效率低。

作为快速比较,请考虑以下基准结果:

代码语言:javascript
复制
;;;Benchmarking ................Elapsed milliseconds / relative speed for 32768 iteration(s):
;;;
;;;    (MASSOC5 2 L).....1482 / 1.25 <fastest> ;; recursive/assoc/member
;;;    (MASSOC4 2 L).....1482 / 1.25           ;; while/assoc/member
;;;    (MASSOC6 2 L).....1498 / 1.24           ;; acet-list-m-assoc
;;;    (MASSOC3 2 L).....1638 / 1.13           ;; vl-remove-if-not
;;;    (MASSOC7 2 L).....1747 / 1.06           ;; basic recursion
;;;    (MASSOC1 2 L).....1748 / 1.06           ;; foreach
;;;    (MASSOC2 2 L).....1856 / 1 <slowest>    ;; append/mapcar

正如预期的那样,assoc/member函数被证明是最快的,而Express Tools函数则是第二个。

票数 5
EN

Stack Overflow用户

发布于 2016-04-26 07:40:34

代码语言:javascript
复制
(setq rectangle (entget en))

首先,你可以通过:

代码语言:javascript
复制
(setq P1(assoc 10 rectangle ))

然后删除P1之前的所有内容

代码语言:javascript
复制
(setq rectangle (cdr (member P1 rectangle)))

得到下一个观点

代码语言:javascript
复制
(setq P2(assoc 10 rectangle ))

你可以用while循环它

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36852628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档