Script to Generate Line Segments but Needs to Avoid Curved Lines and Multiple Line Segments.
Copy link to clipboard
Copied
Hello there!
I've developed a script to create line segments between adjacent selected objects. However, I'm facing two challenges: I want to eliminate curved segments, and I don't want multiple line segments to be generated on a single straight line with multiple anchor points. I've spent hours trying to solve this problem.
Can anyone provide some assistance? Your help is greatly appreciated!
if (app.documents.length > 0) {
var doc = app.activeDocument;
var strokeColor = new RGBColor();
strokeColor.red = 0;
strokeColor.green = 0;
strokeColor.blue = 0;
var strokeWidth = 0.5;
function areAnchorPointsEqual(point1, point2) {
return point1.anchor[0] === point2.anchor[0] && point1.anchor[1] === point2.anchor[1];
}
var selectedItems = doc.selection;
for (var i = 0; i < selectedItems.length; i++) {
var currentItem = selectedItems[i];
if (currentItem.typename === "GroupItem") {
// If the selected item is a group, iterate through its pageItems
for (var k = 0; k < currentItem.pageItems.length; k++) {
var groupItem = currentItem.pageItems[k];
processItem(groupItem);
}
} else {
processItem(currentItem);
}
}
function processItem(item) {
if (item.typename === "PathItem") {
var pathPoints = item.pathPoints;
for (var j = 0; j < pathPoints.length; j++) {
var startPoint = pathPoints[j];
var endPoint = pathPoints[(j + 1) % pathPoints.length];
if (!areAnchorPointsEqual(startPoint, endPoint)) {
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
newLine.strokeColor = strokeColor;
newLine.strokeWidth = strokeWidth;
}
}
} else if (item.typename === "CompoundPathItem") {
var compoundPathItems = item.pathItems;
for (var l = 0; l < compoundPathItems.length; l++) {
var pathItem = compoundPathItems[l];
var pathPoints = pathItem.pathPoints;
for (var j = 0; j < pathPoints.length; j++) {
var startPoint = pathPoints[j];
var endPoint = pathPoints[(j + 1) % pathPoints.length];
if (!areAnchorPointsEqual(startPoint, endPoint)) {
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
newLine.strokeColor = strokeColor;
newLine.strokeWidth = strokeWidth;
}
}
}
}
}
}
Thanks in Advance!
Explore related tutorials & articles
Copy link to clipboard
Copied
Ok, I managed to get it right for the first issue.
if (app.documents.length > 0) {
var doc = app.activeDocument;
var strokeColor = new RGBColor();
strokeColor.red = 0;
strokeColor.green = 0;
strokeColor.blue = 0;
var strokeWidth = 0.5;
function hasHandles(point) {
return (
point.leftDirection[0] !== point.anchor[0] || point.leftDirection[1] !== point.anchor[1] ||
point.rightDirection[0] !== point.anchor[0] || point.rightDirection[1] !== point.anchor[1]
);
}
var selectedItems = doc.selection;
for (var i = 0; i < selectedItems.length; i++) {
var currentItem = selectedItems[i];
if (currentItem.typename === "GroupItem") {
// If the selected item is a group, iterate through its pageItems
for (var k = 0; k < currentItem.pageItems.length; k++) {
var groupItem = currentItem.pageItems[k];
processItem(groupItem);
}
} else {
processItem(currentItem);
}
}
function processItem(item) {
if (item.typename === "PathItem") {
var pathPoints = item.pathPoints;
for (var j = 0; j < pathPoints.length; j++) {
var startPoint = pathPoints[j];
var endPoint = pathPoints[(j + 1) % pathPoints.length];
// Check if both anchor points have handles
if (hasHandles(startPoint) && hasHandles(endPoint)) {
continue; // Skip line segment creation
}
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
newLine.strokeColor = strokeColor;
newLine.strokeWidth = strokeWidth;
}
} else if (item.typename === "CompoundPathItem") {
var compoundPathItems = item.pathItems;
for (var l = 0; l < compoundPathItems.length; l++) {
var pathItem = compoundPathItems[l];
var pathPoints = pathItem.pathPoints;
for (var j = 0; j < pathPoints.length; j++) {
var startPoint = pathPoints[j];
var endPoint = pathPoints[(j + 1) % pathPoints.length];
// Check if both anchor points have handles
if (hasHandles(startPoint) && hasHandles(endPoint)) {
continue; // Skip line segment creation
}
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
newLine.strokeColor = strokeColor;
newLine.strokeWidth = strokeWidth;
}
}
}
}
}
one problem to go!
Copy link to clipboard
Copied
unfortunately, this one still did not get the final result I sought. if a line has an anchor point with outer handles which straightly connected to another anchor point with a handle out. it will refuse to create a line. sigh
Copy link to clipboard
Copied
What is the purpose of the script? Can you give the simplest example of what you are using it for?
Copy link to clipboard
Copied
Thanks for asking! So, the script's primary purpose is to simplify complex paths by converting straight segments into individual line segments while ignoring curved segments. This can be helpful for various tasks where you want to work with the straight parts of a path, such as simplifying complex shapes or creating basic geometric figures. It is also useful for checking optical characters for small bezier curves within straight lines. By creating line segments from straight path segments and ignoring the curved ones, you can easily identify and isolate areas where the characters or shapes might have unintentional curves. Soon it will be like guiding me in generating grids for straight lines.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Regarding the first point, this is what your original script gives me. If this is what you want, and you are not getting, I would focus on debugging this. One possibility is that the script doesn't handle items >1 group deep. Could you show the hierarchy of the items in an expanded layers panel?
Copy link to clipboard
Copied
Yes that mockup you've provided was using the initial code.
However, my current issue for now is to handle a straight line which has both 2 anchors which has handles out.
like this:
Anyway, below is the updated code that will run with groups, objects, and compound paths in selection
if (app.documents.length > 0) {
var doc = app.activeDocument;
var strokeColor = new RGBColor();
strokeColor.red = 0;
strokeColor.green = 0;
strokeColor.blue = 0;
var strokeWidth = 0.5;
function hasHandles(point) {
return (
point.leftDirection[0] !== point.anchor[0] || point.leftDirection[1] !== point.anchor[1] ||
point.rightDirection[0] !== point.anchor[0] || point.rightDirection[1] !== point.anchor[1]
);
}
var selectedItems = doc.selection;
for (var i = 0; i < selectedItems.length; i++) {
var currentItem = selectedItems[i];
if (currentItem.typename === "GroupItem") {
// If the selected item is a group, iterate through its pageItems
for (var k = 0; k < currentItem.pageItems.length; k++) {
var groupItem = currentItem.pageItems[k];
processItem(groupItem);
}
} else {
processItem(currentItem);
}
}
function processItem(item) {
if (item.typename === "PathItem") {
var pathPoints = item.pathPoints;
for (var j = 0; j < pathPoints.length; j++) {
var startPoint = pathPoints[j];
var endPoint = pathPoints[(j + 1) % pathPoints.length];
// Check if both anchor points have handles
if (hasHandles(startPoint) && hasHandles(endPoint)) {
continue; // Skip line segment creation
}
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
newLine.strokeColor = strokeColor;
newLine.strokeWidth = strokeWidth;
}
} else if (item.typename === "CompoundPathItem") {
var compoundPathItems = item.pathItems;
for (var l = 0; l < compoundPathItems.length; l++) {
var pathItem = compoundPathItems[l];
var pathPoints = pathItem.pathPoints;
for (var j = 0; j < pathPoints.length; j++) {
var startPoint = pathPoints[j];
var endPoint = pathPoints[(j + 1) % pathPoints.length];
// Check if both anchor points have handles
if (hasHandles(startPoint) && hasHandles(endPoint)) {
continue; // Skip line segment creation
}
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
newLine.strokeColor = strokeColor;
newLine.strokeWidth = strokeWidth;
}
}
}
}
}
Copy link to clipboard
Copied
The image below is the piece of lines in the condition where I need to keep generating a new line segment
Copy link to clipboard
Copied
Please also see the attached image below, the black outlines are straight segments. This is the exact end result I want. Hope these images helps. TIA
Copy link to clipboard
Copied
updated code,
// LINE SEGMENTS//
var doc = app.activeDocument;
//REMOVE THIS AFTER FIXED//
// Set stroke properties for the line segments
function setStrokeProperties(item) {
item.stroked = true; // Ensure it's stroked
item.strokeWidth = 2; // Set the stroke width
var newColor;
// Set the stroke color based on the document's color space
if (doc.documentColorSpace == DocumentColorSpace.RGB) {
newColor = new RGBColor();
newColor.red = 0;
newColor.green = 0;
newColor.blue = 0;
} else if (doc.documentColorSpace == DocumentColorSpace.CMYK) {
newColor = new CMYKColor();
newColor.cyan = 0;
newColor.magenta = 0;
newColor.yellow = 0;
newColor.black = 100;
}
item.strokeColor = newColor;
}
// Function to set the bezier handle properties
function BEZIER(point, pathPoints, index) {
// Check if the segment is a curve and avoid generating lines
if (
(point.leftDirection[0] !== point.anchor[0] || point.leftDirection[1] !== point.anchor[1]) &&
(point.rightDirection[0] !== point.anchor[0] || point.rightDirection[1] !== point.anchor[1])
) {
return true;
}
// Skip line segment creation of open paths
if (
(pathPoints.parent.closed === false) &&
(index === 0 || index === pathPoints.length - 1)
) {
return true;
}
// If none of the above conditions are met, generate lines
return false;
}
// Function to create line segments with a stable stroke color
function createLineSegment(startPoint, endPoint) {
var newLine = doc.pathItems.add();
newLine.setEntirePath([startPoint, endPoint]);
setStrokeProperties(newLine); // Set stroke properties and color
// Place the line segment in the "LINE SEGMENTS" layer
newLine.layer = lineLayer;
}
// Create a new layer for line segments
var lineLayer = doc.layers.add();
lineLayer.name = "LINE SEGMENTS";
// Function to process different item types
function processItem(item) {
if (item.typename === "GroupItem") {
var groupItems = item.pageItems;
for (var j = 0; j < groupItems.length; j++) {
processItem(groupItems[j]);
}
} else if (item.typename === "PathItem") {
var pathPoints = item.pathPoints;
if (pathPoints.length === 2) {
if (
(pathPoints[0].leftDirection[0] !== pathPoints[0].anchor[0] || pathPoints[0].leftDirection[1] !== pathPoints[0].anchor[1]) &&
(pathPoints[1].rightDirection[0] !== pathPoints[1].anchor[0] || pathPoints[1].rightDirection[1] !== pathPoints[1].anchor[1])
) {
return; // Skip line segment creation
}
createLineSegment(pathPoints[0].anchor, pathPoints[1].anchor);
} else {
for (var k = 0; k < pathPoints.length; k++) {
var startPoint = pathPoints[k];
var endPoint = pathPoints[(k + 1) % pathPoints.length];
if (BEZIER(startPoint, pathPoints, k) && BEZIER(endPoint, pathPoints, (k + 1) % pathPoints.length)) {
continue; // Skip line segment creation
}
createLineSegment(startPoint.anchor, endPoint.anchor);
}
}
} else if (item.typename === "CompoundPathItem") {
// Recursively process each path item within the compound path
for (var i = 0; i < item.pathItems.length; i++) {
processItem(item.pathItems[i]);
}
}
}
// Now, process the selected items to generate lines
var selectedItems = doc.selection;
for (var i = 0; i < selectedItems.length; i++) {
var currentItem = selectedItems[i];
if (currentItem.layer.name === "DUP") {
continue;
}
processItem(currentItem);
}
The last thing I want to remove is in red :

