找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 475|回复: 6

[他山之石] Samples of power sorting in AutoLisp

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2018-8-22 09:26:17 | 显示全部楼层 |阅读模式

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

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

×
  1. ;;; File       : lispsort.lsp
  2. ;;; Purpose    : Samples of power sorting in AutoLisp
  3. ;;;
  4. ;;; Author     : T.J. DiTullio   Herman Goldner Co. Inc.
  5. ;;;              (70214,3131)
  6. ;;;
  7. ;;; Date       : 3-23-95 (complied from earlier files 1992)
  8. ;;;
  9. ;;; Desciption : Here are four sorting functions that implement
  10. ;;;              sorting with pointers (Yes in AutoLisp).
  11. ;;;              There are two shell sorts and two bubble sorts
  12. ;;;              One of each for lists and one for list of lists
  13. ;;;
  14. ;;;              After I developed these functions, I speed tested
  15. ;;;              the shells against the bubbles. Since then I have not
  16. ;;;              used the bubble sorts.
  17. ;;;
  18. ;;;              All four functions use an integer list (ptr_lst) as
  19. ;;;              pointers to the list to be sorted. One problem with
  20. ;;;              sorting in AutoLisp is that the list to be sorted must
  21. ;;;              be reconstructed each time a pair of items are swapped
  22. ;;;              If the list (or list of lists) is very large, it can
  23. ;;;              slow down the sort. By using a pointer list of type
  24. ;;;              integer, this reconstruction will be much faster.
  25. ;;;
  26. ;;;              At the start of each sort function, an integer list
  27. ;;;              (ptr_lst) is constructed starting at 0 and ending at
  28. ;;;              the number of items in list to be sorted (length lst).
  29. ;;;              As items in the list to be sorted are compared, the
  30. ;;;              pointer list is used to reference the list to be sorted.
  31. ;;;              [ something like (nth (nth index ptr_lst) lst) ]
  32. ;;;              [ meaning - The value of the list to be sorted is still
  33. ;;;                          in its original location. Used the integer
  34. ;;;                          (ptr_lst) value to determine where it is.
  35. ;;;              ]
  36. ;;;              Since the pointer list starts at 0, I used value of -1
  37. ;;;              for the 1st (subst) call to avoid have duplicate values in
  38. ;;;              the pointer list that would both be updated on the 2nd
  39. ;;;              (subst) call. Then after the 2nd (subst) call, a 3rd call
  40. ;;;              is made to replace the -1 value with the correct value.
  41. ;;;                  (setq t1 1st_item) - save 1st
  42. ;;;                  (setq t2 2nd_item) - save 2nd
  43. ;;;                  (subst -1 t1)      - change t1 to -1
  44. ;;;                  (subst t1 t2)      - change t2 to t1
  45. ;;;                  (subst t2 -1)      - change -1 to t2
  46. ;;;                                     - t1 and t2 are >= 0  always
  47. ;;;
  48. ;;;              As items are swapped around, only the pointer list is
  49. ;;;              modified. After the sorting is completed, the list to
  50. ;;;              be sorted to rebuilt using the pointer list for the
  51. ;;;              sorted location.
  52. ;;;
  53. ;;;              This may seem like a lot of work to do some sorting. But
  54. ;;;              the list of list that I sort get very large. (I use list
  55. ;;;              of lists like an array of structures for anyone who knows
  56. ;;;              the C language)
  57. ;;;
  58. ;;;              Here is an example for a list of lists I might sort:
  59. ;;;              ( ( "string" integer real integer real real "string"
  60. ;;;                  "string" real integer "string" real
  61. ;;;                )
  62. ;;;                ( "string" integer real integer real real "string"
  63. ;;;                  "string" real integer "string" real
  64. ;;;                )
  65. ;;;                etc ...
  66. ;;;              )
  67. ;;;
  68. ;;;    lisp call   -> (setq mylist (l_ssort mylist 3))
  69. ;;;    lisp retn   -> sorted list
  70. ;;;    description -> sort mylist bases on the 4th item (an integer)
  71. ;;;
  72. ;;;
  73. ;;;              One thing I noticed when I wrote these sorts was that
  74. ;;;              a shell sort is unable to sort completely if there are
  75. ;;;              duplicate values. I could not find anything in writing
  76. ;;;              to back this up. So I modified the algorithm to continue
  77. ;;;              looping while the partition size is one until no swaps
  78. ;;;              occurred.
  79. ;;;
  80. ;;;              Sorry there are not a lot of comments!
  81. ;;;
  82. ;;;              If you program in AutoLisp and are unfamiliar with these
  83. ;;;              sorting methods, try looking at another language like
  84. ;;;              Basic or C.
  85. ;;;
  86. ;;;              Any comments or questions can be directed to me.
  87. ;;;
  88. ;;;
  89. ;;;  THIS CODE IS THE PROPERTY OF T.J. DITULLIO AND THE HERMAN GOLDNER CO INC
  90. ;;;  PERMISSION IS GRANTED TO USE, COPY, MODIFY, AND DISTRIBUTE WITHOUT FEE
  91. ;;;  PROVIDED THAT THIS NOTICE IS DISTRIBUTED.
  92. ;;;


  93. ;;;* * * * * * * * * * * * * SORT FUNCTIONS  * * * * * * * * * * * * * * *
  94. ;;;
  95. ;;; l_bsort
  96. ;;;
  97. ;;; Modified Bubble Sort of List of Lists
  98. ;;; Parameters   llist ->  list of lists
  99. ;;;              key   ->  element in inner lists to sort by
  100. ;;;
  101. ;;; Returns  ->  Sorted list of lists
  102. ;;;

  103. (defun l_bsort ( llist key /   number_items  count     i
  104.                                unsorted      ptr_lst   j
  105.                                sorted_list   t1        t2
  106.                )
  107.   (if (and llist key)
  108.     (progn
  109.       (setq i 1
  110.             number_items (length llist)
  111.             unsorted T
  112.             ptr_lst nil          ;pointer list
  113.             count 0
  114.       )

  115.       (while (< count number_items)
  116.         (setq ptr_lst (append ptr_lst (list count))  ;built pointer list
  117.               count (1+ count)
  118.         )
  119.       ) ;while

  120.     ;-----------------------------------------------------------------------

  121.       (while (or unsorted (< i number_items))
  122.         (setq j 0
  123.               unsorted nil       ;assume list is sorted
  124.         )

  125.         ;loop thru and test (j) to (J+1) in pointer list

  126.         (while (< j (- number_items i))
  127.             (if (> (nth key (nth (nth j ptr_lst) llist))
  128.                    (nth key (nth
  129.                       (nth (1+ j) ptr_lst) llist)
  130.                    )
  131.                 )

  132.               ; swap items in pointer list
  133.               (setq t1 (nth j ptr_lst)
  134.                     t2 (nth (1+ j) ptr_lst)
  135.                     ptr_lst (subst t2 -1
  136.                               (subst t1 t2
  137.                                 (subst -1 t1 ptr_lst)
  138.                               )
  139.                             )
  140.                     unsorted T
  141.               ) ;setq
  142.             ) ;if

  143.           (setq j (1+ j))
  144.         ) ;while j

  145.         (setq i (1+ i))
  146.       ) ;while i

  147.     ;-----------------------------------------------------------------------
  148.       ;Build new list using sorted pointers

  149.       (setq count 0 sorted_list nil)
  150.       (while (< count number_items)
  151.         (setq sorted_list
  152.                 (append sorted_list        ;build updated list
  153.                   (list
  154.                     (nth
  155.                       (nth count ptr_lst)  ;pointer
  156.                       llist
  157.                     )
  158.                   )
  159.                 )
  160.               count (1+ count)
  161.         ) ;setq
  162.       ) ;while

  163.       sorted_list                          ;return sorted list
  164.     ) ;progn

  165.     ;else
  166.     nil
  167.   ) ;if

  168. ) ;defun

  169. ;;;=======================================================================
  170. ;;;
  171. ;;; l_ssort
  172. ;;;
  173. ;;; Modified Shell Sort of List of Lists
  174. ;;; Parameters   llist ->  list of lists
  175. ;;;              key   ->  element in inner lists to sort by
  176. ;;;
  177. ;;; Returns  ->  Sorted list of lists
  178. ;;;
  179. ;;; Note: This custom shell sort algorithm will handle multiple
  180. ;;;       occurrences of any items. The sort will continue looping
  181. ;;;       when partition size is 1 until no swaps occur.
  182. ;;;

  183. (defun l_ssort (llist key /
  184.                               number_items       partition_size
  185.                               number_partitions  first_index
  186.                               last_index         unsorted
  187.                               count              ptr_lst
  188.                               sorted_list        i         j
  189.                               t1                 t2
  190.                  )

  191.   (if (and llist key)
  192.     (progn
  193.       (setq number_items (length llist)
  194.             partition_size number_items
  195.             ptr_lst nil                  ;pointer list
  196.             count 0
  197.             unsorted T                   ;assume list is not sorted
  198.       )

  199.       (while (< count number_items)
  200.         (setq ptr_lst (append ptr_lst (list count)) ;built pointer list
  201.               count (1+ count)
  202.         )
  203.       ) ;while

  204.     ;------------------------------------------------------------------

  205.       (while unsorted

  206.         (setq partition_size (fix (/ (1+ partition_size) 2))
  207.               number_partitions (fix (/ number_items partition_size))
  208.         )

  209.         (if (= partition_size 1)
  210.           (setq unsorted nil)       ;assume list is sorted
  211.         )

  212.         (if (/= (rem number_items partition_size) 0)
  213.           (setq number_partitions (1+ number_partitions))
  214.         )
  215.         (setq first_index 0
  216.               i 1
  217.         )
  218.         (while (< i number_partitions)
  219.           (setq last_index (+ first_index partition_size))

  220.           (if (> last_index (- number_items partition_size))
  221.             (setq last_index (- number_items partition_size))
  222.           )

  223.           ;loop thru and test (j) to (j+offset) in pointer list

  224.           (setq j first_index)
  225.           (while (< j last_index)
  226.             (if (> (nth key (nth (nth j ptr_lst) llist))
  227.                    (nth key (nth
  228.                       (nth (+ j partition_size) ptr_lst) llist)
  229.                    )
  230.                 )

  231.               ; then swap items in pointer list
  232.               (setq t1 (nth j ptr_lst)
  233.                     t2 (nth (+ j partition_size) ptr_lst)
  234.                     ptr_lst (subst t2 -1
  235.                               (subst t1 t2
  236.                                 (subst -1 t1 ptr_lst)
  237.                               )
  238.                             )
  239.                     unsorted T
  240.               ) ;setq
  241.             ) ;if

  242.             (setq j (1+ j))

  243.           ) ;while j

  244.           (setq first_index (+ first_index partition_size)
  245.                 i (1+ i)
  246.           )

  247.         ) ;while i


  248.       ) ;while unsorted

  249.     ;------------------------------------------------------------------
  250.       ;Build new list using sorted pointers

  251.       (setq count 0 sorted_list nil)
  252.       (while (< count number_items)
  253.         (setq sorted_list
  254.                 (append sorted_list        ;build updated list
  255.                   (list
  256.                     (nth
  257.                       (nth count ptr_lst)  ;pointer
  258.                       llist
  259.                     )
  260.                   )
  261.                 )
  262.               count (1+ count)
  263.         ) ;setq
  264.       ) ;while

  265.       sorted_list                          ;return sorted list
  266.     ) ;progn

  267.     ;else
  268.     nil
  269.   ) ;if

  270. ) ;defun

  271. ;;;=======================================================================
  272. ;;;
  273. ;;; bsort
  274. ;;;
  275. ;;; Modified Bubble Sort of List of values
  276. ;;; Parameters   lst   ->  list of values
  277. ;;;
  278. ;;; Returns  ->  Sorted list of values
  279. ;;;


  280. (defun bsort ( lst  /   number_items  count     i
  281.                         unsorted      ptr_lst   j
  282.                         sorted_list   t1        t2
  283.                )
  284.   (if lst
  285.     (progn
  286.       (setq i 1
  287.             number_items (length lst)
  288.             unsorted T
  289.             ptr_lst nil          ;pointer list
  290.             count 0
  291.       )

  292.       (while (< count number_items)
  293.         (setq ptr_lst (append ptr_lst (list count))  ;built pointer list
  294.               count (1+ count)
  295.         )
  296.       ) ;while

  297.     ;-----------------------------------------------------------------------

  298.       (while (or unsorted (< i number_items))
  299.         (setq j 0
  300.               unsorted nil       ;assume list is sorted
  301.         )

  302.         ;loop thru and test (j) to (J+1) in pointer list

  303.         (while (< j (- number_items i))
  304.             (if (> (nth (nth j ptr_lst) lst)
  305.                    (nth (nth (1+ j) ptr_lst) lst)
  306.                 )

  307.               ; swap items in pointer list
  308.               (setq t1 (nth j ptr_lst)
  309.                     t2 (nth (1+ j) ptr_lst)
  310.                     ptr_lst (subst t2 -1
  311.                               (subst t1 t2
  312.                                 (subst -1 t1 ptr_lst)
  313.                               )
  314.                             )
  315.                     unsorted T
  316.               ) ;setq
  317.             ) ;if

  318.           (setq j (1+ j))
  319.         ) ;while j

  320.         (setq i (1+ i))
  321.       ) ;while i

  322.     ;-----------------------------------------------------------------------
  323.       ;Build new list using sorted pointers

  324.       (setq count 0 sorted_list nil)
  325.       (while (< count number_items)
  326.         (setq sorted_list
  327.                 (append sorted_list        ;build updated list
  328.                   (list
  329.                     (nth
  330.                       (nth count ptr_lst)  ;pointer
  331.                       lst
  332.                     )
  333.                   )
  334.                 )
  335.               count (1+ count)
  336.         ) ;setq
  337.       ) ;while

  338.       sorted_list                          ;return sorted list
  339.     ) ;progn

  340.     ;else
  341.     nil
  342.   ) ;if

  343. ) ;defun

  344. ;;;=======================================================================
  345. ;;;
  346. ;;; ssort
  347. ;;;
  348. ;;; Modified Shell Sort of List of Values
  349. ;;; Parameters   lst ->  list of values
  350. ;;;
  351. ;;; Returns  ->  Sorted list of values
  352. ;;;
  353. ;;; Note: This custom shell sort algorithm will handle multiple
  354. ;;;       occurrences of any items. The sort will continue looping
  355. ;;;       when partition size is 1 until no swaps occur.
  356. ;;;

  357. (defun ssort (lst /
  358.                        number_items       partition_size
  359.                        number_partitions  first_index
  360.                        last_index         unsorted
  361.                        count              ptr_lst
  362.                        sorted_list        i         j
  363.                        t1                 t2
  364.                  )

  365.   (if lst
  366.     (progn
  367.       (setq number_items (length lst)
  368.             partition_size number_items
  369.             ptr_lst nil                  ;pointer list
  370.             count 0
  371.             unsorted T                   ;assume list is not sorted
  372.       )

  373.       (while (< count number_items)
  374.         (setq ptr_lst (append ptr_lst (list count)) ;built pointer list
  375.               count (1+ count)
  376.         )
  377.       ) ;while

  378.     ;------------------------------------------------------------------

  379.       (while unsorted

  380.         (setq partition_size (fix (/ (1+ partition_size) 2))
  381.               number_partitions (fix (/ number_items partition_size))
  382.         )

  383.         (if (= partition_size 1)
  384.           (setq unsorted nil)       ;assume list is sorted
  385.         )

  386.         (if (/= (rem number_items partition_size) 0)
  387.           (setq number_partitions (1+ number_partitions))
  388.         )
  389.         (setq first_index 0
  390.               i 1
  391.         )
  392.         (while (< i number_partitions)
  393.           (setq last_index (+ first_index partition_size))

  394.           (if (> last_index (- number_items partition_size))
  395.             (setq last_index (- number_items partition_size))
  396.           )

  397.           ;loop thru and test (j) to (j+offset) in pointer list

  398.           (setq j first_index)
  399.           (while (< j last_index)
  400.             (if (> (nth (nth j ptr_lst) lst)
  401.                    (nth (nth (+ j partition_size) ptr_lst) lst)
  402.                 )

  403.               ; then swap items in pointer list
  404.               (setq t1 (nth j ptr_lst)
  405.                     t2 (nth (+ j partition_size) ptr_lst)
  406.                     ptr_lst (subst t2 -1
  407.                               (subst t1 t2
  408.                                 (subst -1 t1 ptr_lst)
  409.                               )
  410.                             )
  411.                     unsorted T
  412.               ) ;setq
  413.             ) ;if

  414.             (setq j (1+ j))

  415.           ) ;while j

  416.           (setq first_index (+ first_index partition_size)
  417.                 i (1+ i)
  418.           )

  419.         ) ;while i


  420.       ) ;while unsorted

  421.     ;------------------------------------------------------------------
  422.       ;Build new list using sorted pointers

  423.       (setq count 0 sorted_list nil)
  424.       (while (< count number_items)
  425.         (setq sorted_list
  426.                 (append sorted_list        ;build updated list
  427.                   (list
  428.                     (nth
  429.                       (nth count ptr_lst)  ;pointer
  430.                       lst
  431.                     )
  432.                   )
  433.                 )
  434.               count (1+ count)
  435.         ) ;setq
  436.       ) ;while

  437.       sorted_list                          ;return sorted list
  438.     ) ;progn

  439.     ;else
  440.     nil
  441.   ) ;if

  442. ) ;defun

  443. ;;;========================================================================


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

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2018-8-22 09:52:43 | 显示全部楼层
大师写个绘图顺序记录并恢复的函数吧..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 37个

财富等级: 招财进宝

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

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2018-8-22 17:28:18 | 显示全部楼层
q3_2006 发表于 2018-8-22 09:52
大师写个绘图顺序记录并恢复的函数吧..

Autocad 的绘图顺序记录在 AcDbBlockTableRecord 的扩展词典中,名字是 ACAD_SORTENTS

To draw the last entity in the space first (or "behind" the others), five entries in the sortents table must be made, as follows:



Entity ID  Draw Order Handle  
4E  4A  
4A  4B  
4B  4C  
4C  4D  
4D  4E  

The order of the entries (represented as a row in the preceding table) is irrelevant; draw order processing ends up sorting the entries by the draw order handle when performing the draw. In other words, in a DXF file, the table entries might appear in the following order, but the resultant draw order is identical:



Entity ID  Draw Order Handle  
4C  4D  
4B  4C  
4E  4A  
4D  4E  
4A  4B  

As another example, the last entity in the space is moved "under" the next-to-last entity in the space, but the rest of the entities are drawn in "natural" order. In that case, the sortents table would only need two entries, as follows:



Entity ID  Draw Order Handle  
4E  4D  
4D  4E  

Adding new entities to the block table record with an implicit draw order of "last" requires no new entry in the sortents table.

使用 ldata 记录实体句柄,然后使用 vla  进行恢复

点评

用这个吗..SetRelativeDrawOrder  详情 回复 发表于 2018-8-23 10:34
; IAcadSortentsTable: AutoCAD AcadSortentsTable 接口 ;特性值: ; Application (RO) = # ; Document (RO) = # ; Handle (RO) = "505552E" ; Ha**tensionDictionary (RO) = 0 ; ObjectID (RO) = -1  详情 回复 发表于 2018-8-23 08:20
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2018-8-23 08:20:19 | 显示全部楼层
st788796 发表于 2018-8-22 17:28
Autocad 的绘图顺序记录在 AcDbBlockTableRecord 的扩展词典中,名字是 ACAD_SORTENTS

To draw the la ...

; IAcadSortentsTable: AutoCAD AcadSortentsTable 接口
;特性值:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00d74d3c>
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0becabc0>
;   Handle (RO) = "505552E"
;   Ha**tensionDictionary (RO) = 0
;   ObjectID (RO) = -1388368
;   ObjectName (RO) = "AcDbSortentsTable"
;   OwnerID (RO) = -1498640
;支持的方法:
;   Block ()
;   Delete ()
;   GetExtensionDictionary ()
;   GetFullDrawOrder (2)
;   GetRelativeDrawOrder (2)
;   GetXData (3)
;   MoveAbove (2)
;   MoveBelow (2)
;   MoveToBottom (1)
;   MoveToTop (1)
;   SetRelativeDrawOrder (1)
;   SetXData (2)
;   SwapOrder (2)
怎么做..看不懂呢..大师指导下哈..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6468个

财富等级: 富甲天下

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

使用道具 举报

已领礼包: 2476个

财富等级: 金玉满堂

发表于 2018-8-23 10:34:45 | 显示全部楼层
st788796 发表于 2018-8-22 17:28
Autocad 的绘图顺序记录在 AcDbBlockTableRecord 的扩展词典中,名字是 ACAD_SORTENTS

To draw the la ...

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-26 01:35 , Processed in 0.390017 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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