AutoLISP: Break 3D line through User defined Plane

This routine was made by Chen Qing Jun, qjchen and is found at

It is quite handy if you happen to need to break a line that passes through a “plane.” I am using the term “plane” loosely because it doesn’t have to be a 3d object like a face or a solid. You define the “plane” by picking 3 points without having to use a different UCS…

Here’s how:

  • PBL
  • Pick 3 points to define the plane
  • Select the Line(s) to be broken – (Note: they must pass through the defined plane)
  • Thank you Chen!!

    Break 3d Line through Plane


    ;;;Break 3d lines by a 3d Plane
    ;;;Author: Chen Qing Jun, qjchen
    ;;;Programed by: South China University of Technology
    ;;;date: 2011.12.19
    ;;;Note: the intersection function of Line and Plane, has the parameter of nil and T
    ;;;      For T, the line segment should pass through the plane
    ;;;      but it is not necessary for the nil parameter.
    ;;;      The plane defined by 3p is infinite.
    ;;;_Some vector function, some get from gile's great function________________
    (defun q:geo:is-3p-plane(p1 p2 p3)
     (> (q:vec:Len (q:vec:Norm (q:vec:cross* (q:vec:- p2 p1) (q:vec:- p3 p1)))) 1e-6)
    (defun q:geo:is-samepoint(p1 p2) (< (distance p1 p2) 1e-5) )
    (defun q:vec:+(v1 v2) (mapcar '+ v1 v2) )
    (defun q:vec:-(v1 v2) (mapcar '- v1 v2) )
    (defun q:vec:*c(v a) (mapcar '(lambda(x) (* x a)) v) )
    (defun q:vec:dot*(v1 v2) (apply '+ (mapcar '* v1 v2)) )
    (defun q:vec:cross*(v1 v2)
      (list (q:det:2 (cadr v1) (caddr v1) (cadr v2) (caddr v2))
            (q:det:2 (caddr v1) (car v1) (caddr v2) (car v2))
            (q:det:2 (car v1) (cadr v1) (car v2) (cadr v2))) 
    ;;;;cal determinant
    ;;;;|a1 a2|
    ;;;;|b1 b2|
    (defun q:det:2(a1 a2 b1 b2)  (- (* a1 b2) (* a2 b1)))
    ;;;;Normalize a vector
    (defun q:vec:Norm(v / l)
      (if (not (zerop (setq l (distance '(0 0 0) v))))
      (mapcar '(lambda(x) (/ x l)) v))
    ;;;;Vector Length
    (defun q:vec:Len(v / l)  (distance '(0 0 0) v))
    ;;;;a normal to a plane, 
    (defun p2 p3)
      (if (q:geo:is-3p-plane p1 p2 p3)(q:vec:cross* (q:vec:- p2 p1) (q:vec:- p3 p1)))
    ;;p1 p2 are two points,V is the normal of the plane, VP is one point on the plane
    (defun q:geo:line-intersect-plane-1(P1 P2 V VP F / d l n)
     (setq n (q:vec:Norm V) l (q:vec:Norm (q:vec:- P2 P1)))
     (if (not (zerop (q:vec:dot* l n)))
         (setq d (/ (q:vec:dot* (q:vec:- VP P1) n) (q:vec:dot* l n)))
         (setq res (q:vec:+ P1 (q:vec:*c l d)))
         (setq temp (q:vec:Len (q:vec:- P2 P1)))
         (if (and F (or (< d 0) (> d (q:vec:Len (q:vec:- P2 P1))))) (setq res nil)) 
    ;;;;;;______end of Vector function__________________________________;;;
    (defun q:entmake:point(pt layer)
      (entmake (list (cons 0 "POINT")(cons 8 layer)(cons 10 pt)))
    (defun q:mulentmod (ent numlst contentlst / i x)
      (setq i 0)
      (foreach x numlst
        (if (/= (assoc x ent) nil)
          (setq ent (subst (cons x (nth i contentlst)) (assoc x ent) ent ) )
          (setq ent (append ent (list (cons x (nth i contentlst))) ) )
        (setq i (1+ i))
      (entmod ent)  ;(entupd ent)
    ;;;;;stdlib from Reini Urban
    (defun std-sslist (ss / n lst)
      (if (eq 'pickset (type ss))
        (repeat (setq n (fix (sslength ss))) ; fixed
          (setq lst (cons (ssname ss (setq n (1- n))) lst))
    ;;;???______by qjchen____________________________;;;
    (defun c:PBL()
      (setq p1 (getpoint "\nThe first point:") p2 (getpoint "\nThe second point:") p3 (getpoint "\nThe third point:"))
      (if (q:geo:is-3p-plane p1 p2 p3)
          (setq c (std-sslist(ssget '((0 . "LINE")))))
          (setq pn ( p1 p2 p3))
          (foreach x c
           (setq pa (cdr (assoc 10 (entget x))) pb (cdr (assoc 11 (entget x))))
           (setq int (q:geo:line-intersect-plane-1 pa pb pn p1 T))
           (if (and int (not (q:geo:is-samepoint int pa))(not (q:geo:is-samepoint int pb)))
    	    (q:mulentmod (entget (entmakex (entget x))) (list 62 11) (list 1 int))
    	    (q:mulentmod (entget (entmakex (entget x))) (list 62 10) (list 2 int))
    	    (entdel x)
    	    (q:entmake:point int "0")
        (princ "\n These three points can not form a plane.")
    (princ "\n Break 3d lines by a 3d Plane,by qjchen,the command is :test")

    About AutoCAD Tips

    This blog serves as a knowledge base for myself (and anyone else) so that I can reference tips & tricks that I have learned and also refer others to it as well. I hope that this blog helps you learn at least one tip to make your drafting/design experience better.
    This entry was posted in AutoLISP, AutoLISP: 3D, AutoLISP: Modify, Modifying. Bookmark the permalink.

    3 Responses to AutoLISP: Break 3D line through User defined Plane

    1. Ken Krupa says:

      Excellent – thank you!

    Leave a Reply

    Fill in your details below or click an icon to log in: Logo

    You are commenting using your account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s