Generating Point Grids from Custom Shaped Closed Polylines

Generating Point Grids from Custom Shaped Closed Polylines

adaptacad
Advocate Advocate
1,288 Views
13 Replies
Message 1 of 14

Generating Point Grids from Custom Shaped Closed Polylines

adaptacad
Advocate
Advocate

I've been trying to do this process for a while now, but I keep returning to the manual approach. I have some closed polylines and the idea is to select them to create an internal grid of points, defining the distances both on the X and Y axis. It is important to note that the Array command is not suitable for my purpose, since I intend to store the points in a list-type variable. I would be very grateful if anyone could provide me with guidance, as I have already sought help elsewhere without success.

 

adaptacad_0-1692195081934.png

 

0 Likes
Accepted solutions (1)
1,289 Views
13 Replies
Replies (13)
Message 2 of 14

Kent1Cooper
Consultant
Consultant

When the X and Y spacings are equal, as they appear to be in your image, it shouldn't be hard.  Use a Hatch pattern of zero-length lines at 1-unit spacings [see the DOTS-SQ pattern defined >here<].  Hatch in the outline, using the spacing you want as the Hatch pattern scale factor.  Adjust the Hatch's origin to suit the positioning you want within the outline.  Explode the Hatch.  You will be left with a bunch of zero-length Line objects, which a routine could easily-enough replace with Points, and put the locations into a list variable.

 

If there are a limited number of ratios you ever use for the X vs. Y spacings, Hatch patterns for each such ratio could be defined, to use in the same way.  If the ratio could be anything, that's more complicated -- maybe the easiest thing would be to have a routine create a Hatch pattern for the purpose, and apply it.

Kent Cooper, AIA
Message 3 of 14

komondormrex
Mentor
Mentor

and these are autocad point entities?

Message 4 of 14

Kent1Cooper
Consultant
Consultant

@komondormrex wrote:

and these are autocad point entities?


They certainly can be, if PDMODE = 33.

Kent Cooper, AIA
Message 5 of 14

komondormrex
Mentor
Mentor

fine.

Message 6 of 14

komondormrex
Mentor
Mentor

maybe this be of help. still has gaps thou.

;*****************************************************************************************************************************************************************

;	komondormrex, apr 2023

;*****************************************************************************************************************************************************************

(defun c:do_ename_boundary_array (/ boundary_ename block_ename boundary_extents_list block_extents_list x_block_distance y_block_distance
									x_number_default y_number_default x_number y_number array_block_item to_stay_object_list
									offset_boundary offset_variant init_get
								 )
	(vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
	(setq boundary_ename (car (entsel "\nSelect boundary to fill: "))
		  block_ename (car (entsel "\nSelect entity to fill boundary with: "))
	)
	(vla-getboundingbox (vlax-ename->vla-object boundary_ename)  'llc 'ruc)
	(setq boundary_extents_list (list (vlax-safearray->list llc) (vlax-safearray->list ruc)))
	(vla-getboundingbox (vlax-ename->vla-object block_ename)  'llc 'ruc)
	(setq block_extents_list (list (vlax-safearray->list llc) (vlax-safearray->list ruc))
		  init_get (initget 5)
		  x_block_distance (getreal (strcat "\nEnter gap between entities by X axis (Item width = "
		  									(rtos (- (caadr block_extents_list) (caar block_extents_list)))
											": <0>"
									)
						   )
		  init_get (initget 5)
		  y_block_distance (getreal (strcat "\nEnter gap between entities by Y axis (Item width = "
											(rtos (- (cadadr block_extents_list) (cadar block_extents_list)))
		  									": <0>"
									)
						   )
		  x_number_default (fix (/ (+ (- (caadr boundary_extents_list) (caar boundary_extents_list)) x_block_distance)
		  						   (+ (- (caadr block_extents_list) (caar block_extents_list)) x_block_distance)
							    )
						   )
		  y_number_default (fix (/ (+ (- (cadadr boundary_extents_list) (cadar boundary_extents_list)) x_block_distance)
		  						   (+ (- (cadadr block_extents_list) (cadar block_extents_list)) y_block_distance)
							    )
						   )
		  init_get (initget 5)
		  x_number (getint (strcat "\nEnter number of entities by X axis <"
		  						   (itoa x_number_default)
								   "> :"
						   )
				   )
		  init_get (initget 5)
		  y_number (getint (strcat "\nEnter number of entities by Y axis <"
		  						   (itoa y_number_default)
								   "> :"
						   )
				   )
		  array_block_item (vla-copy (vlax-ename->vla-object block_ename))
	)
	(vla-move array_block_item (vlax-3d-point (trans (car block_extents_list) 1 0))
						   	   (vlax-3d-point (list (+ (caar boundary_extents_list)
						   				 			   (* 0.5 (- (- (caadr boundary_extents_list) (caar boundary_extents_list))
						   				 						 (+ (* x_number (- (caadr block_extents_list) (caar block_extents_list)))
						   				 							 (* (1- x_number) x_block_distance)
						   				 						 )
						   				 					  )
						   				 			   )
						   			  	 			)
						   			  	 			(+ (cadar boundary_extents_list)
						   			  				   (* 0.5 (- (- (cadadr boundary_extents_list) (cadar boundary_extents_list))
						   			  					 		 (+ (* y_number (- (cadadr block_extents_list) (cadar block_extents_list)))
						   			  								(* (1- y_number) y_block_distance)
						   			  							 )
						   			  						  )
						   			  					)
						   			  	 			)
						   				       )
						   	   )
	)
  	(setq array_list (vlax-safearray->list (vlax-variant-value (vla-arrayrectangular array_block_item
											 										 y_number
											 										 x_number
											 										 1
		                                 	 										 (+ y_block_distance (- (cadadr block_extents_list) (cadar block_extents_list)))
											 										 (+ x_block_distance (- (caadr block_extents_list) (caar block_extents_list)))
											 										 0
															   )
										 )
					 )
	)
	(vla-regen (vla-get-activedocument (vlax-get-acad-object)) acactiveviewport)
	(if (> x_number x_number_default)
			(progn
				(setq offset_value (* 0.5 (- x_number x_number_default) (+ (- (caadr block_extents_list) (caar block_extents_list)) x_block_distance)))
				(if (< (vla-get-area (setq offset_boundary (car (vlax-safearray->list (vlax-variant-value (setq offset_variant (vla-offset (vlax-ename->vla-object boundary_ename) offset_value)))))))
					   (vla-get-area (vlax-ename->vla-object boundary_ename))
					)
						(progn
							(mapcar 'vla-erase (vlax-safearray->list (vlax-variant-value offset_variant)))
							(setq offset_boundary (car (vlax-safearray->list (vlax-variant-value (vla-offset (vlax-ename->vla-object boundary_ename) (* -1 offset_value))))))
						)
				)
			)
	)
	(setq to_stay_object_list (mapcar 'vlax-ename->vla-object
									   (vl-remove-if 'listp
													  (mapcar 'cadr
													  		   (ssnamex (ssget "_wp"
															   				   (mapcar 'cdr
																			   			(vl-remove-if-not '(lambda (dxf_group) (= 10 (car dxf_group)))
																			   							   (if (null offset_boundary)
																										   			(entget boundary_ename)
																													(entget (vlax-vla-object->ename offset_boundary))
																										   )
																						)
																			   )
																		)
															   )
													  )
									   )
							   )
	)
	(foreach object array_list
		(if (not (member object to_stay_object_list))
				(vla-erase object)
		)
	)
	(if offset_boundary (vla-erase offset_boundary))
	(vla-erase array_block_item)
	(vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
	(princ)
)

;*****************************************************************************************************************************************************************
Message 7 of 14

adaptacad
Advocate
Advocate

Precisely what I require! However, there's no need to add any entities to the DWG file. My aim is to store the values within a variable, following this format: `(list '(x y z) '(x y z) ...)`, where the value of z always remains zero.

0 Likes
Message 8 of 14

adaptacad
Advocate
Advocate

 


@komondormrex wrote:

maybe this be of help. still has gaps thou.


This involves multiple input entries and still doesn't completely fill the polyline space. The objective is to distribute points throughout the region delimited by the polyline, and there's no need to add entities – generating a variable with the points is sufficient.

0 Likes
Message 9 of 14

Kent1Cooper
Consultant
Consultant

For example, at equal X and Y, and assuming closed objects that you will select, in fairly simple terms:

 

(defun C:GPEXY ; = Grid of Points at Equal X & Y spacings
  (/ ss n ent pt)
  (setvar 'hporiginmode 5); origin at center of bounding box
  (setvar 'hpname "DOTS-SQ")
  (setvar 'pdmode 33); open circles
  (setvar 'pdsize -2); 2% of viewport size
  (command-s "_.HATCH" "" pause "")
  (command "_.explode" (entlast))
  (setq ss (ssget "_P")); the resulting Lines
  (repeat (setq n (sslength ss))
    (setq ent (ssname ss (setq n (1- n))))
    (command "_.point" "_non" (setq pt (cdr (assoc 10 (entget ent)))))
    (entdel ent)
    (setq ptlist (cons pt ptlist))
  ); repeat
  (prin1)
)

 

It requires you to have that DOTS-SQ pattern available, and asks for the spacing within the Hatch command.  It could ask for that in advance instead, could have Layer control, and other things.

 

It leaves the list of locations as points in the 'ptlist' variable, which is not localized so it survives after the command.

 

Read about the System Variables it sets, and edit accordingly.  Maybe you want it to allow you to change the origin [and/or rotation?] before Exploding, and other refinements are possible, such as confirming that you picked closed object(s), or allowing picking in areas instead of selecting objects, etc.

Kent Cooper, AIA
Message 10 of 14

Kent1Cooper
Consultant
Consultant

@adaptacad wrote:

.... The objective is to distribute points throughout the region delimited by the polyline, and there's no need to add entities – generating a variable with the points is sufficient.


Then you can replace the (repeat) function in mine with:

 

  (repeat (setq n (sslength ss))
    (setq
      ent (ssname ss (setq n (1- n)))
      pt (cdr (assoc 10 (entget ent)))
      ptlist (cons pt ptlist)
    ); setq
    (entdel ent)
  ); repeat

and forget the PD.... System Variable settings.

 

Kent Cooper, AIA
Message 11 of 14

adaptacad
Advocate
Advocate

The result is as expected; however, having to load the hatch in my project is not convenient. The way I currently do it is similar. I would like to calculate the points without needing to insert the hatches.

0 Likes
Message 12 of 14

Kent1Cooper
Consultant
Consultant

[You don't need to "load the hatch in [your] project," if that's really what you mean, but need only to put it [once] in any folder location where AutoCAD knows to look, and it will be available to all projects.  They're not like Linetypes, which do need to be loaded into each drawing where they're used.  I'm working on something that can create one for any XY spacings you specify -- under development.]

Kent Cooper, AIA
Message 13 of 14

Sea-Haven
Mentor
Mentor
Accepted solution
Message 14 of 14

adaptacad
Advocate
Advocate

Thank you very much everyone, the answer in the other community solved my question

0 Likes