List of transformations in transform attribute are now parsed correctly.

pull/20/merge^2
alphanoob1337 2017-04-10 09:19:14 +02:00
parent 3a2cd2c7a0
commit fb49d5b752
3 changed files with 54 additions and 30 deletions

View File

@ -93,35 +93,47 @@ def svg2paths(svg_file_location,
def parse_trafo(trafo_str):
"""Returns six matrix elements for a matrix transformation for any valid SVG transformation string."""
value_str = trafo_str.split('(')[1].split(')')[0]
values = list(map(float, value_str.split(',')))
if 'translate' in trafo_str:
x = values[0]
y = values[1] if (len(values) > 1) else 0.
return [1., 0., 0., 1., x, y]
elif 'scale' in trafo_str:
x = values[0]
y = values[1] if (len(values) > 1) else 0.
return [x, 0., 0., y, 0., 0.]
elif 'rotate' in trafo_str:
a = values[0]*np.pi/180.
x = values[1] if (len(values) > 1) else 0.
y = values[2] if (len(values) > 2) else 0.
am = np.dot(np.array([np.cos(a), -np.sin(a), 0., np.sin(a), np.cos(a), 0., 0., 0., 1.]).reshape((3, 3)),
np.array([1., 0., -x, 0., 1., -y, 0., 0., 1.]).reshape((3, 3)))
am = list(np.dot(np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)), am).reshape((9, ))[:6])
am = am[::3]+am[1::3]+am[2::3]
return am
elif 'skewX' in trafo_str:
a = values[0]*np.pi/180.
return [1., 0., np.tan(a), 1., 0., 0.]
elif 'skewY' in trafo_str:
a = values[0]*np.pi/180.
return [1., np.tan(a), 0., 1., 0., 0.]
else:
while len(values) < 6:
values += [0.]
return values
trafos = trafo_str.split(')')[:-1]
trafo_matrix = np.array([1., 0., 0., 0., 1., 0., 0., 0., 1.]).reshape((3, 3)) # Start with neutral matrix
for trafo_sub_str in trafos:
trafo_sub_str = trafo_sub_str.lstrip(', ')
value_str = trafo_sub_str.split('(')[1]
values = list(map(float, value_str.split(',')))
if 'translate' in trafo_sub_str:
x = values[0]
y = values[1] if (len(values) > 1) else 0.
trafo_matrix = np.dot(trafo_matrix,
np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)))
elif 'scale' in trafo_sub_str:
x = values[0]
y = values[1] if (len(values) > 1) else 0.
trafo_matrix = np.dot(trafo_matrix,
np.array([x, 0., 0., 0., y, 0., 0., 0., 1.]).reshape((3, 3)))
elif 'rotate' in trafo_sub_str:
a = values[0]*np.pi/180.
x = values[1] if (len(values) > 1) else 0.
y = values[2] if (len(values) > 2) else 0.
am = np.dot(np.array([np.cos(a), -np.sin(a), 0., np.sin(a), np.cos(a), 0., 0., 0., 1.]).reshape((3, 3)),
np.array([1., 0., -x, 0., 1., -y, 0., 0., 1.]).reshape((3, 3)))
am = np.dot(np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)), am)
trafo_matrix = np.dot(trafo_matrix, am)
elif 'skewX' in trafo_sub_str:
a = values[0]*np.pi/180.
trafo_matrix = np.dot(trafo_matrix,
np.array([1., np.tan(a), 0., 0., 1., 0., 0., 0., 1.]).reshape((3, 3)))
elif 'skewY' in trafo_sub_str:
a = values[0]*np.pi/180.
trafo_matrix = np.dot(trafo_matrix,
np.array([1., 0., 0., np.tan(a), 1., 0., 0., 0., 1.]).reshape((3, 3)))
else: # Assume matrix transformation
while len(values) < 6:
values += [0.]
trafo_matrix = np.dot(trafo_matrix,
np.array([values[::2], values[1::2], [0., 0., 1.]]))
trafo_list = list(trafo_matrix.reshape((9,))[:6])
return trafo_list[::3]+trafo_list[1::3]+trafo_list[2::3]
def parse_node(node):
"""Recursively iterate over nodes. Parse the groups individually to apply group transformations."""

View File

@ -1,5 +1,5 @@
<?xml version="1.0" ?>
<svg id="rootn" version="1.1" baseProfile="full" width="1100" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg id="rootn" version="1.1" baseProfile="full" width="1250" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
<path
id="p0"
style="stroke:#ff0000;stroke-width:2."
@ -78,4 +78,15 @@
d="m 0.,0. 100.,0." />
</g>
</g>
<path
id="p14"
style="stroke:#ff0000;stroke-width:2."
d="m 1100.,100. 100.,0." />
<g id="concatenated" transform="translate(1150.,150.),rotate(-90.)">
<path
id="p15"
style="stroke:#ff0000;stroke-width:2."
d="m 0.,0. 100.,0." />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -11,4 +11,5 @@ class TestSvg2pathsGroups(TestCase):
self.assertTrue((len(paths) % 2) == 0)
for i in range(len(paths)//2):
print(i * 2)
self.assertTrue(len(paths[i * 2].intersect(paths[i * 2 + 1])) > 0, 'Path '+str(i * 2)+' does not intersect path '+str(i * 2 + 1)+'!')