1) Press Ctrl+F12 and select zebra_from_lines.jsx
script file.
2) Select two or more open paths.
3) Click Combine paths by pairs button.

Just copy-paste this code to zebra_from_lines.jsx
file using your preffered text editor (in my case it is Notepad++):
//@target illustrator
//@targetengine main
// zebra_from_lines.jsx
// This script connects selected open paths by pairs.
// The paths sequence order follows their z-order.
// Made specially for https://graphicdesign.stackexchange.com/q/116396/128685
// by oshatrk, 2018.
(function(undefined) {
var combineSelected = function() {
var haveIntersection = function (p1, p2, p3, p4) {
var p1x = p1.anchor[0], p1y = p1.anchor[1];
var p2x = p2.anchor[0], p2y = p2.anchor[1];
var p3x = p3.anchor[0], p3y = p3.anchor[1];
var p4x = p4.anchor[0], p4y = p4.anchor[1];
var d = (p1x - p2x) * (p4y - p3y) - (p1y - p2y) * (p4x - p3x);
var da = (p1x - p3x) * (p4y - p3y) - (p1y - p3y) * (p4x - p3x);
var db = (p1x - p2x) * (p1y - p3y) - (p1y - p2y) * (p1x - p3x);
var ta = da / d;
var tb = db / d;
return (ta >= 0 && ta <= 1 && tb >= 0 && tb <= 1);
};
var combinePaths = function (obj1, obj2) {
var pps1 = obj1.pathPoints;
var pps2 = obj2.pathPoints;
var n1 = pps1.length;
var n2 = pps2.length;
pps1[0].pointType = PointType.CORNER;
pps1[0].leftDirection = pps1[0].anchor;
pps1[n1-1].pointType = PointType.CORNER;
pps1[n1-1].rightDirection = pps1[n1-1].anchor;
pps2[0].pointType = PointType.CORNER;
pps2[0].leftDirection = pps2[0].anchor;
pps2[n2-1].pointType = PointType.CORNER;
pps2[n2-1].rightDirection = pps2[n2-1].anchor;
if(haveIntersection(pps1[0],pps2[0],pps1[n1-1],pps2[n2-1])) {
for(var i = 0; i < n2; ++i) {
var p1 = pps1.add();
var p2 = pps2[i];
p1.anchor = p2.anchor;
p1.rightDirection = p2.rightDirection;
p1.leftDirection = p2.leftDirection;
p1.pointType = p2.pointType;
}
} else {
for(var i = n2-1; i >= 0; --i) {
var p1 = pps1.add();
var p2 = pps2[i];
p1.anchor = p2.anchor;
p1.rightDirection = p2.leftDirection;
p1.leftDirection = p2.rightDirection;
p1.pointType = p2.pointType;
}
}
obj2.remove();
obj1.closed = true;
};
var sel = app.selection;
if( sel === undefined || sel.length === undefined) return;
for(var i = 0, n = sel.length; i < n; ++i) {
var obj1 = sel[i];
if(obj1.pathPoints === undefined || obj1.closed == true) continue;
var obj2 = undefined;
for(++i; i < n; ++i) {
obj2 = sel[i];
if(obj2.pathPoints !== undefined || obj2.closed == true) {
combinePaths(obj1, obj2);
break;
}
}
}
}
var bt = new BridgeTalk;
bt.target = BridgeTalk.appSpecifier; // "illustrator-[current version]"
bt.body = '('+combineSelected+')();';
var w = new Window (
"palette {text:'Zebra from lines',\
btn: Button {text:'Combine paths by pairs'}\
}");
w.btn.onClick = function() {
bt.send();
};
w.show();
})();
Note: This script is quite simple one. So it appologizes all paths are simple and are in correct z-order. Feel free to adapt this script with your requirements.
It was tested with multiple versions of Illustrator: CS5, CS6 and CC 2019.
There are few tricks shown in this script:
The targetengine
directive is used to prevent immediate deletion of a palette window. Without it the palette is just garbage collected within a second.
All the processing code is placed into one function (in this case it is in combineSelected
variable).
Then this function is stringified and sended via BridgeTalk to Illustrator which evaluates this string.
It looks this process is the only working way to execute something from palette window.
Also when a function is executed in this way it can not be debugged step by step in ExtendScript Toolkit.
So for development it is more usefull at first to write a script without such modeless window.
There are two options at this point: witout UI at all, or use modal dialog window (just use "dialog"
instead of "palette"
in Window()
constructor).
And after the script becomes stable the modeless palette can be implemented as in this script.
Usefull links: