乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 149|回复: 10

=>[挑战]<=嵌套矩形

[复制链接]

1

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
6
发表于 2013-5-12 19:40:59 | 显示全部楼层 |阅读模式
以为我们需要一个有趣的任务来做。考虑矩形内矩形的插图。我们假设每个矩形都是一个动态块,已根据需要拉伸。我们还将假设绘制所有矩形,以便它们不相交或相互接触。我希望用户能够选择所有矩形并获取嵌套括号,指示矩形之间的嵌套关系。顺序将从左到右和从上到下确定。让整数表示矩形的用户名。我想得到一个这样的列表
(1(2)(3(4)(5))(6(7(8))))
),其中每对括号代表其中一个矩形,整数是相应矩形的文件名。

4fs4gdv0nhh.JPG

4fs4gdv0nhh.JPG

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

1

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
6
发表于 2013-5-12 19:46:40 | 显示全部楼层
这是我的尝试:
  1. (defun c:rord ( / _inside-p _massoc _process ent inc itm lst ref sel sub tmp vtl )
  2.     (defun _inside-p ( ll1 ur1 ll2 ur2 )
  3.         (apply 'and (mapcar '
  4.     )
  5.     (defun _massoc ( key lst )
  6.         (if (setq itm (assoc key lst))
  7.             (cons (cdr itm) (_massoc key (cdr (member itm lst))))
  8.         )
  9.     )
  10.     (defun _process ( lst ref / itm nst out )
  11.         (while (setq itm (car lst))
  12.             (setq lst (cdr lst))
  13.             (if (setq nst (cdr (assoc itm ref)))
  14.                 (setq out (cons (cons itm (_process nst ref)) out)
  15.                       lst (vl-remove-if '(lambda ( x ) (member x nst)) lst)
  16.                 )
  17.                 (setq out (cons itm out))
  18.             )
  19.         )
  20.         (reverse out)
  21.     )
  22.    
  23.     (if (setq sel (ssget '((0 . "LWPOLYLINE") (90 . 4) (-4 . "&=") (70 . 1))))
  24.         (progn
  25.             (repeat (setq inc (sslength sel))
  26.                 (setq ent (ssname sel (setq inc (1- inc)))
  27.                       vtl (_massoc 10 (entget ent))
  28.                       tmp (cons (cons ent (mapcar '(lambda ( x ) (apply 'mapcar (cons x vtl))) '(min max))) tmp)
  29.                       lst (cons ent lst)
  30.                 )
  31.             )
  32.             (foreach x1 tmp
  33.                 (foreach x2 (vl-remove x1 tmp)
  34.                     (if (apply '_inside-p (append (cdr x2) (cdr x1)))
  35.                         (setq sub (cons (car x2) sub))
  36.                     )
  37.                 )
  38.                 (setq ref (cons (cons (car x1) sub) ref)
  39.                       sub nil
  40.                 )
  41.             )
  42.             (_process (vl-sort lst '(lambda ( a b ) (> (length (assoc a ref)) (length (assoc b ref))))) ref)
  43.         )
  44.     )
  45. )
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-13 07:29:55 | 显示全部楼层

你好,李!
您的版本为嵌套实体提供了重播...
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-13 12:30:31 | 显示全部楼层
优化了我的版本:
  1. (defun eea-test-1 (/ f l)
  2.   (defun f (l a b c)
  3.     (cond ((not l)
  4.            (cons (if b
  5.                    (cons (last a) (f (cdr (reverse b)) (last b) nil nil))
  6.                    (cddr a)
  7.                  )
  8.                  (if c
  9.                    (f (cdr (reverse c)) (last c) nil nil)
  10.                  )
  11.            )
  12.           )
  13.           ((vl-every (function
  14.           ((f (cdr l) a b (cons (car l) c)))
  15.     )
  16.   )
  17.   (if (setq l (ssget '((0 . "LWPOLYLINE") (90 . 4) (-4 . "&=") (70 . 1))))
  18.     (progn (setq l (vl-sort (mapcar (function (lambda (a) (reverse (cons a (acet-geom-extents a)))))
  19.                                     (vl-remove-if (function listp) (mapcar (function cadr) (ssnamex l)))
  20.                             )
  21.                             (function (lambda (a b) (
  22.                    )
  23.            )
  24.            (f (cdr l) (car l) nil nil)
  25.     )
  26.   )
  27. )

ps。为什么这个主题在“CAD常规”一节中,而不是在“AutoLISP (Vanilla / Visual)”一节中?
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-13 12:34:31 | 显示全部楼层

精湛的方法Evgeniy!
递归技术让我想起了这一点。
嗨,李!
您的版本为嵌套实体提供了重播.........
它在我的所有测试中都有效,但我同意该方法不如您的方法健壮。
小心的Evgeniy:
  1. (reverse (cons a (acet-geom-extents a))) =/= (append (acet-geom-extents a) (list a))

此外,由于您的目标是优化,为什么使用:
  1. (vl-remove-if (function listp) (mapcar (function cadr) (ssnamex l)))

ssnamex
已知非常慢...
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-14 07:56:40 | 显示全部楼层

绘制三个矩形,首先在内部,然后外部(请参阅附件)...
  1. ((  ( )))


谢谢!
这应该可以解决这个问题,但与你的解决方案相比,它很丑陋:
  1. (defun c:rord ( / _inside-p _massoc _process _sort enx han inc itm lst ref sel sub tmp vtl )
  2.     (defun _inside-p ( ll1 ur1 ll2 ur2 )
  3.         (apply 'and (mapcar '
  4.     )
  5.   
  6.     (defun _massoc ( key lst )
  7.         (if (setq itm (assoc key lst))
  8.             (cons (cdr itm) (_massoc key (cdr (member itm lst))))
  9.         )
  10.     )
  11.   
  12.     (defun _process ( lst ref / itm nst out )
  13.         (while (setq itm (car lst))
  14.             (setq lst (cdr lst))
  15.             (if (setq nst (cdr (assoc itm ref)))
  16.                 (setq out (cons (cons itm (_process (_sort nst ref) ref)) out)
  17.                       lst (vl-remove-if '(lambda ( x ) (member x nst)) lst)
  18.                 )
  19.                 (setq out (cons itm out))
  20.             )
  21.         )
  22.         (reverse out)
  23.     )
  24.     (defun _sort ( lst ref )
  25.         (vl-sort lst '(lambda ( a b ) (> (length (assoc a ref)) (length (assoc b ref)))))
  26.     )      
  27.   
  28.     (if (setq sel (ssget '((0 . "LWPOLYLINE") (90 . 4) (-4 . "&=") (70 . 1))))
  29.         (progn
  30.             (repeat (setq inc (sslength sel))
  31.                 (setq enx (entget (ssname sel (setq inc (1- inc))))
  32.                       vtl (_massoc 10 enx)
  33.                       han (cdr (assoc 5 enx))
  34.                       tmp (cons (cons han (mapcar '(lambda ( x ) (apply 'mapcar (cons x vtl))) '(min max))) tmp)
  35.                       lst (cons han lst)
  36.                 )
  37.             )
  38.             (foreach x1 tmp
  39.                 (foreach x2 (vl-remove x1 tmp)
  40.                     (if (apply '_inside-p (append (cdr x2) (cdr x1)))
  41.                         (setq sub (cons (car x2) sub))
  42.                     )
  43.                 )
  44.                 (setq ref (cons (cons (car x1) sub) ref)
  45.                       sub nil
  46.                 )
  47.             )
  48.             (_process (_sort lst ref) ref)
  49.         )
  50.     )
  51. )

我还使用了实体句柄而不是实体名称,因为它更容易跟踪。
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-14 08:47:21 | 显示全部楼层
是的,它工作得很好!
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-14 09:14:04 | 显示全部楼层
以下是我对您的功能的建议:
  1. (defun eea-test-1-lm ( / f e i l s )
  2.     (defun f ( l a / b c )
  3.         (foreach x l
  4.             (if (vl-every '
  5.                 (setq b (cons x b))
  6.                 (setq c (cons x c))
  7.             )
  8.         )
  9.         (cons
  10.             (if b
  11.                 (cons (last a) (f (cdr (reverse b)) (last b)))
  12.                 (cddr a)
  13.             )
  14.             (if c
  15.                 (f (cdr (reverse c)) (last c))
  16.             )
  17.         )
  18.     )
  19.     (if (setq s (ssget '((0 . "LWPOLYLINE") (90 . 4) (-4 . "&=") (70 . 1))))
  20.         (progn
  21.             (repeat (setq i (sslength s))
  22.                 (setq e (ssname s (setq i (1- i)))
  23.                       l (cons (reverse (cons (cdr (assoc 5 (entget e))) (reverse (acet-geom-extents e)))) l)
  24.                 )
  25.             )
  26.             (setq l (vl-sort l (function (lambda ( a b ) (
  27.             (f (cdr l) (car l))
  28.         )
  29.     )
  30. )

希望你不介意
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-14 09:25:33 | 显示全部楼层
另一个 - 嗖嗖嗖的方式:
  1. (defun eea-test-1 (/ f l)
  2.   (defun f (l a b c)
  3.     (cond ((not l)
  4.            (cons (if b
  5.                    (cons (last a) (f (cdr (reverse b)) (last b) nil nil))
  6.                    (cddr a)
  7.                  )
  8.                  (if c
  9.                    (f (cdr (reverse c)) (last c) nil nil)
  10.                  )
  11.            )
  12.           )
  13.           ((vl-every (function
  14.           ((f (cdr l) a b (cons (car l) c)))
  15.     )
  16.   )
  17.   (if (setq l (ssget '((0 . "LWPOLYLINE") (90 . 4) (-4 . "&=") (70 . 1))))
  18.     (progn (setq l (vl-sort (mapcar (function (lambda (a) (reverse (cons a (acet-geom-extents a))))) (acet-ss-to-list l))
  19.                             (function (lambda (a b) (
  20.                    )
  21.            )
  22.            (f (cdr l) (car l) nil nil)
  23.     )
  24.   )
  25. )

也许它更慢但更短...
回复

使用道具 举报

8

主题

65

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
86
发表于 2013-5-14 09:30:26 | 显示全部楼层
Evgeniy,
使用时:
  1. (reverse (cons a (acet-geom-extents a)))

这永远不会是真的:
  1. (vl-every (function

因为(car a)[右上角]的坐标将始终大于(cadr a)[左下角]
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-11 09:07 , Processed in 1.223450 second(s), 75 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表