Inquiry About Lisp Routine for Extending Lines to Circle Center Point

Inquiry About Lisp Routine for Extending Lines to Circle Center Point

ishaq03
Advocate Advocate
581 Views
6 Replies
Message 1 of 7

Inquiry About Lisp Routine for Extending Lines to Circle Center Point

ishaq03
Advocate
Advocate

I am writing to inquire about a specific functionality within AutoCAD. I am currently working on a project that involves several lines that need to be precisely extended to the center point of a circle. I have been manually adjusting these lines, but this process is quite time-consuming.

Could you please let me know if there is an existing Lisp routine or any other automated method in AutoCAD that can extend lines to the centre point of a circle automatically? This feature would greatly enhance my workflow and improve efficiency.

 

ishaq03_1-1719480689846.png

 

 

0 Likes
Accepted solutions (1)
582 Views
6 Replies
Replies (6)
Message 2 of 7

Kent1Cooper
Consultant
Consultant

Are they always and only Line objects specifically?  In the image they look like they could be Polylines.  Either should be able to be processed, but differently, so it would be important to know whether they are one kind or the other, or could be either.

Kent Cooper, AIA
0 Likes
Message 3 of 7

ishaq03
Advocate
Advocate

@Kent1Cooper 

Yes, it is a polyline, but I want to link both objects to the center of the circle. Your lisp needs to be connected to either line or polyline to connect circle center point. Also, a DWG file is attached.

0 Likes
Message 4 of 7

Moshe-A
Mentor
Mentor
Accepted solution

@ishaq03 hi,

 

check this quick solution 

 

At select objects you can pick as many circles you have.

 

enjoy,

Moshe

 

 

(defun c:joinln (/ ss0 ss1 ename0 ename1 elist0 elist1 AcDbCircle c0 p0 p1)
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (if (setq ss0 (ssget '((0 . "circle"))))
  (foreach ename0 (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss0)))
   (setq AcDbCircle (vlax-ename->vla-object ename0))
   (setq c0 (vlax-safearray->list (vlax-variant-value (vla-get-center AcDbCircle))))

   (vla-getBoundingbox AcDbCircle 'MinPoint 'MaxPoint)  
   (setq p0 (vlax-safearray->list MinPoint)) 
   (setq p1 (vlax-safearray->list MaxPoint)) 

   (if (setq ss1 (ssget "_c" p0 p1 '((0 . "line,lwpolyline"))))
    (foreach ename1 (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1)))
     (setq elist1 (entget ename1))
      
     (setq p0 (vlax-curve-getStartPoint ename1))
     (setq p1 (vlax-curve-getEndPoint ename1))

     (if (< (distance c0 p0) (distance c0 p1))
      (cond
       ((eq (cdr (assoc '0 elist1)) "LINE")
        (entmod (subst (cons '10 c0) (assoc '10 elist1) elist1))
       ); case
       ((eq (cdr (assoc '0 elist1)) "LWPOLYLINE")
        (entmod (subst (cons '10 c0) (assoc '10 elist1) elist1))
       ); case
      ); cond
      (cond
       ((eq (cdr (assoc '0 elist1)) "LINE")
        (entmod (subst (cons '11 c0) (assoc '11 elist1) elist1))
       ); case
       ((eq (cdr (assoc '0 elist1)) "LWPOLYLINE")
        (entmod (subst (cons '10 c0) (assoc '10 (reverse elist1)) elist1))
       ); case
      ); cond
     ); if
      
    ); foreach
   ); if
		   
   (vlax-release-object AcDbCircle)		   
  ); foreach
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)
  
 (princ)
); c:joinln
0 Likes
Message 5 of 7

marko_ribar
Advisor
Advisor

Another one, pure Vanilla AutoLISP... Though untested...

 

(defun c:extlinslws2centers ( / s s1 s2 i e clst ex p1 p2 c1 c2 )
  (if (setq s (ssget "_:L" (list (cons -4 "<or") (cons 0 "CIRCLE,LINE") (cons -4 "<and") (cons 0 "LWPOLYLINE") (cons -4 "<or") (cons 70 0) (cons 70 128) (cons -4 "or>") (cons -4 "and>") (cons -4 "or>"))))
    (progn
      (setq s1 (ssadd))
      (setq s2 (ssadd))
      (repeat (setq i (sslength s))
        (if (= (cdr (assoc 0 (entget (setq e (ssname s (setq i (1- i))))))) "CIRCLE")
          (ssadd e s1)
          (ssadd e s2)
        )
      )
      (repeat (setq i (sslength s1))
        (setq clst (cons (list (cdr (assoc 10 (setq ex (entget (ssname s1 (setq i (1- i))))))) (cdr (assoc 40 ex))) clst))
      )
      (repeat (setq i (sslength s2))
        (if (= (cdr (assoc 0 (setq ex (entget (setq e (ssname s2 (setq i (1- i)))))))) "LINE")
          (progn
            (setq p1 (cdr (assoc 10 ex)))
            (setq p2 (cdr (assoc 11 ex)))
            (setq c1 (car (vl-sort clst (function (lambda ( a b ) (< (distance p1 (car a)) (distance p1 (car b))))))))
            (if (< (distance (car c1) p1) (cadr c1))
              (setq ex (subst (cons 10 (car c1)) (assoc 10 ex) ex))
            )
            (setq c2 (car (vl-sort clst (function (lambda ( a b ) (< (distance p2 (car a)) (distance p2 (car b))))))))
            (if (< (distance (car c2) p2) (cadr c2))
              (setq ex (subst (cons 11 (car c2)) (assoc 11 ex) ex))
            )
            (entupd (cdr (assoc -1 (entmod ex))))
          )
          (progn
            (setq p1 (cdr (assoc 10 ex)))
            (setq p2 (cdr (assoc 10 (reverse ex))))
            (setq c1 (car (vl-sort clst (function (lambda ( a b ) (< (distance p1 (car a)) (distance p1 (car b))))))))
            (if (< (distance (car c1) p1) (cadr c1))
              (setq ex (subst (cons 10 (car c1)) (assoc 10 ex) ex))
            )
            (setq c2 (car (vl-sort clst (function (lambda ( a b ) (< (distance p2 (car a)) (distance p2 (car b))))))))
            (if (< (distance (car c2) p2) (cadr c2))
              (setq ex (subst (cons 10 (car c2)) (assoc 10 (reverse ex)) ex))
            )
            (entupd (cdr (assoc -1 (entmod ex))))
          )
        )
      )
    )
  )
  (princ)
)

 

HTH.

M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 6 of 7

ishaq03
Advocate
Advocate

@Moshe-A 

I appreciate you providing the lisp; it exactly meets my needs.

0 Likes
Message 7 of 7

Kent1Cooper
Consultant
Consultant

In the case of Lines specifically, you can simply use the CHANGE command on as many of them as you want at once, with ORTHO turned off, and take all their nearer endpoints to the CENter of a Circle.  That can speed up manual operation.

 

Another question:  Do the Lines/Polylines always cross or at least touch the Circle circumference somewhere?  Or could some of them end nearby but not on or inside the Circle?  Those could be missed by crossing-window selection using the bounding box of the Circle, so should that window be enlarged to catch them?  How far would cover most situations?

 

And I would limit selection in the case of Polylines to open-ended ones only:

(ssget

  '(

    (-4 . "<OR")

      (0 . "LINE"); any Line(s), but:

      (-4 . "<AND"); only open-ended Polyline(s):

        (0 . "LWPOLYLINE") (-4 . "<NOT") (-4 . "&") (70 . 1) (-4 . "NOT>")

      (-4 . "AND>")

    (-4 . "or>")

  )

)

[Now I see Message 5 has similar functionality -- this is another way to do the same, and unlike the approach in Message 5, will remain valid if in the future some other bit-code ingredients become involved in the DXF 70 value for Polylines.]

Kent Cooper, AIA
0 Likes