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

Easy way to draw connections between dots?

Community Beginner ,
Feb 02, 2021 Feb 02, 2021

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
3.6K
Translate
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();
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
...
Translate
Adobe
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();
Translate
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

You beat me to it! lol!

Translate
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

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.

Translate
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

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

 

 

Translate
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

Great use of uuids. Thanks for showing! - Mark

Translate
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

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

Translate
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

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

Translate
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

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.

Translate
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

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

Translate
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

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. 

Translate
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

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

 

Translate
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

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

Translate
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

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

Translate
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

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

 

Translate
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

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.

Translate
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

Yup, that's got it, thank you.

 

Peter

Translate
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

@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

Translate
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

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.

Translate
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

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?

Translate
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

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.

Translate
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

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

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

 

Translate
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
New Here ,
Jun 04, 2025 Jun 04, 2025
LATEST

does anyone know a website that automatically does this? i've been trying to but cant for the life of me

Translate
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