Get all the vertices from a general path

I'm working with a PathBasedVisionShape. I want to get the coordinates for all of the points on the line. It doesn't matter if the coordinates are relative to the shape object or the container.

I can get the general path from the component using a test button like this:

path = event.source.parent.getComponent('Test Path').shape
print type(path)

Output:

java.awt.geom.GeneralPath

path.currentPoint accurately gives me the last point in the path relative to the content container: Point2D.Float[995.0, 690.0]
If I get the iterator and cycle through the segments, I see the correct number of iterations:

iterator = path.getPathIterator(None)

iDontTrustWhileLoops = 0
while not iterator.done and iDontTrustWhileLoops < 50:
	iDontTrustWhileLoops += 1
	iterator.next()

print iDontTrustWhileLoops

Output: 5

According to the documentation for the Path2D iterator, I should be able to get the coordinates by passing a double into the currentSegment method, but the script blew up when I did this.

TypeError: currentSegment(): 1st arg can't be coerced to float[], double[]

A bit of trial and error revealed that a list of length 2 or a tuple of floats works:

coords = (0.0, 0.0) # or [0.0, 0.0]
while not iterator.done:
	print iterator.currentSegment(coords)
	print coords
	iterator.next()

...but the input values are not modifed.

Output:

0
(0.0, 0.0)
1
(0.0, 0.0)
1
(0.0, 0.0)
1
(0.0, 0.0)
1
(0.0, 0.0)

I'm stumped at the moment. Does anybody know how to do this?

Edit:
Here is a screenshot of the test line:
image

iterator.currentSegment(coords) returns the type of movement, so:

# iterator.SEG_MOVETO = 0
# iterator.SEG_LINETO = 1
# iterator.SEG_QUADTO = 2
# iterator.SEG_CUBICTO = 3
# iterator.SEG_CLOSE = 4

...according to the outputs in my case, the iterator simply moves to the starting position and then uses LINETO to paint each segment of the line.

I figured it out. The argument needs to be Java array.instead of a Python list

Example:

from jarray import zeros # for creating an array.array

# Get the iterator from the general path within the shape
iterator = event.source.parent.getComponent('Test Path').shape.getPathIterator(None)

# Create a list to hold the coordinates,
# ...and generate a Java array for the iterator's currentSegment method
allCoordinates = []
coords = zeros(2, 'd')  #(number of zeros to create, type 'd' for double)

# Iterate through all of the segments and get the ending points
# iterator.currentSegment(coords) returns the type:
#	iterator.SEG_MOVETO = 0 # Array size 2 
#	iterator.SEG_LINETO = 1 # Array size 2 
#	iterator.SEG_QUADTO = 2 # Array size 4 (2 coordinate sets)
#	iterator.SEG_CUBICTO = 3 # Array size 6 (3 coordinate sets)
#	iterator.SEG_CLOSE = 4 # Array size 2 
while not iterator.done:
	iterator.currentSegment(coords)
	allCoordinates.append(list(coords))
	iterator.next()

for coordinate in allCoordinates:
	print coordinate

Output:

[80.0, 660.0]
[100.0, 640.0]
[525.0, 660.0]
[950.0, 640.0]
[995.0, 690.0]

If there is a more intuitive way to accomplish this, please let me know.

Edit: Added a list to contain the currentSegment outputs, so they can actually be used in the script somewhere, and added comments that include useful stuff I learned while researching the problem that could come in handy with other applications of this code.

1 Like

I had a bit of fun while developing my path mapping function...

...and I'll betcha didn't know that you could do this usng a PathBasedVisionShape:
MerryChrismas

Merry Christmas everybody!
ChristmasTemplate.zip (15.8 KB)

5 Likes