mightyscape-1.2/extensions/fablabchemnitz/mutual_cut_line/mutual_cut_line.py

90 lines
2.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
'''
Mutual Cut Line
This Inkscape extension will take 2 selected line and cut them both
at their intersection point.
Only the first segment of a multi-segment line will be used.
'''
import inkex
from inkex.paths import Path
from math import *
from lxml import etree
def error(message):
inkex.errormsg(message)
exit()
class MutualCutLine(inkex.EffectExtension):
def effect(self):
if len(self.svg.selected.items()) != 2:
error('Please select 2 lines before running this effect.')
line = []
numPaths = 0
for id, path in self.svg.selected.items():
if path.tag == inkex.addNS('path','svg'):
numPaths += 1
style = path.get('style')
np = [style]
p = Path(path.get('d')).to_arrays()
for sp in p:
np.append([sp[1][0], sp[1][1]])
line.append(np)
path.getparent().remove(path) #after cutting we remove the original lines
if numPaths != 2:
error('Please select 2 lines before running this effect.')
# Extract style and points for the first 2 line segments.
astyle = line[0][0]
bstyle = line[1][0]
a1x = line[0][1][0]
a1y = line[0][1][1]
a2x = line[0][2][0]
a2y = line[0][2][1]
b1x = line[1][1][0]
b1y = line[1][1][1]
b2x = line[1][2][0]
b2y = line[1][2][1]
# Calculate intersection point.
adx = a1x - a2x
ady = a1y - a2y
bdx = b1x - b2x
bdy = b1y - b2y
denom = adx * bdy - ady * bdx
numa = (a1x * a2y - a1y * a2x)
numb = (b1x * b2y - b1y * b2x)
x_num = numa * bdx - numb * adx
y_num = numa * bdy - numb * ady
if denom == 0:
error('Lines don\'t intersect in a single point.')
x = x_num / denom
y = y_num / denom
# TODO: Verify that the 2 segments intersect.
# Current code will connect outside the line segments.
# Create 4 line segments from the intersection point.
svg_path = inkex.addNS('path','svg')
sega1 = etree.SubElement(self.svg.get_current_layer(), svg_path)
sega1.set('d', 'M '+str(x)+','+str(y)+' L '+str(a1x)+','+str(a1y))
sega1.set('style', astyle)
sega2 = etree.SubElement(self.svg.get_current_layer(), svg_path)
sega2.set('d', 'M '+str(x)+','+str(y)+' L '+str(a2x)+','+str(a2y))
sega2.set('style', astyle)
segb1 = etree.SubElement(self.svg.get_current_layer(), svg_path)
segb1.set('d', 'M '+str(x)+','+str(y)+' L '+str(b1x)+','+str(b1y))
segb1.set('style', bstyle)
segb2 = etree.SubElement(self.svg.get_current_layer(), svg_path)
segb2.set('d', 'M '+str(x)+','+str(y)+' L '+str(b2x)+','+str(b2y))
segb2.set('style', bstyle)
if __name__ == '__main__':
MutualCutLine().run()