当然,由于平行向量的叉积是零向量。。。除了我不允许零范数,因此我用一个小补丁更新了我的代码 你好
规格化例程为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)
)
) 我不认为三个共线点可以创建一个平面。任何返回都会导致某种错误。所以零回报是正确的。至少在我看来。。。。只要它不会崩溃-大卫
这是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")
) 吉尔,
是的,我明白了。
我们正在将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))
我们知道这些面是共面的,因为它们的生成方式不同,但不知道它们没有一对重合点(三边面)。所以我测试了不同的点组合来找到平面。我可能可以使用空测试来提高效率-大卫 如果在共线点的情况下,您的“正常”例程返回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)
)
吉尔,
这听起来很像3Dmax所做的。使用3dsout和3dsin,可以得到非常相似的结果。谢谢-大卫
页:
1
[2]