• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
2

Hexagonal tiles script

Guide ,
Jun 23, 2021 Jun 23, 2021

Copy link to clipboard

Copied

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. 

 

Untitled.png

 

/*
 * 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.");
}

 

TOPICS
Scripting

Views

758

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Jun 24, 2021 Jun 24, 2021

Copy link to clipboard

Copied

ah the great Scriptographer, brings back memories.

 

I was getting a somewhat inconsistent error at the line that removes the "group", I added a try/catch to fix

 

    draw: function() {
        try {
            app.activeDocument.groupItems["group"].remove();
        }
        catch (e) {}
        var group = app.activeDocument.groupItems.add();

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 27, 2021 Jun 27, 2021

Copy link to clipboard

Copied

Redrawing app.redraw(); the interface always slows down the script. If there is no way to do without it here, I suggest using this trick. Remember the current state of the view and temporarily bring it to full screen. Then there is no interface left on the user's monitor, which is updated every time.

button1.onClick = function () {
    var userView = app.activeDocument.views[0].screenMode;
    app.activeDocument.views[0].screenMode = ScreenMode.FULLSCREEN;
    grid = new Grid(cellShape, cellSize, contentScale);
    grid.draw();
    app.activeDocument.views[0].screenMode = userView;
};

 speed-test.jpg

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 27, 2021 Jun 27, 2021

Copy link to clipboard

Copied

LATEST

also, if you switch to Outline View, the screen redraws faster.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines