Jump to content

entmakex polyline with arcs


Emmanuel Delay

Recommended Posts

Has someone made a function to entmakex polyline with arcs?

 

I want a simple 2 click accolade (  } shape ), four 90° arcs and 2 lines with adjustable length ...

 

Or perhaps it's easier to make separate arcs and lines, then PEdit Join  them?

Or straight line polyline then fillet 

...

 

Any ideas anyone?

 

 

Something like this

image.png.5155a0337630057507f86c081c725d56.png

Edited by Emmanuel Delay
Link to comment
Share on other sites

Either just a fixed radius, or something relative to the size.

I'll worry about that later

 

Right now just a 1.0 units radius 

Edited by Emmanuel Delay
Link to comment
Share on other sites

Here you go...

 

(defun c:accolade ( / *error* LM:3pcircle LM:3parc pea cmd r p1 p2 a arc1 li1 arc2 arc3 li2 arc4 ss )

  (defun *error* ( m )
    (if cmd
      (setvar 'cmdecho cmd)
    )
    (if pea
      (setvar 'peditaccept pea)
    )
    (if m
      (prompt m)
    )
    (princ)
  )

  ;; 3-Point Circle  -  Lee Mac
  ;; Returns the center (UCS) and radius of the circle defined by three supplied points (UCS).

  (defun LM:3pcircle ( pt1 pt2 pt3 / cen md1 md2 vc1 vc2 )
    (if
      (and
        (setq md1 (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) pt1 pt2))
        (setq md2 (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) pt2 pt3))
        (setq vc1 (mapcar '- pt2 pt1))
        (setq vc2 (mapcar '- pt3 pt2))
        (setq cen (inters md1 (mapcar '+ md1 (list (- (cadr vc1)) (car vc1) 0))
                          md2 (mapcar '+ md2 (list (- (cadr vc2)) (car vc2) 0))
                          nil
                  )
        )
      )
      (list cen (distance cen pt1))
    )
  )

  (defun LM:3parc ( pt1 pt2 pt3 / lst ocs arc )
    (if (setq ocs (trans '(0.0 0.0 1.0) 1 0 t))
      (if (setq lst (LM:3pcircle pt1 pt2 pt3))
        (progn
          (if (minusp (sin (- (angle pt1 pt3) (angle pt1 pt2))))
              (mapcar 'set '(pt1 pt3) (list pt3 pt1))
          )
          (setq arc
            (entmakex
              (list
               '(000 . "ARC")
                (cons 010 (trans (car lst) 1 ocs))
                (cons 040 (cadr lst))
                (cons 050 (angle (trans (car lst) 1 ocs) (trans pt1 1 ocs)))
                (cons 051 (angle (trans (car lst) 1 ocs) (trans pt3 1 ocs)))
                (cons 210 ocs)
              )
            )
          )
        )
        (princ "\nPoints are collinear.")
      )
    )
    (if arc
      arc
    )
  )

  (setq cmd (getvar 'cmdecho))
  (setvar 'cmdecho 0)
  (setq pea (getvar 'peditaccept))
  (setvar 'peditaccept 1)
  (if
    (and
      (not (initget 7))
      (setq r (getdist "\nPick or specify radius of arcs : "))
      (not (initget 1))
      (setq p1 (getpoint "\nPick or specify p1 : "))
      (not (initget 1))
      (setq p2 (getpoint p1 "\nPick or specify p2 : "))
      (> (distance p1 p2) (* 2.0 r))
      (setq a (angle p1 p2))
      (setq arc1 (LM:3parc (polar p1 (rem (+ a pi) (* 2 pi)) r) (polar p1 (rem (+ a (* 1.25 pi)) (* 2 pi)) r) (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r)))
      (setq li1 (entmakex (list (cons 0 "LINE") (cons 10 (trans (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) 1 0)) (cons 11 (trans (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (- (/ (distance p1 p2) 2.0) r)) 1 0)))))
      (setq arc2 (LM:3parc (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (- (/ (distance p1 p2) 2.0) r)) (polar (polar (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (- (/ (distance p1 p2) 2.0) r)) (rem (+ a (* 1.5 pi)) (* 2 pi)) r) (rem (+ a (* 0.25 pi)) (* 2 pi)) r) (polar (polar (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (- (/ (distance p1 p2) 2.0) r)) (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a r)))
      (setq arc3 (LM:3parc (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (+ (/ (distance p1 p2) 2.0) r)) (polar (polar (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (+ (/ (distance p1 p2) 2.0) r)) (rem (+ a (* 1.5 pi)) (* 2 pi)) r) (rem (+ a (* 0.75 pi)) (* 2 pi)) r) (polar (polar (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (+ (/ (distance p1 p2) 2.0) r)) (rem (+ a (* 1.5 pi)) (* 2 pi)) r) (rem (+ a pi) (* 2 pi)) r)))
      (setq li2 (entmakex (list (cons 0 "LINE") (cons 10 (trans (polar (polar p1 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) a (+ (/ (distance p1 p2) 2.0) r)) 1 0)) (cons 11 (trans (polar p2 (rem (+ a (* 1.5 pi)) (* 2 pi)) r) 1 0)))))
      (setq arc4 (LM:3parc (polar p2 a r) (polar p2 (rem (- a (* 0.25 pi)) (* 2 pi)) r) (polar p2 (rem (- a (* 0.5 pi)) (* 2 pi)) r)))
    )
    (progn
      (setq ss (ssadd))
      (ssadd arc1 ss)
      (ssadd li1 ss)
      (ssadd arc2 ss)
      (ssadd arc3 ss)
      (ssadd li2 ss)
      (ssadd arc4 ss)
      (vl-cmdf "_.PEDIT" "_M" ss "" "_J")
      (while (< 0 (getvar 'cmdactive))
        (vl-cmdf "")
      )
    )
  )
  (*error* nil)
)

 

HTH.

M.R.

Edited by marko_ribar
  • Like 3
Link to comment
Share on other sites

At first glance... So you did use Polyline Edit - Join.

 

Thanks a lot.

I'll test it soon

Edited by Emmanuel Delay
Link to comment
Share on other sites

In (and there was mistake :

it was written :

(> (distance p1 p2) (* 4.0 r))

and it should be :

(> (distance p1 p2) (* 2.0 r))

 

That's all...

Link to comment
Share on other sites

Here's another -

(defun c:brace ( / ang blg di1 di2 mat rad pt1 pt2 )

    (setq rad 1.0) ;; Brace radius
    
    (if (and (setq pt1 (getpoint "\nSpecify 1st point for brace: "))
            (progn
                (while
                    (and (setq pt2 (getpoint "\nSpecify 2nd point for brace: " pt1))
                         (< (distance pt1 pt2) (* 4 rad))
                    )
                    (princ "\nDistance between the two points must be greater than 4 times the radius.")
                )
                pt2
            )
        )
        (progn
            (setq di1 (distance pt1 pt2)
                  di2 (- (/ di1 2.0) rad)
                  ang (angle pt1 pt2)
                  mat (list (list (cos ang) (- (sin ang))) (list (sin ang) (cos ang)))
                  blg (1- (sqrt 2.0))
            )
            (entmake
                (append
                   '(
                        (000 . "LWPOLYLINE")
                        (100 . "AcDbEntity")
                        (100 . "AcDbPolyline")
                        (090 . 7)
                        (070 . 0)
                    )
                    (apply 'append
                        (mapcar
                            (function
                                (lambda ( a b )
                                    (list
                                        (cons 010 (mapcar '+ (mapcar '(lambda ( r ) (apply '+ (mapcar '* r a))) mat) pt1))
                                        (cons 042 b)
                                    )
                                )
                            )
                            (list
                               '(0.0 0.0)
                                (list rad (- rad))
                                (list di2 (- rad))
                                (list (+ di2 rad) (- 0 rad rad))
                                (list (- di1 di2) (- rad))
                                (list (- di1 rad) (- rad))
                                (list di1 0.0)
                            )
                            (list blg 0.0 (- blg) (- blg) 0.0 blg 0.0)
                        )
                    )
                    (list (cons 210 (trans '(0.0 0.0 1.0) 1 0 t)))
                )
            )
        )
    )
    (princ)
)

 

To flip the brace, pick the points in the opposite direction.

  • Like 5
Link to comment
Share on other sites

No Idea why I look at these, now I want to do -another- LISP, will put it on the list, a bracket / brace as above, first option "Pick a point or enter a radius (1): " (where 1 is the current radius), got that all somewhere to copy and paste.

Link to comment
Share on other sites

@Emmanuel Delay Have you thought about using a block for this?

(defun c:foo (/ d p1 p2)
  (cond	((null (tblobjname "block" "Brace"))
	 (entmake '((0 . "BLOCK")
		    (100 . "AcDbEntity")
		    (67 . 0)
		    (8 . "0")
		    (100 . "AcDbBlockReference")
		    (2 . "Brace")
		    (10 0. 0. 0.)
		    (70 . 0)
		   )
	 )
	 (entmake '((0 . "LWPOLYLINE")
		    (100 . "AcDbEntity")
		    (67 . 0)
		    (8 . "0")
		    (100 . "AcDbPolyline")
		    (90 . 7)
		    (70 . 0)
		    (43 . 0.)
		    (38 . 0.)
		    (39 . 0.)
		    (10 -0.5 0.)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . 0.414213562373095)
		    (91 . 0)
		    (10 -0.4 -0.1)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . 0.)
		    (91 . 0)
		    (10 -0.1 -0.1)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . -0.414213562373095)
		    (91 . 0)
		    (10 0. -0.2)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . -0.414213562373095)
		    (91 . 0)
		    (10 0.1 -0.1)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . 0.)
		    (91 . 0)
		    (10 0.4 -0.1)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . 0.414213562373095)
		    (91 . 0)
		    (10 0.5 0.)
		    (40 . 0.)
		    (41 . 0.)
		    (42 . 0.)
		    (91 . 0)
		   )
	 )
	 (entmake '((0 . "ENDBLK") (100 . "AcDbBlockEnd") (8 . "0")))
	)
  )
  (if (and (setq p1 (getpoint "\nPick first point: "))
	   (setq p2 (getpoint p1 "\nPick second point: "))
      )
    (entmake (list '(0 . "INSERT")
		   '(100 . "AcDbEntity")
		   '(8 . "Brace")
		   '(100 . "AcDbBlockReference")
		   '(2 . "Brace")
		   (cons 10 (mapcar '/ (mapcar '+ p1 p2) '(2 2 2)))
		   (cons 41 (setq d (distance p1 p2)))
		   (cons 42 d)
		   (cons 43 d)
		   (cons 50 (angle p1 p2))
	     )
    )
  )
  (princ)
)

 

  • Like 2
Link to comment
Share on other sites

Based on wall  insulation code I have of straights and arcs using just the pline command with option of a "Arc" would be feasible also, though the code by lee would be hard to beat. May have a go also using plain pline commands. Could add radius options in a range like 0.5 - 2.5 but more than likely will be fixed.

image.png.397762ca7515726bb13fd6e9df378e42.png

 

Another

; pline with arcs by AlanH April 2023

(defun c:wow ( / pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8 pt9 pt10 pt11 dist ang rad)
(setq rad 1)

(setq pt1 (getpoint "\nPick start point "))
(setq pt11 (getpoint pt1 "\nPick end point "))

(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)

(setq ang (angle pt1 pt11))
(setq dist (distance pt1 pt11))
; do like Lee check dist is long enough 

(setq pt2 (polar (polar pt1 ang rad) (+ ang (* 1.25 pi)) rad))
(setq pt3 (polar (polar pt1 ang rad) (- ang (/ pi 2)) rad))
(setq pt4 (polar pt3 ang (- (/ dist 2.0) (* 2.0 rad))))
(setq pt5 (polar (polar pt4 (- ang (/ pi 2.)) rad)(+ ang (* 0.25 pi)) rad))
(setq pt6 (polar (polar pt4 ang rad) (- ang (/ pi 2)) rad))
(setq pt7 (polar (polar pt6 ang rad) (+ ang (* 0.75 pi)) rad))
(setq pt8 (polar pt4 ang (* 2.0 rad)))
(setq pt9 (polar pt8 ang (- (/  dist 2.0) (* 2.0 rad))))
(setq pt10 (polar (polar pt11 (+ pi ang) rad) (+ ang (* 1.75 pi)) rad))

(command "pLINE"  pt1 "w" 0.0 0.0 "arc" "s" pt2 pt3 "L" pt4 "arc" "s" pt5 pt6  "arc" "s" pt7 pt8 "L" pt9 "arc" "s" pt10 pt11 "")

(setvar 'osmode oldsnap)
(princ)
)

 

image.thumb.png.16e7df6ccbe75684bd9e5256be77eccd.png

Edited by BIGAL
  • Like 2
Link to comment
Share on other sites

My grain of sand

another. Selecting 3 points. The third point will be on one side or the other of the main alignment.

The radius is equal to the distance from p3 to the line p1-p2/2

 

(defun punto_izda_dcha (p1 p2 p3 / a b c)
  (defun det3 (a b c)
    (+ (det2 b c) (det2 a b) (- (det2 a c)))
  )
  (defun det2 (a b)
    (- (* (car a) (cadr b)) (* (car b) (cadr a)))
  )
  (setq resultado (/ (det3 p1 p2 p3) 2))
 
)

(defun c:llave (/ pt1 pt2 pt3 dist_pt1_pt2 radio bulge p2aux p3aux p4aux p5aux p6aux
        area ang_perp)
  (if (= cal nil) (arxload "geomcal"))
  (setq pt1 (getpoint "\nIndica el punto 1: "))
  (setq pt2 (getpoint "\nIndica el punto 2: "))
  (setq pt3 (getpoint "\nIndica el punto 3: "))
  
  (setq dist_pt1_pt2 (distance pt1 pt2))
  (setq radio (/ (c:cal "dpl(pt3,pt1,pt2)") 2.))
  (setq bulge (abs(- 1 (sqrt 2))))

  (cond ((equal (c:cal "dpl(pt3,pt1,pt2)") 0.0 0.01)
     (setq radio (/ dist_pt1_pt2 8))
    )
    ((> (* (c:cal "dpl(pt3,pt1,pt2)") 4) dist_pt1_pt2)
     (setq radio (/ dist_pt1_pt2 4))
    )
  )
     

  (setq p2aux (polar pt1 (angle pt1 pt2) radio))
  (setq p4aux (mapcar '(lambda (x y) (/ (+ x y) 2)) pt1 pt2))
  (setq p3aux (polar p4aux (angle pt2 pt1) radio))
  (setq p5aux (polar p4aux (angle pt1 pt2) radio))
  (setq p6aux (polar pt2 (angle pt2 pt1) radio))

  (setq area (punto_izda_dcha pt1 pt2 pt3))
  
  (if (< area 0)
    (setq ang_perp (+ (angle pt1 pt2) (* (/ pi 2)3)))
    (setq ang_perp (+ (angle pt1 pt2) (/ pi 2)))
  )
  (setq p2 (polar p2aux ang_perp radio))
  (setq p3 (polar p3aux ang_perp radio))
  (setq p4 (polar p4aux ang_perp (* radio 2)))
  (setq p5 (polar p5aux ang_perp radio))
  (setq p6 (polar p6aux ang_perp radio))
  
  (entmake (list '(0 . "LWPOLYLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbPolyline")
               '(90 . 7)
               '(43 . 0.25);grosor
               '(38 . 0.0);elevacion
               '(62 . 1);color por capa
               (list 10 (car pt1) (cadr pt1))
                       '(40 . 0.0) '(41 . 0.0)
               (if (< area 0) (cons 42 bulge) (cons 42 (- bulge)))
               (list 10 (car p2) (cadr p2))
               '(40 . 0.0) '(41 . 0.0) '(42 . 0.0)
               (list 10 (car p3) (cadr p3))
               '(40 . 0.0) '(41 . 0.0)
               (if (< area 0) (cons 42 (- bulge)) (cons 42 bulge))
                (list 10 (car p4) (cadr p4))
               '(40 . 0.0) '(41 . 0.0)
               (if (< area 0) (cons 42 (- bulge)) (cons 42 bulge))
                       (list 10 (car p5) (cadr p5))
               '(40 . 0.0) '(41 . 0.0) '(42 . 0.0)
               (list 10 (car p6) (cadr p6))
               '(40 . 0.0) '(41 . 0.0)
                (if (< area 0) (cons 42 bulge) (cons 42 (- bulge)))
                (list 10 (car pt2) (cadr pt2))
                       '(40 . 0.0) '(41 . 0.0) '(42 . 0.0)
               '(210 0.0 0.0 1.0)
  ))
  
)


image.thumb.png.826164c93029f7b4e8ca7e091275b4b5.png

Edited by robierzo
  • Like 1
Link to comment
Share on other sites

On 4/21/2023 at 5:43 PM, Lee Mac said:

Here's another -

(defun c:brace ( / ang blg di1 di2 mat rad pt1 pt2 )

    (setq rad 1.0) ;; Brace radius
    
    (if (and (setq pt1 (getpoint "\nSpecify 1st point for brace: "))
            (progn
                (while
                    (and (setq pt2 (getpoint "\nSpecify 2nd point for brace: " pt1))
                         (< (distance pt1 pt2) (* 4 rad))
                    )
                    (princ "\nDistance between the two points must be greater than 4 times the radius.")
                )
                pt2
            )
        )
        (progn
            (setq di1 (distance pt1 pt2)
                  di2 (- (/ di1 2.0) rad)
                  ang (angle pt1 pt2)
                  mat (list (list (cos ang) (- (sin ang))) (list (sin ang) (cos ang)))
                  blg (1- (sqrt 2.0))
            )
            (entmake
                (append
                   '(
                        (000 . "LWPOLYLINE")
                        (100 . "AcDbEntity")
                        (100 . "AcDbPolyline")
                        (090 . 7)
                        (070 . 0)
                    )
                    (apply 'append
                        (mapcar
                            (function
                                (lambda ( a b )
                                    (list
                                        (cons 010 (mapcar '+ (mapcar '(lambda ( r ) (apply '+ (mapcar '* r a))) mat) pt1))
                                        (cons 042 b)
                                    )
                                )
                            )
                            (list
                               '(0.0 0.0)
                                (list rad (- rad))
                                (list di2 (- rad))
                                (list (+ di2 rad) (- 0 rad rad))
                                (list (- di1 di2) (- rad))
                                (list (- di1 rad) (- rad))
                                (list di1 0.0)
                            )
                            (list blg 0.0 (- blg) (- blg) 0.0 blg 0.0)
                        )
                    )
                    (list (cons 210 (trans '(0.0 0.0 1.0) 1 0 t)))
                )
            )
        )
    )
    (princ)
)

 

To flip the brace, pick the points in the opposite direction.

 

I'm rewriting this to do more general making of polylines with lines and arcs.

 

Before asking the question I had something like this, where I would put extra bulge information in lst, and feed it to (cons 42).   But this doesn't work.

(defun drawLWPoly_arcs (lst cls)
 (entmakex (append 
					(list (cons 0 "LWPOLYLINE")
                         (cons 100 "AcDbEntity")
                         (cons 100 "AcDbPolyline")
                         (cons 90 (length lst))
                         (cons 70 cls)
					)
                    (mapcar (function (lambda (p) (cons 10 p) (cons 40 0.0) (cons 41 0.0) (cons 42 0.0) (cons  91 0)  )) lst)
				   )))

 

 

But I'll work further on something like this.  I feed it an pointlist and bulge list ...

 


(defun c:brace2 ( /  pointlist bulgelist ang blg di1 di2 mat rad pt1 pt2)
    (setq rad 1.0) ;; Brace radius
	
	(setq pt1 (getpoint "\nSpecify 1st point for brace: "))
	(setq pt2 (getpoint "\nSpecify 2nd point for brace: " pt1))
	
	(setq di1 (distance pt1 pt2)
		  di2 (- (/ di1 2.0) rad)
		  ang (angle pt1 pt2)
		  mat (list (list (cos ang) (- (sin ang))) (list (sin ang) (cos ang)))
		  blg (1- (sqrt 2.0))
	)

	(setq pointlist 
		(list
		   '(0.0 0.0)
			(list rad (- rad))
			(list di2 (- rad))
			(list (+ di2 rad) (- 0 rad rad))
			(list (- di1 di2) (- rad))
			(list (- di1 rad) (- rad))
			(list di1 0.0)
		)
	)
			
	(setq bulgelist 
		(list blg 0.0 (- blg) (- blg) 0.0 blg 0.0)
		;;(list blg 0.0 blg blg 0.0 blg 0.0)
	)
				
	(princ mat)			
				
	(entmake_points_bulges_list pt1 mat pointlist bulgelist)
	(princ)
)

(defun entmake_points_bulges_list (pt1 mat pointlist bulgelist / )
        (progn
            (entmake
                (append
                   '(
                        (000 . "LWPOLYLINE")
                        (100 . "AcDbEntity")
                        (100 . "AcDbPolyline")
                        (090 . 7)
                        (070 . 0)
                    )
                    (apply 'append
                        (mapcar
                            (function
                                (lambda ( a b )
                                    (list
                                        (cons 010 (mapcar '+ (mapcar '(lambda ( r ) (apply '+ (mapcar '* r a))) mat) pt1))
                                        (cons 042 b)
                                    )
                                )
                            )
							pointlist
							bulgelist
                        )
                    )
                    (list (cons 210 (trans '(0.0 0.0 1.0) 1 0 t)))
                )
            )
        )
    (princ)
)

 

 

So may thanks.

 

Same for the rest of you.  I'll find useful bits I can use for later projects.

 

Link to comment
Share on other sites

I'll put it back.

I wanted to first see what's the minimum parameters the second function needs.  Isolate the brace from the entmaking of the polyline, and have it run.

Link to comment
Share on other sites

Doing the entmake with bulges to me was complicated v's working out points and making a pline. Speed is not a problem, a simple pline. Can add radius input etc as you should know with a dcl it keeps last value entered as current press Ok to keep going, when repeated.

 

 

Edited by BIGAL
Link to comment
Share on other sites

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...