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

Easy way to draw connections between dots?

Community Beginner ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

I like this image and don't want to straight up copy/steal it. Is there a way to EASILY get all dots and all possible connections drawn in Illustrator? I'd hate to manually draw hundreds of lines. Thanks for any help you might offer. 

 group-size-churchhealth-wiki.png

TOPICS
Draw and design , Scripting

Views

1.8K

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

correct answers 2 Correct answers

Guide , Feb 02, 2021 Feb 02, 2021
var n = prompt("Enter number ≥ 3", 3, "Number of points");
var d = app.activeDocument.artboards[0].artboardRect;
var paths = app.activeDocument.pathItems;
var polygon1 = paths.polygon(d[2]/2, d[3]/2, 250, n);
var points1 = polygon1.pathPoints;
for (var i = 0; i < points1.length; i++) {
    for (var j = i + 1; j < points1.length; j++) {   
        var line1 = paths.add();
        var points2 = [points1[i].anchor, points1[j].anchor];
        line1.setEntirePath(points2);
    }
}
polygon1.remove();

Votes

Translate

Translate
Valorous Hero , Feb 02, 2021 Feb 02, 2021

Yea, just use the Radial repeat to make enough circles, make sure to expand the object so you get the Radial Repeat split up into circle paths, and use this script, it should do what you want:

 

 

 

 

 

#target illustrator
function test () {

	var doc = app.activeDocument;
	var sel = doc.selection;
	var pathUuids = [];
	var thisItem;
	for (var i = 0; i < sel.length; i++) {
		thisItem = sel[i];
		pathUuids.push(thisItem.uuid);
	}
	var thisPath, thisOtherPath, newLine;
	var newGroup = doc.groupIte
...

Votes

Translate

Translate
Adobe
Guide ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

var n = prompt("Enter number ≥ 3", 3, "Number of points");
var d = app.activeDocument.artboards[0].artboardRect;
var paths = app.activeDocument.pathItems;
var polygon1 = paths.polygon(d[2]/2, d[3]/2, 250, n);
var points1 = polygon1.pathPoints;
for (var i = 0; i < points1.length; i++) {
    for (var j = i + 1; j < points1.length; j++) {   
        var line1 = paths.add();
        var points2 = [points1[i].anchor, points1[j].anchor];
        line1.setEntirePath(points2);
    }
}
polygon1.remove();

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
Valorous Hero ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

You beat me to it! lol!

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 Beginner ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Nice and clean! I just put that text into a .js file and ran the script. The prompt for how many points to create was a nice touch!

 

My output: 

Daniel5E28_0-1612310562721.png

 

 

Glad I got to select two right answers.

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
Valorous Hero ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Yea, just use the Radial repeat to make enough circles, make sure to expand the object so you get the Radial Repeat split up into circle paths, and use this script, it should do what you want:

 

 

 

 

 

#target illustrator
function test () {

	var doc = app.activeDocument;
	var sel = doc.selection;
	var pathUuids = [];
	var thisItem;
	for (var i = 0; i < sel.length; i++) {
		thisItem = sel[i];
		pathUuids.push(thisItem.uuid);
	}
	var thisPath, thisOtherPath, newLine;
	var newGroup = doc.groupItems.add();
	newGroup.name = "Lines";
	for (var i = 0; i < pathUuids.length; i++) {
		thisPath = doc.getPageItemFromUuid(pathUuids[i]);
		for (var j = 0; j < pathUuids.length; j++) {
			thisOtherPath = doc.getPageItemFromUuid(pathUuids[j]);
			newLine = newGroup.pathItems.add();
			newLine.setEntirePath([
				[
					thisPath.left + (thisPath.width / 2),
					thisPath.top - (thisPath.height / 2)
				],
				[
					thisOtherPath.left + (thisOtherPath.width / 2),
					thisOtherPath.top - (thisOtherPath.height / 2)
				],
			]);
			newLine.stroked = true;
		}
	}

};
test();

 

 

 

 

 

It is not handling duplicated lines, so there are a lot of duplicated lines on top of each other as the lines are drawn from each and every shape to each other shape - like in the case of the triangle it would make 6 lines total. Matter of fact, it also draws a line to itself - haha.

 

Silly-V_0-1612301162228.png

Hey, you can come up with cool jellyfish art using some effects on this.

Silly-V_0-1612301556913.png

 

 

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 ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Great use of uuids. Thanks for showing! - Mark

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 ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Nice scripts! To get rid of the duplicate lines, you could make it a Live Paint object and expand the Live Paint.

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 ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Ton, is it possible to make it a Live Paint object via script? I'd like to try it when I get a chance.

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 ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Sorry, you are asking the wrong person, I know how to use scripts, but unfortunately not how to write them 😞

I let Femkeblanco or Silly-V answer that one.

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 ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Well you got me thinking about it, so thanks for that! 🙂

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
Guide ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

You can make a live paint group from selected pathItems with

 

app.executeMenuCommand("Make Planet X");

 

but you will have to paint it manually with the Live Paint Bucket tool.  Apart from expanding the live paint group ( app.executeMenuCommand("Expand Planet X") ), there's not much you can do with scripting. 

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 Beginner ,
Feb 02, 2021 Feb 02, 2021

Copy link to clipboard

Copied

Wonderful. Thanks. 

 

Took me a little to figure out the Radial thing. Got that. Then, saved your code in file with .js extension.

Last thing I had to do was select all my yellow circles before running script. Got the desired result! Thanks!

 

Daniel5E28_0-1612310366945.png

 

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 ,
Feb 03, 2021 Feb 03, 2021

Copy link to clipboard

Copied

This seemed like a good exercise so I figured I'd also give it a shot:

 

// You can set direct property values for the appearance here:
var options = {
    anchor: {
        size: 20,
        filled: true,
        stroked: true,
        strokeWidth: 2,
        fillColor: [255, 0, 0]
    },
    line: {
        stroked: true,
        strokeWidth: 2,
        strokeCap: StrokeCap.ROUNDENDCAP,
        strokeColor: "#ff0000"
    }
};

/**
 * Utilities
 */
Array.prototype.forEach = function (callback) {
    for (var i = 0; i < this.length; i++) callback(this[i], i, this);
};
if (!Array.isArray) 
    Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === "[object Array]";
    };
RGBColor.prototype.create = function (params) {
    if (/string/i.test(typeof params)) {
        var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(params);
        this.red = parseInt(result[1], 16);
        this.green = parseInt(result[2], 16);
        this.blue = parseInt(result[3], 16);
        return this;
    } else if (Array.isArray(params)) {
        this.red = +params[0];
        this.green = +params[1];
        this.blue = +params[2];
        return this;
    }
};
function get(type, parent) { 
    parent = parent ? parent : app.activeDocument;
    var result = [];
    if (!parent[type]) return [];
    for (var i = 0; i < parent[type].length; i++)
        result.push(parent[type][i]);
    return result;
}

/**
 * Main functions
 */
get('selection', app).forEach(function (pathItem) {
    var group = app.activeDocument.groupItems.add();
    get('pathPoints', pathItem).forEach(function (pathPoint, i, list) {
        drawLinesFrom(pathPoint, list.slice(i + 1), group);
        setAppearance(group.pathItems.ellipse(
            pathPoint.anchor[1] + options.anchor.size / 2,
            pathPoint.anchor[0] - options.anchor.size / 2,
            options.anchor.size,
            options.anchor.size
        ), 'anchor');
    })
    pathItem.remove();
})
function setAppearance(shape, type) {
    for (var key in options[type])
        shape[key] = (/Color$/.test(key))
            ? new RGBColor().create(options[type][key])
            : options[type][key];
}
function drawLinesFrom(point, list, parent) {
    list.forEach(function (sibling) {
        var shape = parent.pathItems.add();
        shape.setEntirePath([point.anchor, sibling.anchor]);
        setAppearance(shape, 'line');
    })
}

 

 

 I've found myself doing things like this often but I'd personally rather just draw a polygon or closed shape, not the circles. So this script works off the currently selected shapes:

ice_screenshot_20210203-183332.png

Converts them with configurable options to set stroke/fill colors, line widths, size of anchor shapes, etc:

ice_screenshot_20210203-183339.png

It also groups the resulting shapes, removes the original path, and doesn't produce any redundant paths (triangle here is 6 paths, 3 lines + 3 ellipses):

ice_screenshot_20210203-183422.png

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 ,
Feb 03, 2021 Feb 03, 2021

Copy link to clipboard

Copied

I'm learning a lot from this thread! Thanks everyone.

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

Not a script guy. All I can tell is that it didn't work. Was it something I said? Wrong latitude?

tromboniator_0-1612428877340.png

 

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

Just edited, try now. Illustrator can be picky when it comes to prototypes.

 

Not really meant for an ellipse since this doesn't account for bezier handles, that's going to produce the same as a 4-sided polygon.

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

Yup, that's got it, thank you.

 

Peter

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

@Inventsablethis is really fun code to read and there's some super cool stuff going on in there, so thanks for sharing! If you don't mind a random question for my learning... Does the line

return result || [];

in the get function need the || [] ? At a quick glance I would think that result would always be an empty array at least. Is there something I'm missing?

- Mark

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

Good catch! This is actually a simplified version of a much larger recursive function that I normally use, I'd copy/pasted then deleted a large chunk of it when I'd placed it in here since we don't need recursion or the full function, though now that you mention it, that's probably unnecessary even in that one.

 

There's probably a few other mistakes or ways it could be improved still. I tend to write in Typescript, not .jsx, so I normally use ES6 syntax like arrow functions which is why my code looks a lot different than what people normally post like nested functions inside other function arguments and prototype extensions.

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

That's cool. I'm interested in Typescript. Have you managed to get set up so that you can code in TypeScript/ES6 and generate ExendScript code from it automatically?

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
Valorous Hero ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

Yea, that's how it work is you get your typescript set up and then you can open VSCode in that folder and ensure the ts.config file is in there - then you can run the command tsc which generates the normal js files from it, but make sure that your ts config has the setting to output ES3-compatible code. They can start at ES5 by default. The file that is put out will have some edits and possibly make the code more verbose - but at that point you're not worried about that because the script will run as fast as ever and the code you really care about now will be your typescript code. (However, as seen proven by @Inventsable , to paste things for non-TS users takes some back-translation).
The running of the tsc command can be made to automatically run when a ts file is saved, but I've not done that yet, so maybe I'll ask @Inventsable on what the steps are.

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 ,
Feb 04, 2021 Feb 04, 2021

Copy link to clipboard

Copied

LATEST

Thanks Silly-V, I found it: compileOnSave in tsconfig.json.

{
    "compileOnSave": true,
    "compilerOptions": {
        "target": "es3",
        "module": "CommonJS",
        "outDir": "out",
        "sourceMap": true
    }
}

 

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