Need some expertise with this one

Need some expertise with this one

Anonymous
Not applicable
1,012 Views
9 Replies
Message 1 of 10

Need some expertise with this one

Anonymous
Not applicable

Hello everyone,

 

I have spent a long time trying to dissect this code and add or change what it need to do what i want. 

This code prompts the user to select a polyline and then creates circles in that polyline also centering them in an offset pattern. 

I have been trying to get the code to draw the circles in a parallel pattern and center them. I got as far as getting it to draw them in a parallel pattern but I cant figure out the math or code behind getting it to center it.

Heres the code...

(defun c:MPC (/ circle grx gry grd dia pll pur mid nll pnt oy ox iy iy)
  
  (defun circle (cen rad)
    (entmakex (list (cons 0 "CIRCLE")
		    (cons 10 cen)
		    (cons 40 rad))))
  
  (setq grx (cvunit 32 "mm" "inch")				; grid x distance
	gry (cvunit 32 "mm" "inch")				; grid y distance
	dia 0.315						; circle diameter
	
	grd (list grx gry)			; grid '(x y)
	)
  ;(setvar "clayer" "_Perforations")
  
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))								; multiple polyline selection
    
    (repeat (setq i (sslength ss))									;repeats the number of objects selccted
      (setq en (ssname ss (setq i (1- i))))								; polyline's ename
      (if (and (not (vla-getboundingbox (vlax-ename->vla-object en) 'minpt 'maxpt))			; get polyline's bounding box
	       (setq pll (vlax-safearray->list minpt))							; polyline's lower-left point
	       (setq pur (vlax-safearray->list maxpt))							; polyline's upper-right point
	       (setq mid (mapcar '/ (mapcar '+ pll pur) '(2 2)))					; polyline's center point
	       
	       (setq nll (mapcar 'fix (mapcar '/ (mapcar '- mid pll) grd)))				; number of cells fit to lower-left quadrand in both directions '(n m)
	       (setq pnt (mapcar '+ (mapcar '- mid (mapcar '* nll grd)) (mapcar '/ grd '(2. 2.))))	; get lower-left point from number of cells.
	       
	       (setq o (if (= (rem (car nll) 2)	 ;returns the remainder of the first point /2		; if number of cells in x and y direction are both odd or both even
			      (rem (cadr nll) 2));returns the remainder of the second point /2		; set inition on/off state of circle existence
			 1										; 0 - no circle in cell
			 0))										; 1 - a circle to draw
	       (setq iy 0)
	       )
	
	(repeat (* 2 (cadr nll))							; repeat to move in y direction
	  
	  (setq o (- 1 o);change 1 to 0 to get parallel but when this is done they are no longer centered
		ix 0)
	  (repeat (* 2 (car nll))							; repeat to move in x direction
	    (if (= 1 (setq o (- 1 o)))							; each cell change 0/1/0 and if it's equal to 1
	      (circle (mapcar '+ pnt (list (* ix grx) (* iy gry))) (/ dia 2.)))		;  ... then draw a circle
	    (setq ix (1+ ix)))								; counter to move in x-dir by 1 cell
	  
	  (setq iy (1+ iy)
                )
          )
        )
    )
  )								; counter to move in y-dir by 1 cell
  (princ)
  )




Can someone tell me what I need to change or add to get it to do what I want??? 

 

Thanks to all!!!!

 

 

 

0 Likes
Accepted solutions (1)
1,013 Views
9 Replies
Replies (9)
Message 2 of 10

CodeDing
Advisor
Advisor

@Anonymous ,

 

I don't have time to experiment with it right now, but why not just create a circle then use ARRAYRECT command?

(of course implementing with autolisp)

 

Hopefully this gets you on the right track.

 

Best,

~DD

0 Likes
Message 3 of 10

Sea-Haven
Mentor
Mentor

Codeding as provided do an array then use erase F to remove excess circles that cross etc.

0 Likes
Message 4 of 10

ВeekeeCZ
Consultant
Consultant

Post a dwg to be clear.

0 Likes
Message 5 of 10

Anonymous
Not applicable

Hey @ВeekeeCZ

Thanks for chiming in, it was actually you who helped me with the original code you can see it and the thread >>>HERE<<< it works awesome by the way and have got it to work for me with most everything I need except the parallel pattern. I cant figure out what is making it not center in the polyline... 

 

Thanks to everyone for all the input

 

0 Likes
Message 6 of 10

ВeekeeCZ
Consultant
Consultant

Not really sure since you have too many figures in your drawing. But try and see...

 

(defun c:MPC (/ circle grx gry grd dia pll pur mid nll pnt oy ox iy iy)
  
  (defun circle (cen rad)
    (entmakex (list (cons 0 "CIRCLE")
		    (cons 10 cen)
		    (cons 40 rad))))
  
  (setq grx (cvunit 32 "mm" "inch")				; grid x distance
	gry (cvunit 32 "mm" "inch")				; grid y distance
	dia 0.315						; circle diameter
	
	grd (list grx gry)			; grid '(x y)
	)
  ;(setvar "clayer" "_Perforations")
  
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))								; multiple polyline selection
    
    (repeat (setq i (sslength ss))									;repeats the number of objects selccted
      (setq en (ssname ss (setq i (1- i))))								; polyline's ename
      (if (and (not (vla-getboundingbox (vlax-ename->vla-object en) 'minpt 'maxpt))			; get polyline's bounding box
	       (setq pll (vlax-safearray->list minpt))							; polyline's lower-left point
	       (setq pur (vlax-safearray->list maxpt))							; polyline's upper-right point
	       (setq mid (mapcar '/ (mapcar '+ pll pur) '(2 2)))					; polyline's center point
	       
	       (setq nll (mapcar 'fix (mapcar '/ (mapcar '- mid pll) grd)))				; number of cells fit to lower-left quadrand in both directions '(n m)
	       (setq pnt (mapcar '- mid (mapcar '* nll grd))) 						; get lower-left point from number of cells.
	       
	       (setq iy 0)
	       )
	
	(repeat (1+ (* 2 (cadr nll)))							; repeat to move in y direction
	  
	  (setq ix 0)
	  (repeat (1+ (* 2 (car nll)))							; repeat to move in x direction
	    (circle (mapcar '+ pnt (list (* ix grx) (* iy gry))) (/ dia 2.))		;  ... then draw a circle
	    (setq ix (1+ ix)))								; counter to move in x-dir by 1 cell
	  (setq iy (1+ iy))))))
  
  (princ)
  )
0 Likes
Message 7 of 10

Anonymous
Not applicable

Sorry, I wanted to make sure everything was in there just in case... 

It centers them perfectly, but on some sizes of the polyline its not removing the circles if its touching that selected polyline... any way of fixing that? 

You can see it in the dwg I have attached. Only one figure in this one lol 

0 Likes
Message 8 of 10

ВeekeeCZ
Consultant
Consultant
Accepted solution

 

(defun c:MPC (/ circle grx gry grd dia pll pur mid nll pnt oy ox iy iy)
  
  (defun circle (cen rad)
    (entmakex (list (cons 0 "CIRCLE")
		    (cons 10 cen)
		    (cons 40 rad))))
  
  (setq grx (cvunit 32 "mm" "inch")				; grid x distance
	gry (cvunit 32 "mm" "inch")				; grid y distance
	dia 0.315						; circle diameter
	
	grd (list grx gry)			; grid '(x y)
	)
  ;(setvar "clayer" "_Perforations")
  
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))								; multiple polyline selection
    
    (repeat (setq i (sslength ss))									;repeats the number of objects selccted
      (setq en (ssname ss (setq i (1- i))))								; polyline's ename
      (if (and (not (vla-getboundingbox (vlax-ename->vla-object en) 'minpt 'maxpt))			; get polyline's bounding box
	       (setq pll (vlax-safearray->list minpt))							; polyline's lower-left point
	       (setq pur (vlax-safearray->list maxpt))							; polyline's upper-right point
	       (setq mid (mapcar '/ (mapcar '+ pll pur) '(2 2)))					; polyline's center point
	       
	       (setq nll (mapcar 'fix (mapcar '- (mapcar '/ (mapcar '- mid pll) grd) '(0.5 0.5))))	; number of cells fit to lower-left quadrand in both directions '(n m)
	       (setq pnt (mapcar '- mid (mapcar '* nll grd))) 						; get lower-left point from number of cells.
	       
	       (setq iy 0)
	       )
	
	(repeat (1+ (* 2 (cadr nll)))							; repeat to move in y direction
	  
	  (setq ix 0)
	  (repeat (1+ (* 2 (car nll)))							; repeat to move in x direction
	    (circle (mapcar '+ pnt (list (* ix grx) (* iy gry))) (/ dia 2.))		;  ... then draw a circle
	    (setq ix (1+ ix)))								; counter to move in x-dir by 1 cell
	  (setq iy (1+ iy))))))
  
  (princ)
  )
Message 9 of 10

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... 

I have been trying to get the code to draw the circles in a parallel pattern and center them. ....


 

I think it can be simpler, not drawing each Circle but just figuring out how many rows and columns and where the lower-left one should go, and Arraying that:

(defun c:MPC (/ dia grd ss i en pll pur spcs)
  (setq
    dia 0.315 ; circle diameter
    grd (list (cvunit 32 "mm" "inch") (cvunit 32 "mm" "inch")); grid '(x y)
    osm (getvar 'osmode)
  ); setq
  (setvar 'osmode 0)
  (if (setq ss (ssget '((0 . "LWPOLYLINE")))); multiple polyline selection
    (repeat (setq i (sslength ss)); repeats the number of objects selccted
      (setq en (ssname ss (setq i (1- i)))); Polyline's ename
      (vla-getboundingbox (vlax-ename->vla-object en) 'minpt 'maxpt); bounding box
      (setq
        pll (vlax-safearray->list minpt); lower-left point
        pur (vlax-safearray->list maxpt); upper-right point
        spcs (mapcar 'fix (mapcar '/ (mapcar  '- pur pll (list dia dia)) grd)); spaces both directions
          ; max. span of Circle-centers for Circles to not cross bounding box '(x y) div. by grid
      ); setq
      (command
        "_.circle" (mapcar '+ pll (mapcar '/ (mapcar '- pur pll (mapcar '* grd spcs)) '(2 2))) (/ dia 2)
        "_.array" "_last" "" "_rectangular" (1+ (cadr spcs)) (1+ (car spcs)) (cadr grd) (car grd)
      ); command
    ); repeat
  ); if
  (setvar 'osmode osm)
  (princ)
); defun 

 

Kent Cooper, AIA
0 Likes
Message 10 of 10

Anonymous
Not applicable

Thanks for making it more simple Kent, that works great! 

0 Likes