@Anonymous wrote:
@ВeekeeCZ ,
I did just notice the holes are being placed at .63 and not a true 16mm On Center which is a big deal.
Any way of tweaking that?
Yeah, I know. I've simplified that hoping that you where searching for an algorithm and this little things you will able to adjust by yourself...
Anyway, I rewrote the code little bit and added commentaries. It also should help you to make further adjustments.
(defun c:Holes (/ 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 0.32 ; grid x distance
gry 0.32 ; grid y distance
dia (cvunit 8 "mm" "inch") ; circle diameter
grd (list grx gry) ; grid '(x y)
)
(if (setq ss (ssget '((0 . "LWPOLYLINE")))) ; multiple polyline selection
(repeat (setq i (sslength ss)) ; go thru selection set
(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) ; if number of cells in x and y direction are both odd or both even
(rem (cadr nll) 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)
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)
)
About the pattern - there is o variable in the code which stops every second circle from drawing. It changes its value 0-1-0-1-0-1.... across whole row, than makes one more step before next row... and again going thru a row changing 1-0-1-0...
;-----------------
There are a lot of mapcar's in the code. I might look difficult to understand... but all those are used very similar way...
Here is one example of used pattern:
(mapcar '+ '(1 2) (list 5 7))
which is: mapcar 'function one-list second-list
all it does is applying the function to each member of lists respectively.
(mapcar '+ '(1 2) (list 5 7)) === '(1+5 2+7) === '(6 9), which is the result.
The reason for mapcar usage soooo many times is to do the same operation for x and y coordinates at same time.
See this function from the actual code:
(setq pnt (mapcar '+
(mapcar '-
mid
(mapcar '*
nll
grd))
(mapcar '/
grd
'(2. 2.))))
then the same rewritten just for X coordinate:
(setq pnt-x (+
(-
mid-x
(*
nll-x
grd-x))
(/
grd-x
2.)))
...then you will have to the similar with Y coordinate... or just use a mapcar.
Once you understand to mapcar, I guess would be easy to understand the whole code and adjust that in future by your needs.
BTW If you feel like Kent's code is more understandable to you, please go ahead and use it. I did a quick test with about 70000 holes... and the performance is just about similar, you probably won't notice a difference - thought my routine is about 10% faster than Kent's.
HTH and have fun! Cheers!