Script to Randomly Distribute Objects


#1

I have 16 hexagonal tile units as in the image. Cloning these 16 tiles, form unwanted repetitions.

I need a script to randomly select tiles from this set of 16 hexagons and distribute them to create a wall of X hexagons horizontal and Y hexagons vertical.

Each hexagon has a radius of 4.3275 cm’s (7.5cm from side to side) and there is a grout width of 0.3 cm between each hexagon.

I can’t think of any other method but scripting. I’ll appreciate any help it is not a tedious work.

Thank you


#2

of course it should be a geometry plugin (or a simple object plugin)
of course it would be better to use Substitute Modifier, Xref objects or Xref scene for source geometry

but…

here is a simple snippet how to make the job with using nodes from Selection Set with name “honey
if there is no this set the built-in hexagon shape will be used:

try(destroydialog Honeycomber) catch()
rollout Honeycomber "Honeycomber" width:191
(
	spinner seed_sp "Seed: " type:#integer range:[0, 1e9, 0] fieldwidth:48 enabled:off

	spinner width_sp "Width: " type:#integer range:[1, 100, 4] fieldwidth:48 offset:[0,6] 
	spinner height_sp "Height: " type:#integer range:[1, 100, 4] fieldwidth:48 
	spinner cellsize_sp "Cell Size: " type:#float range:[0, 1e9, 40] fieldwidth:48 offset:[0,6]
	spinner spacing_sp "Spacing: " type:#float range:[0, 1e9, 3] fieldwidth:48 
	
	button make_bt "Make" width:182 offset:[0,4]

	on make_bt pressed do undo "Make Honeycombs" on
	(
		try(delete $honey*) catch()
		
		ss = if not keyboard.altpressed  do selectionSets["honey"]
		nodes = if ss != undefined do join #() ss
		
		w = width_sp.value
		h = height_sp.value
		r = cellsize_sp.value
		t = (cos 30) * r
		
		s = spacing_sp.value
				
		for z = 0 to h-1 do
		(
			for x = 0 to w-1 do
			(
				px = (2*t + s) * (x + (mod z 2)/2)
				pz = (1.5 * r + s*(tan 60)/2) * z	
					
				tm = matrix3 1
					
				if (random 0 1) == 1 do prescale tm [-1,1,1] -- flip x	
				if (random 0 1) == 1 do prescale tm [1,-1,1] -- flip y	
				prerotateZ tm ((random 0 5) * 60) -- spin
				
				rotateX tm 90	
				rotateY tm 30	
				
				translate tm [px,0,pz]  
								
				node = if nodes != undefined then
				(
					instance nodes[random 1 nodes.count] wirecolor:green name:#honey
				)
				else
				(
					ngon sides:6 radius:10 scribe:1 wirecolor:orange name:#honey 
				)
				sc = node.max.x - node.min.x

				node.transform = tm
				scale node (r*2/[sc,sc,sc]) 
				
				node
			)
		)
	)
	
	on make_bt rightclick do undo "Delete All" on try(delete $honey*) catch()

)
createdialog Honeycomber

It’s free to be modified or improved. Volunteers are welcome


#3

I randomize:

  1. object index from list
  2. horizontal flip
  3. vertical flip
  4. number rotations on 60 degrees

#4

I want to note that just five different objects are enough so that there are no two identical neighbors


#5

Thank you very much indeed.
The script works brilliantly without a “honey” selection set, but with my hexagon objects in “honey” selection, I couldn’t manage to get a value that distributes correctly. Can you have a look at the file. (Originally created in Max 2018, and also saved as 2015)

I created the tiles in the following scene with System Units set to centimeters, and the scene I’ll be using this set of tiles is in mm. I’ve checked in both scenes but the result is the same.

This is my result. And if I change the Cell Size, the grout size increases , too.

final edit: I have aligned the scale values of the newly created hexagons to the original - Everything is good.
Nevertheless, I still wish to know what is causing this scaling and how to correct it.

Is it this and how can I correct it:

scale node (r*2/[sc,sc,sc])

Final Edit: I’ve just deleted the line and it seems to work :smiley: