Lee Mac 发表于 2022-7-6 11:09:54

 
当然,由于平行向量的叉积是零向量。。。除了我不允许零范数,因此我用一个小补丁更新了我的代码

gile 发表于 2022-7-6 11:12:01

你好
规格化例程为0,0,0向量返回nil。
 
下面是一个例程,用于评估列表中的所有点是否共线(也适用于三维点)
 
;; Linearp (gile)
;; Evaluates if all points in the list are colinear
;;
;; Arguments: a points list

(defun linearp (lst / v1 v2)
(or
   (null (cddr lst))
   (and (or
      (null (setq v1 (Normalize (mapcar '- (cadr lst) (car lst)))))
      (null (setq v2 (Normalize (mapcar '- (caddr lst) (car lst)))))
      (equal v1 v2 1e-9)
      (equal v1 (mapcar '- v2) 1e-9)
    )
    (linearp (cdr lst))
   )
)
)

;; Normalize
;; Returns the single unit vector of a vector
;;
;; Argument : a vector

(defun Normalize (v)
((lambda (l)
    (if (/= 0 l)
      (mapcar (function (lambda (x) (/ x l))) v)
    )
)
   (distance '(0 0 0) v)
)
)

David Bethel 发表于 2022-7-6 11:17:14

我不认为三个共线点可以创建一个平面。任何返回都会导致某种错误。所以零回报是正确的。至少在我看来。。。。只要它不会崩溃-大卫

gile 发表于 2022-7-6 11:19:36

 
这是CALCAD发布的例程的工作方式。
 
(if (setq normal (Norm_3pts p1 p2 p3))
(princ (strcat "\nThe normal vector is: " (vl-princ-to-string normal)))
(princ "\np1 p2 p3 are colinear, they do not define a plane")
)

David Bethel 发表于 2022-7-6 11:23:21

吉尔,
 
是的,我明白了。
 
我们正在将3DAFCE集转换为可挤出实体:
 

(and
(setq i -1
      ss (ssget "X" '((0 . "3DFACE"))))

(while (setq en (ssname ss (setq i (1+ i))))
      (setq ed (entget en))
      (foreach p '(10 11 12 13)
             (set (read (strcat "P" (itoa p)))
                     (cdr (assoc p ed))))
      (setq ocs (cond ((not (is_pt_colinear p10 p11 p12 1e-8))
                         (normal p10 p11 p12))
                        ((not (is_pt_colinear p10 p11 p13 1e-8))
                         (normal p10 p11 p13))
                        ((not (is_pt_colinear p11 p12 p13 1e-8))
                         (normal p11 p12 p13))
                        (T nil)))
      (and ocs
         (entmake (list (cons 0 "SOLID")(cons 62 256)
                        (cons 6 "BYLAYER")(cons 39 0)
                        (assoc 8 ed)
                        (cons 10 (trans p10 0 ocs))
                        (cons 11 (trans p11 0 ocs))
                        (cons 12 (trans p13 0 ocs))
                        (cons 13 (trans p12 0 ocs))
                        (cons 210 ocs)))
         (entdel en)))
(prin1))

 
我们知道这些面是共面的,因为它们的生成方式不同,但不知道它们没有一对重合点(三边面)。所以我测试了不同的点组合来找到平面。我可能可以使用空测试来提高效率-大卫

gile 发表于 2022-7-6 11:29:40

如果在共线点的情况下,您的“正常”例程返回nil,您可以编写:
(setq ocs (cond    ((normal p10 p11 p12))
       ((normal p10 p11 p13))
       ((normal p11 p12 p13))
   )
)
 
在我这边,处理3d面时,我宁愿将它们转换为只有p12等于p13的三角形面。
我编写了一个小例程,用这种方式转换3dfaces:
;; Triang3dFace
;; Divides a quadrangular 3d face into two triangular 3d faces and returns its ename
;; or 'normalise' a triangular one (3rd and 4th vertices overlapped) and returns nil.
;;
;; Argument : a 3d face (ENAME)

(defun Triang3dFace    (f3d / p1 p2 p3 p4)
(setq    elst (entget f3d)
   p1   (cdr (assoc 10 elst))
   p2   (cdr (assoc 11 elst))
   p3   (cdr (assoc 12 elst))
   p4   (cdr (assoc 13 elst))
)
(cond
   ((equal p3 p4 1e-9) nil)
   ((equal p1 p2 1e-9)
    (entmod (subst (cons 11 p3)
         (assoc 11 elst)
         (subst (cons 12 p4) (assoc 12 elst) elst)
      )
    )
    nil
   )
   ((equal p1 p4 1e-9)
    (entmod (subst (cons 13 p3) (assoc 13 elst) elst))
    nil
   )
   (T
    (if (< (distance p2 p4) (distance p1 p3))
      (progn
    (entmod
      (subst (cons 12 p4) (assoc 12 elst) elst)
    )
    (entmakex
      (subst (cons 10 p2)
         (assoc 10 elst)
         (subst (cons 11 p3)
            (assoc 11 elst)
            (subst (cons 12 p4) (assoc 12 elst) elst)
         )
      )
    )
      )
      (progn
    (entmod (subst (cons 13 p3) (assoc 13 elst) elst))
    (entmakex
      (subst (cons 11 p3)
         (assoc 11 elst)
         (subst (cons 12 p4) (assoc 12 elst) elst)
      )
    )
      )
    )
   )
)
)

;; TRIFACE
;; Converts selected 3d faces in 'normalised' triangular faces

(defun c:TriFace (/ n ss ent)
(if (and (setq n-1
      ss (ssget '((0 . "3DFACE")))
      )
   )
   (while (setq ent (ssname ss (setq n (1+ n))))
   (Triang3dFace ent)
   )
)
(princ)
)

David Bethel 发表于 2022-7-6 11:33:20

吉尔,
 
这听起来很像3Dmax所做的。使用3dsout和3dsin,可以得到非常相似的结果。谢谢-大卫
页: 1 [2]
查看完整版本: (3) 三维点到UCS拉伸