figuring out distances between lines

I am working on a project and trying to use applescript to complete it. It will be faster for me to do this process manually, but I want to learn how to use applescript to solve the problem.

I have a number of indesign template files. They all have crop marks and such on them. Some documents have 1 page others have 2 pages. I’m not concerned about that. On page 1 of the document there could be specific lines that I am interested in - these are the lines that show where lamination has to go between. They will be the ONLY lines that are of weight 2 pts. I am storing the ids of the lines in a list:

set MyLamLines to (every graphic line whose stroke weight is 2)
set NumLines to number of items in MyLamLines

i know that I can store each of the 4 coords of the given line using:


set MyBoundsFirst to geometric bounds of item j of MyLamLines
set MyBoundsSecond to geometric bounds of item (j+1) of MyLamLines

and I know that IF i only had two lines in MyLamLines I could easily figure out the distance between them.

my complicated question is: When I have more than 2 lines in MyLamLines what is the best way to figure out which lines go together, and what are the distances between them.

see here for a screen shot:
https://www.dropbox.com/s/dit0lrcijodokbj/Screen%20Shot%202016-09-25%20at%2010.57.10%20PM.png?dl=0

I think some of the guidelines needed are:

  1. is the line a vertical or horizontal line. Lines can only pair together if they are oriented the same direction
  2. if line 1 and line 2 are being compared, and they are not of the same orientation, then go on to the next line.
  3. if line 1 and the next line are the same orientation, then do they have the same X1 value?

This is where I start getting confused. Is there an easier way to accomplish this? Is this enough information to understand what I am asking?

I love learning the correct way to do these things, but I need to be able to understand what I’m doing too.

thanks for any help…
david

OK, so no one gave me help… maybe this query will get more traction.

Let’s say I have a list that was created by this:

set MyLamLines to geometric bounds of (every graphic line whose stroke weight is 2)

This results in a list that could look like this:

9.75, 8.23, 9.75, 8.48
0.25, 8.23, 0.25, 8.48
9.75, -0.18, 9.75, 0.23
0.25, -.018, 0.25, 0.23
9.65, 7.84, 9.91, 7.84
9.65, 0.65, 9.91, 0.65
0.21, 7.84, 0.46, 7.84
0.21, 0.65. 0.46, 0.65

These numbers represent the (y1, x1, y2, x2) of eight different lines.
I am trying to pair lines up. In this case, I can look at line 1 & line 2 and tell that
a) they are horizontal lines (because the y1 an y2 numbers are the same
b) they also have the same x1 and x2 values, which means they are parallel to each other and essentially in the same position on the sheet, but are set apart by the difference of Line2(y1) - Line1(y1), which in this case equals 9.5

I am looking for a way to “pair up” the lines in this manner and determine the distance apart the lines are.

In the sample above, it’s convenient that the first two lines pair up, the second two pair up, and so on, but that’s not always going to be the case.

If I do the calculations manually, I see that lines 1 & 2 are 9.5 apart, lines 3 & 4 are 9.5 apart, lines 5 & 6 are 7.19 apart and lines 7 & 8 are 7.19 apart.

Is there a logical way to figure this out using applescript? See my description above for more information.
thanks
david

Hope I’ve understood the problem!

-- Customisable insertion sort by Arthur J. Knapp and Nigel Garvey.
on CustomInsertionSort(theList, l, r, customiser)
	script o
		property comparer : me
		property slave : me
		property lst : theList
		
		on isrt(l, r)
			set u to item l of o's lst
			repeat with j from (l + 1) to r
				set v to item j of o's lst
				if (comparer's isGreater(u, v)) then
					set here to l
					set item j of o's lst to u
					repeat with i from (j - 2) to l by -1
						tell item i of o's lst
							if (comparer's isGreater(it, v)) then
								set item (i + 1) of o's lst to it
							else
								set here to i + 1
								exit repeat
							end if
						end tell
					end repeat
					set item here of o's lst to v
					slave's rotate(here, j)
				else
					set u to v
				end if
			end repeat
		end isrt
		
		on isGreater(a, b)
			(a > b)
		end isGreater
		
		on rotate(a, b)
		end rotate
	end script
	
	set listLen to (count theList)
	if (listLen > 1) then
		if (l < 0) then set l to listLen + l + 1
		if (r < 0) then set r to listLen + r + 1
		if (l > r) then set {l, r} to {r, l}
		
		if (customiser's class is record) then set {comparer:o's comparer, slave:o's slave} to (customiser & {comparer:o, slave:o})
		
		o's isrt(l, r)
	end if
	
	return -- nothing.
end CustomInsertionSort

-- Plug-in list comparer for CustomInsertionSort().
-- Assumptions: The lists to be compared represent {y1, x1, y2, x2} line coordinates and there are equal numbers of pairs of horizontal and vertical lines being sorted.
-- Sort goal: all horizontal lines, sorted inversely on vertical then horizontal values, followed by all vertical lines, sorted inversely on horizontal then vertical values.  :)
script lineMatcher
	on isGreater(a, b)
		set {y1a, x1a, y2a, x2a} to a
		set {y1b, x1b, y2b, x2b} to b
		
		set aHorizontal to (y1a = y2a)
		set bHorizontal to (y1b = y2b)
		if (aHorizontal = bHorizontal) then
			if (aHorizontal) then
				if (x1a = x1b) then return (y1a < y1b)
				return (x1a < x1b)
			else
				if (y1a = y1b) then return (x1a < x1b)
				return (y1a < y1b)
			end if
		else
			return (bHorizontal)
		end if
	end isGreater
end script


-- Randomised list of David's line coordinates.
set MyLamLines to {{0.21, 0.65, 0.46, 0.65}, {9.65, 7.84, 9.91, 7.84}, {9.75, -0.18, 9.75, 0.23}, {9.65, 0.65, 9.91, 0.65}, {0.21, 7.84, 0.46, 7.84}, {0.25, 8.23, 0.25, 8.48}, {9.75, 8.23, 9.75, 8.48}, {0.25, -0.18, 0.25, 0.23}}

-- Sort lists 1 thru -1 of MyLamLines using the lineMatcher customiser given above.
CustomInsertionSort(MyLamLines, 1, -1, {comparer:lineMatcher})

-- Prepare a list of records, each record containing a pair of matched "line" lists and their distance apart.
set lineCount to (count MyLamLines)
set halfCount to lineCount div 2
set matchList to {}
repeat with i from 1 to lineCount by 2
	-- Get each matched pair of line lists.
	set {line1, line2} to items i thru (i + 1) of MyLamLines
	-- Calculate their distance apart from their first or second items, depending on which half of MyLamLines they're in.
	set j to i div halfCount + 1
	set distance to (item j of line1) - (item j of line2)
	set end of matchList to {|line coords|:{line1, line2}, distance:distance}
end repeat

matchList
--> {{|line coords|:{{9.75, 8.23, 9.75, 8.48}, {0.25, 8.23, 0.25, 8.48}}, distance:9.5}, {|line coords|:{{9.75, -0.18, 9.75, 0.23}, {0.25, -0.18, 0.25, 0.23}}, distance:9.5}, {|line coords|:{{9.65, 7.84, 9.91, 7.84}, {9.65, 0.65, 9.91, 0.65}}, distance:7.19}, {|line coords|:{{0.21, 7.84, 0.46, 7.84}, {0.21, 0.65, 0.46, 0.65}}, distance:7.19}}

Hi. You never responded to Nigel, so I can’t tell if his approach was understood, or if you solved your own problem. The question was interesting, so I played around with it and came up with something that works in the application context. While you asked for the distances, I intuited that you really want to visualize the crop areas, so I created frames for demo purposes.

This entire exercise could be avoided by proper document setup. If you’re creating a template, you should assign the crop lines a script label, rather than having to figure out their partners.

#Categorize by orientation
set {vert, horz} to {{}, {}}
tell application "Adobe InDesign CS3"'s document 1 to repeat with thisLine in (get graphic lines whose stroke weight is 2) --or whatever
	set {OriginY, OriginX, DestinationY, DestinationX} to thisLine's geometric bounds
	if DestinationY > OriginY then --is vertical
		if vert does not contain DestinationX then set vert's end to DestinationX
	else --is horizontal
		if horz does not contain DestinationY then set horz's end to DestinationY
	end if
end repeat
------------------------------------------------------------------------------------------------------------------------
#Rearrange
set {vert, horz} to {my sort(vert), my sort(horz)}
------------------------------------------------------------------------------------------------------------------------
#Test placement
tell application "Adobe InDesign CS3"'s document 1 to repeat with columnVal from 1 to (count vert) by 2
	set {leftmost, rightmost} to {vert's item columnVal, vert's item (columnVal + 1)}
	repeat with rowVal from 1 to (count vert) * 2 by 2
		make rectangle with properties {geometric bounds:{horz's item rowVal, leftmost, horz's item (rowVal + 1), rightmost}}
	end repeat
end repeat
------------------------------------------------------------------------------------------------------------------------


on sort(thelist)
	set AppleScript's text item delimiters to linefeed
	(do shell script "echo " & (thelist as text)'s quoted form & " | sort")'s paragraphs
end sort

*Edited for clarity and to remove an unnecessary step