Grrr 发表于 2022-7-5 17:39:54

查找BBox';s关键点

大家好,
我试图从对象的边界框中找到一些关键点(请参见代码中的图)。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;x - points to find:
;TopLeft, MiddleLeft,
;BottomLeft; TopCenter, MiddleCenter,
;BottomCenter; TopRight, MiddleRight, BottomRight
;
;                   TC
;                  /
; TL-> x**********x**********x <- TR
;      *                     *
;      *                     *
;      *                     *
; ML-> x          * <- MC    x <- MR
;      *                     *
;      *                     *
;      *                     *
; BL-> x**********x**********x <- BR
;                /
;            BC
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun C:test (/ oldPDM ent vla-obj bbox mn mx)
(if
        (setq ent (car (entsel "\nPick an entity")))
        (progn
                (setq oldPDM (getvar 'PDMODE))
                (setvar 'PDMODE 35)
                (setq vla-obj (vlax-ename->vla-object ent))
                (setq bbox (vla-getboundingbox vla-obj 'mn 'mx))
                ; (setq TL)
                ; (setq ML)
                (setq BL (trans (vlax-safearray->list mn) 0 1) )
                (setq TR (trans (vlax-safearray->list mx) 0 1) )
                ; (setq MR)
                ; (setq BR)
                ; (setq TC)
                ; (setq MC)
                ; (setq BC)
               
                ; Perform Check:
                (point BL)
                (point TR)
               
                (setvar 'PDMODE oldPDM)
        );progn
);if
(princ)
);defun       

; LM:
(defun Point (pt)
(entmakex
        (list
                (cons 0 "POINT")
                (cons 10 pt)
        )
)
)

知道对角线的角度和长度并使用正弦和余弦函数可能会使任务变得轻松,但我已经有一段时间没有练习数学了,当涉及到弧度时,我有点困惑。
 
编辑:
更好的主意:为什么不做这样的事?,并为您获得学分:
; Define Sub-function that returns assoc list
; input: entityname
; (ent / TL ML BL TC MC BC TR MR BR)
; return example:
; ((TL . ptx) (ML . ptx) (BL . ptx) (TC . ptx) (MC . ptx) (BC . ptx) (TR . ptx) (MR . ptx) (BR . ptx))
; ptx - coordinates of the point

Grrr 发表于 2022-7-5 17:57:36

我有点明白了:
; Define Sub-function that returns assoc list
; input: entityname
; (ent / TL ML BL TC MC BC TR MR BR)
; return example:
; ((TL . ptx) (ML . ptx) (BL . ptx) (TC . ptx) (MC . ptx) (BC . ptx) (TR . ptx) (MR . ptx) (BR . ptx))
; ptx - coordinates of the point

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;x - points to find:
;TopLeft, MiddleLeft,
;BottomLeft; TopCenter, MiddleCenter,
;BottomCenter; TopRight, MiddleRight, BottomRight
;
;                   TC
;                  /
; TL-> x**********x**********x <- TR
;      *                     *
;      *                     *
;      *                     *
; ML-> x          * <- MC    x <- MR
;      *                     *
;      *                     *
;      *                     *
; BL-> x**********x**********x <- BR
;                /
;            BC
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun C:test (/ oldPDM ent vla-obj bbox mn mx TL BL ML TR BR MR TC BC MC BBoxJustificationsList)
(if
        (setq ent (car (entsel "\nPick an entity")))
        (progn
                (setq oldPDM (getvar 'PDMODE))
                (setvar 'PDMODE 35)
                (setq vla-obj (vlax-ename->vla-object ent))
                (setq bbox (vla-getboundingbox vla-obj 'mn 'mx))
               
                (setq TL (list (car (trans (vlax-safearray->list mn) 0 1) ) (cadr (trans (vlax-safearray->list mx) 0 1) ) (caddr (trans (vlax-safearray->list mx) 0 1) ) ) )
                (setq BL (trans (vlax-safearray->list mn) 0 1) )
                (setq ML (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) BL TL))
               
                (setq TR (trans (vlax-safearray->list mx) 0 1) )
                (setq BR (list (car (trans (vlax-safearray->list mx) 0 1) ) (cadr (trans (vlax-safearray->list mn) 0 1) ) (caddr (trans (vlax-safearray->list mn) 0 1) ) ) )       
                (setq MR (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) BR TR))
               
                (setq TC (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) TL TR))
                (setq BC (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) BL BR))
                (setq MC (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) BL TR))
               
                ; Perform Check:
                ; (point TL)
                ; (point BL)
                ; (point ML)
               
                ; (point TR)
                ; (point BR)
                ; (point MR)
               
                ; (point TC)
                ; (point BC)
                ; (point MC)
               
                (setq BBoxJustificationsList
                        (list
                                (cons "TL" TL)
                                (cons "BL" BL)
                                (cons "ML" ML)
                                (cons "TR" TR)
                                (cons "BR" BR)
                                (cons "MR" MR)
                                (cons "TC" TC)
                                (cons "BC" BC)
                                (cons "MC" MC)
                        )
                )
                (print BBoxJustificationsList)
                (foreach pt BBoxJustificationsList
                        (point (cdr pt))
                );foreach
                ; (setvar 'PDMODE oldPDM)
        );progn
);if
(princ)
);defun       

; LM:
(defun Point (pt)
(entmakex
        (list
                (cons 0 "POINT")
                (cons 10 pt)
        )
)
)

非常感谢您的评论。

Simon1976 发表于 2022-7-5 18:04:33

你好,Grrr
您可以从使用的两个安全数组函数返回的两个坐标集的组合以及角度BL TR和BL TR之间的距离中获得所有这些点。
例如,要查找中间中心MC点,请执行以下操作:
(setq ang (angle BL TR))
(setq dist (distance BL TR))
(setq MC (polar BL ang (* 0.5 dist))

Grrr 发表于 2022-7-5 18:13:59

谢谢Simon1976
我想知道它将如何与cos和sin函数一起工作(正如我为另一个想法所评论的)。

Tharwat 发表于 2022-7-5 18:22:29

你好
 
看一下以下代码,我确实按照您想要的列表订购了它们:
 

(if (and (setq ent (car (entsel "\nPick an entity")))
      (vlax-method-applicable-p (setq vla (vlax-ename->vla-object ent)) 'getboundingbox)
      )
(progn
   ;; ((TL . ptx) (ML . ptx) (BL . ptx) (TC . ptx) (MC . ptx) (BC . ptx) (TR . ptx) (MR . ptx) (BR . ptx))
   (vla-getboundingbox vla 'mn 'mx)
   (setq cor1 (mapcar 'vlax-safearray->list (list mn mx))
         cor2 (list (list (caar cor1) (cadadr cor1) 0.)
                  (list (caar (cdr cor1)) (cadar cor1) 0.))
         mids (mapcar '(lambda (j k)
                         (mapcar '(lambda (j k) (* (+ j k) 0.5)) j k)
                         )
                (append cor1 (list (car cor2) (car cor1) (car cor1)))
                (append cor2 (list (cadr cor1) (cadr cor2) (cadr cor1)))
                )
         fnl(list (car cor2)
                  (car mids)
                  (car cor1)
                  (caddr mids)
                  (last mids)
                  (nth 3 mids)
                  (cadr cor1)
                  (cadr mids)
                  (cadr cor2)
                  )
         )
   )
)

Grrr 发表于 2022-7-5 18:32:57

谢谢,塔瓦!
我必须承认,这个嵌套的mapcar lambda看起来真的很混乱。似乎您对X和Y坐标进行“排序”以找到每个角,然后使用mapcar lambda作为中点。
但你们如何对这样的程序进行检查呢?我的意思是,你在任何地方都创建了即使是日志监视也很难理解的列表:
LOG Watch
...............
MIDS = ((62908.7 47976.2 -5.0e-010) (63034.7 47976.2 5.0e-010) (62971.7 48021.2 5.0e-010) (62971.7 47931.2 -5.0e-010) (62971.7 47976.2 0.0))
COR2 = ((62908.7 48021.2 0.0) (63034.7 47931.2 0.0))
COR1 = ((62908.7 47931.2 -1.0e-009) (63034.7 48021.2 1.0e-009))
FNL = ((62908.7 48021.2 0.0) (62908.7 47976.2 -5.0e-010) (62908.7 47931.2 -1.0e-009) (62971.7 48021.2 5.0e-010) (62971.7 47976.2 0.0) (62971.7 47931.2 -5.0e-010) (63034.7 48021.2 1.0e-009) (63034.7 47976.2 5.0e-010) (63034.7 47931.2 0.0))
...............
或者你会提出观点吗?或者你只是凭直觉编码?
 
编辑:嗯,我试过用一个100x100的正方形,在0,0,0上有一个角,得到了这个:
((0.0 100.0 0.0) (0.0 50.0 0.0) (0.0 0.0 0.0) (50.0 100.0 0.0) (50.0 50.0 0.0) (50.0 0.0 0.0) (100.0 100.0 0.0) (100.0 50.0 0.0) (100.0 0.0 0.0))
这看起来更清楚了,但仍然?

Tharwat 发表于 2022-7-5 18:42:16

你好
 
当您有嵌套的Mapcar时,这意味着代码在列表中实现处理列表。
 
变量细分:
“cor1”包含两个坐标点BL和TR。
“cor2”包含两个坐标TL和BR。
“mids包含所有中点,我在这里按顺序排列:ML、MR、TC、BC。
“fnl”根据您的要求保存点的排列顺序。
 
为我写代码意味着我需要理解每一段代码,知道代码将引导我去哪里,否则我会迷路,会想出不想要的代码,而致命的是,我需要一次又一次地开始,以达到我期待的目的地。
 
首先,我以非常缓慢的方式编写代码,专门用于需要一些复杂过程的任务,例如坐标、对象列表、排序。。。等等,当我正确获得列表后,我就在它们上执行我需要的任务,这样我就可以运行任何函数,而不需要注意任何错误,就像那样。
 
在所有这些之后,我可以用Vlide检查程序,如果有任何错误或任何不希望的结果,那么我会重新检查代码的主要部分并解决它。
 
当你知道你想要什么,你有正确的工具来完成一项任务,更重要的是,当你知道如何使用这些工具时,你就很容易成功地达到你的目标。
 
祝你好运,编码愉快。
 
塔瓦特
页: [1]
查看完整版本: 查找BBox';s关键点