Question
Hexagonal tiles script
The script overlays hexagonal tiles above a selected path. It's a little slow, but I've tested it to up to a thousand tiles and it got the job done (in four minutes). Still, proceed within reason, as there is no error handling. It's based on this script from the defunct Scriptographer plugin.

/*
* Hexagonal Tiles by Femke Blanco
* Beta 23/06/2021
* Based on Hexagonal Rasterizer by xoihazard @ http://scriptographer.org
* License: https://scriptographer.org/license/
*/
var grid;
(app.activeDocument.groupItems.add()).name = "group";
var Grid = function(cellShape, cellSize, contentScale) {
this.cellShape = cellShape;
this.cellSize = cellSize;
this.contentScale = contentScale;
this.originX;
this.originY;
};
Grid.prototype = {
draw: function() {
app.activeDocument.groupItems["group"].remove();
var group = app.activeDocument.groupItems.add();
group.name = "group";
var source1 = app.selection[0];
var source2 = source1.duplicate(app.activeDocument);
var fence = app.activeDocument.pathItems.rectangle(
source2.top + this.cellSize, source2.left - this.cellSize,
source2.width + this.cellSize * 2, source2.height + this.cellSize * 2,
);
fence.stroked = false;
fence.filled = false;
var hypotenuse = Math.sqrt(
Math.pow(fence.width / 2, 2) + Math.pow(fence.height / 2, 2)
);
var radius = Math.ceil(hypotenuse / this.cellSize * 4 / 3);
var bounds1 = source1.geometricBounds;
var bounds2 = fence.geometricBounds;
this.originX = bounds1[0] + (bounds1[2] - bounds1[0]) / 2;
this.originY = bounds1[1] + (bounds1[3] - bounds1[1]) / 2;
var size1 = this.cellSize / 2;
var size2 = this.cellSize * Math.sqrt(3) / 2;
var size3 = this.cellSize * 3 / 4;
var counter = 1;
for (var i = 0; i < radius; i++) {
var cells = this.getCells(i);
for (var j = 0; j < cells.length; j++) {
var paths = [];
cells[j].getXY();
if (cells[j].x > bounds2[0] && cells[j].x < bounds2[2] &&
cells[j].y < bounds2[1] && cells[j].y > bounds2[3]) {
if (this.cellShape.text == "Hexagon") {
paths[j] = app.activeDocument.pathItems.polygon(
cells[j].x, cells[j].y, size1, 6
);
paths[j].rotate(90);
} else if (this.cellShape.text == "Circle") {
paths[j] = app.activeDocument.pathItems.ellipse(
cells[j].y + size2 / 2, cells[j].x - size2 / 2,
size2, size2
);
} else {
paths[j] = app.activeDocument.pathItems.rectangle(
cells[j].y + size3 / 2, cells[j].x - size2 / 2,
size2, size3
);
}
if (this.testForOverlap(paths[j], source2)) {
if (this.contentScale != 1) {
paths[j].resize(
this.contentScale * 100, this.contentScale * 100
);
}
paths[j].moveToBeginning(group);
paths[j].name = counter;
counter += 1;
} else {
paths[j].remove();
}
}
}
}
fence.remove();
source2.remove();
app.redraw();
source1.selected = true;
},
getCells: function(radius) {
var cells = [];
var cell = new Cell(-radius/2, radius);
if (radius == 0) {
cells.push(cell);
} else {
for (var i = 0; i < 6; i++) {
for (var j = 0; j < radius; j++) {
cells.push(cell);
var addend = [[1, 0], [0.5, -1], [-0.5, -1], [-1, 0], [-0.5, 1], [0.5, 1]];
cell = new Cell(cell.dx + addend[i][0], cell.dy + addend[i][1]);
}
}
}
return cells;
},
testForOverlap: function(a, b) {
var path1 = a.duplicate();
var path2 = b.duplicate();
app.selection = null;
path1.selected = true;
path2.selected = true;
app.executeMenuCommand("group");
app.executeMenuCommand("Live Pathfinder Intersect");
app.executeMenuCommand("expandStyle");
app.executeMenuCommand("ungroup");
var n = app.selection.length;
while (app.selection[0]) {
app.selection[0].remove();
}
return n == 1;
}
};
var Cell = function(dx, dy) {
this.dx = dx;
this.dy = dy;
this.x;
this.y;
};
Cell.prototype = {
getXY: function() {
this.x = grid.originX + this.dx * grid.cellSize * Math.sqrt(3) / 2;
this.y = grid.originY + this.dy * grid.cellSize * 3 / 4;
}
};
var UI = function() {
var w = new Window("dialog", "Hexagon Tiles");
var group1 = w.add("group");
group1.orientation = "row";
var group2 = group1.add("group");
group2.preferredSize.width = 81;
group2.orientation = "column";
group2.alignChildren = ["right","center"];
group2.add("statictext", undefined, "Cell Shape");
group2.add("statictext", undefined, "Cell Size");
group2.add("statictext", undefined, "Content Scale");
var group3 = group1.add("group");
group3.preferredSize.width = 81;
group3.orientation = "column";
group3.alignChildren = ["left","center"];
var drop1 = group3.add(
"dropdownlist", undefined, ["Hexagon", "Circle", "Rectangle"]
);
drop1.selection = 0;
var cellShape = drop1.selection;
drop1.onChange = function () {
cellShape = drop1.selection;
};
var edittext1 = group3.add("edittext", undefined, "10");
edittext1.characters = 7;
edittext1.active = true;
var cellSize = Number(edittext1.text);
edittext1.onChange = function () {
cellSize = Number(edittext1.text);
};
var edittext2 = group3.add("edittext", undefined, "1");
edittext2.characters = 7;
var contentScale = Number(edittext2.text);
edittext2.onChange = function () {
contentScale = Number(edittext2.text);
};
var button1 = w.add("button", undefined, "Preview");
button1.onClick = function () {
grid = new Grid(cellShape, cellSize, contentScale);
grid.draw();
};
var button2 = w.add("button", undefined, "Done");
button2.onClick = function () {
w.close();
};
w.show();
};
if (app.selection.length == 1 && app.selection[0].typename == "PathItem") {
UI();
} else {
alert("Select one path item.");
}
