Jump to content

Recommended Posts

Posted

Dear all,

I am looking for a lisp that extend selected line perpendicular to picked point as shown in the picture.

Extend.jpg

Posted

Give this a shot. :) 

(defun c:Test (/ s e p a b g x d)
  ;; Tharwat - 10.Feb.2021	;;
  (and
    (setq
      s (car (entsel "\nSelect line to extend to desired point : "))
    )
    (or (= (cdr (assoc 0 (setq e (entget s)))) "LINE")
        (alert "Invalid object. Please select line object.")
    )
    (or
      (/= 4
          (logand
            4
            (cdr
              (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 e)))))
            )
          )
      )
      (alert
        (strcat "Select line object resides on a LOACKED layer <!>")
      )
    )
    (setq p (getpoint
              "\nSpecify a point to extend the previously line to : "
            )
    )
    (setq a (cdr (assoc 10 e))
          b (cdr (assoc 11 e))
          g (angle a b)
    )
    (vl-some '(lambda (u)
                (setq x (inters a b p (polar p (eval u) 1.0) nil))
              )
             '((+ g (* pi 0.5)) (+ g pi))
    )
    (setq d (if (< (distance x a) (distance x b))
              10
              11
            )
    )
    (entmod (subst (cons d x) (assoc d e) e))
  )
  (princ)
)

 

  • Like 1
Posted
1 hour ago, Tharwat said:

Give this a shot. :) 


(defun c:Test (/ s e p a b g x d)
  ;; Tharwat - 10.Feb.2021	;;
  (and
    (setq
      s (car (entsel "\nSelect line to extend to desired point : "))
    )
    (or (= (cdr (assoc 0 (setq e (entget s)))) "LINE")
        (alert "Invalid object. Please select line object.")
    )
    (or
      (/= 4
          (logand
            4
            (cdr
              (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 e)))))
            )
          )
      )
      (alert
        (strcat "Select line object resides on a LOACKED layer <!>")
      )
    )
    (setq p (getpoint
              "\nSpecify a point to extend the previously line to : "
            )
    )
    (setq a (cdr (assoc 10 e))
          b (cdr (assoc 11 e))
          g (angle a b)
    )
    (vl-some '(lambda (u)
                (setq x (inters a b p (polar p (eval u) 1.0) nil))
              )
             '((+ g (* pi 0.5)) (+ g pi))
    )
    (setq d (if (< (distance x a) (distance x b))
              10
              11
            )
    )
    (entmod (subst (cons d x) (assoc d e) e))
  )
  (princ)
)

 

Thank you very much for your prompt solution.

I works perfect in 2D or in the same z-coordinate of both line and point.

If I move line in Z-coord. it doesn't work and in my dwg where I want to extend it to circle I obtain alert: "Oblique, non-uniformly scaled objects were ignored."

It probably needs to ignore Z-coord of desired point.

I enclosed part of my dwg.

Extend_2.dwg

Posted

Just pick the grip of the line you want to extend, right-click and select Extend, then pick the point.

Easy-peasy!

Posted

tombu, You are correct in that you do not need a lisp routine to extend the line.  I noticed the OP is using AutoCAD 2016; so do I.  For us right clicking on the line's grip does not reveal "Extend" in the context menu.  However when I select a grip a box appears with "Stretch" and "Lengthen".  Clicking on "Lengthen" and then picking the desired point to which you want to extend the line does exactly what we want.  This works regardless of the value of the Z's.  As you say easy-peasy!

  • Like 1
Posted

I have modified z-coordinate of p-point by z- coord of line point and it works.

Both end points of line must have equal z-coordinate.

(defun c:ExtL (/ s e p a b g x d)
  ;; Tharwat - 10.Feb.2021	;;
  (and
    (setq
      s (car (entsel "\nSelect line to extend to desired point : "))
    )
    (or (= (cdr (assoc 0 (setq e (entget s)))) "LINE")
        (alert "Invalid object. Please select line object.")
    )
    (or
      (/= 4
          (logand
            4
            (cdr
              (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8
e)))))
            )
          )
      )
      (alert
        (strcat "Select line object resides on a LOACKED layer
<!>")
      )
    )
    (setq p (getpoint
              "\nSpecify a point to extend the previously line to :
"
            )
    )
    (setq a (cdr (assoc 10 e))
          b (cdr (assoc 11 e))
          g (angle a b)
    )
;;;    Redefine z-coord of p-point
    (setq p (list (car p) (cadr p) (caddr a)))
    
    (vl-some '(lambda (u)
                (setq x (inters a b p (polar p (eval u) 1.0) nil))
              )
             '((+ g (* pi 0.5)) (+ g pi))
    )
    (setq d (if (< (distance x a) (distance x b))
              10
              11
            )
    )
    (entmod (subst (cons d x) (assoc d e) e))
  )
  (princ)
)

 

  • 1 year later...
Posted (edited)

Hi Tharwat. Nice code. Is it possible to do some changes to the code ?

1) I want to pick first the point and then to give me the option to extend multiple lines

2) to pick first the point and then to give me the option to trim multiple lines as Test2 lisp code

 

(defun c:Test (/ s e p a b g x d)
  ;; Tharwat - 10.Feb.2021	;;
  (and
    (setq
      s (car (entsel "\nSelect line to extend to desired point : "))
    )
    (or (= (cdr (assoc 0 (setq e (entget s)))) "LINE")
        (alert "Invalid object. Please select line object.")
    )
    (or
      (/= 4
          (logand
            4
            (cdr
              (assoc 70 (entget (tblobjname "LAYER" (cdr (assoc 8 e)))))
            )
          )
      )
      (alert
        (strcat "Select line object resides on a LOACKED layer <!>")
      )
    )
    (setq p (getpoint
              "\nSpecify a point to extend the previously line to : "
            )
    )
    (setq a (cdr (assoc 10 e))
          b (cdr (assoc 11 e))
          g (angle a b)
    )
    (vl-some '(lambda (u)
                (setq x (inters a b p (polar p (eval u) 1.0) nil))
              )
             '((+ g (* pi 0.5)) (+ g pi))
    )
    (setq d (if (< (distance x a) (distance x b))
              10
              11
            )
    )
    (entmod (subst (cons d x) (assoc d e) e))
  )
  (princ)
)

 

Thanks

Edited by prodromosm
  • 2 weeks later...
Posted (edited)

The following should work on multiple lines anywhere in 3D.

(defun c:test (/ p ss n i en ed e1 e2 ea eb end u d ee)
  ;; L. Minardi  5/2/2022
  (setq p (getpoint "\nSpecify projection point."))
  (setq ss (ssget '((0 . "line"))))
  (setq n (sslength ss))
  (setq i 0)
  (while (< i n)
    (setq en (ssname ss i))
    (setq ed (entget en))
    (setq e1 (cdr (assoc 10 ed))
	  e2 (cdr (assoc 11 ed))
    )
    (if	(> (distance e1 p) (distance e2 p))
      (progn
	(setq ea e1
	      eb e2
	      end 11
	)
      )
      (progn (Setq ea e2
		   eb e1
		   end 10
	     )
      )
    )
    (setq u (uvec ea eb))
    (setq d (dot (mapcar '- p ea) u))
    (setq ee (mapcar '+ ea (mapcar '* u (list d d d))))
    (entmod (subst (cons end ee) (assoc end ed) ed))
    (setq  i (+ i 1))
  )					; end while
  (princ)
)

; calculate unit vector from v1 to v2
(defun uvec (v1 v2 / s)
  (setq s (distance v1 v2))
  (setq s (mapcar '/ (mapcar '- v2 v1) (list s s s)))
)
;;; Compute the dot product of 2 vectors a and b
(defun dot (a b / dd)
  (setq dd (mapcar '* a b))
  (setq dd (+ (nth 0 dd) (nth 1 dd) (nth 2 dd)))
)					;end of dot

 

Edited by lrm
  • Like 1
Posted

Hi lrm nice update but i find a problem with the trim. Trims the line from the side nearest to the point. Is  it possible to trim from the selected side  of the line?

 

Thanks

Posted (edited)

The program functions as you requested in your first post.  The following is how I interpret your revised request.  

Do you really want to trim the far end from the projected point if that is where the line is picked.  The red points are where the line was picked.  The whit points are the point to set the trimming.  The magenta line indicates the projected point onto the line.

 

Please edit the drawing/image to define what you want for these 4 cases.

image.thumb.png.2e013f84af0da5265c5d8f56c9c491c2.png

 

 

 

 

 

trim lines.dwg

 

Edited by lrm
Posted

Hi lrm. Look the example. Is not trim in correct direction. Trim. The extend is correct because the extend point is far away from the line, but  when I trim the line is more complicated 

Screenshot 2022-05-04 093410.jpg

Drawing1.dwg

Posted

It's still not clear what you want.  From your post

image.thumb.png.55f914f48ea47f62af54b441e93a4cf1.png

implies that  the line should be trimmed for the segment where the line is picked (selected).

 

Whereas (again from your post), the following implies the opposite.  That the pick point identifies the portion of the line to keep.

image.thumb.png.cbc5fe09fd0f1c6f91ff0da6fad62e14.png

Which is it.  Keep or delete the segment with the pick point?

 

AutoCAD's trim command deletes the segment containing the pick point.  

 

 

image.png

Posted

This version trims the portion of the line where the line is picked for selection.  I

;  Trims selected line to the 3D projection of a point to the line.
; The line selection pick determines segment to be trimmed.
; L. Minardi  5/4/2022
(defun c:test (/ p ss en ed e1 e2 ea eb end u d ee)
  (setq p (getpoint "\nSpecify projection point."))
  (setq more T)
  (while more
    (setq ent (entsel))
    (if	ent
      (progn
	(setq pp (cadr ent)
	      en (car ent)
	      ed (entget en)
	      e1 (cdr (assoc 10 ed))
	      e2 (cdr (assoc 11 ed))
	)
	(if (> (distance e1 p) (distance e2 p))
	  (progn
	    (setq ea  e1
		  eb  e2
		  end 11
	    )
	  )
	  (progn (Setq ea  e2
		       eb  e1
		       end 10
		 )
	  )
	)
	(setq u	 (uvec ea eb)
	      d	 (dot (mapcar '- p ea) u)
	      ee (mapcar '+ ea (mapcar '* u (list d d d))) ; project point
	)
	; is ee in line segment      
	(if (< (* (dot (mapcar '- ee ea) (mapcar '- ee eb))) 0.0)
	;case for ee in line segment
	  (progn
	    (if
	      (> (* (dot (mapcar '- e1 ee) (mapcar '- pp ee))) 0.0)
	       (progn
		 (setq end 10)
		 (entmod (subst (cons end ee) (assoc end ed) ed))
	       )
	       (progn
		 (setq end 11)
		 (entmod (subst (cons end ee) (assoc end ed) ed))
	       )
	    )				
	  )				
	; case for ee beyond line segment      
	  (entmod (subst (cons end ee) (assoc end ed) ed))
	)	; end IF line segment check
      )
      (setq more nil)
    )					; end IF ent
  )					; end while
  (princ)
)
; calculate unit vector from v1 to v2
(defun uvec (v1 v2 / s)
  (setq s (distance v1 v2))
  (setq s (mapcar '/ (mapcar '- v2 v1) (list s s s)))
)
;;; Compute the dot product of 2 vectors a and b
(defun dot (a b / dd)
  (setq dd (mapcar '* a b))
  (setq dd (+ (nth 0 dd) (nth 1 dd) (nth 2 dd)))
)					;end of dot

 

Posted

The second code does exactly what I want. If it  gives me the opportunity (like the previous code) to select window, more than one lines will be perfect.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...