This repository has been archived on 2023-03-25. You can view files and clone it, but cannot push or open issues or pull requests.
mightyscape-1.1-deprecated/extensions/fablabchemnitz/strip_line/strip_line.py
2021-07-23 02:36:56 +02:00

234 lines
7.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import math
import codecs
import inkex
from inkex.paths import Path
from geometry.Circle import Circle
from geometry.Vertex import Vertex
from geometry.Triangle import Triangle
from geometry.Plus import Plus
from geometry.Minus import Minus
from lxml import etree
ALL=".//"
def fixTo360(radian):
if radian <0:
return math.pi*2.0+radian
return radian
def widenDir(start,end):
d21x = end.x - start.x;
d21y = end.y - start.y;
return fixTo360(-math.atan2(d21x, d21y));
def lineDir(start,end):
d21x = end.x - start.x;
d21y = end.y - start.y;
#inkex.errormsg("d21y "+str(d21y)+" d21x "+str(d21x)+" d21y/d21x"+str(d21y/d21x))
rad=math.atan2(d21y, d21x);
#inkex.errormsg(u"Line direction"+str(math.degrees(rad)))
return fixTo360(rad)
#radian<The assumption is that 0 will not come
def invert(radian):
return radian-math.pi
def fixWithin90(radian):
if math.fabs(radian)>math.pi/2.0: #I want you to be +-90 (forward direction)
return invert(radian)
return radian
def fixOver90(radian):
if math.fabs(radian)<math.pi/2.0:
return invert(radian)
return radian
def fixWithinAb180(radian):
if math.fabs(radian)<math.pi:
return radian
if radian <0:
return math.pi*2.0+radian
return radian-math.pi*2.0
def printRadian(fp,message,radian):
fp.write(message+":"+str(math.degrees(radian))+"\n")
def stripline(bone,linewidth,logname):
fp = codecs.open(logname, "w", "utf_8" )
i = 0;
segmentNum = len(bone)-1;
elementNum=(segmentNum*2+2)*5
outVertexArray = []
#4 vertices per line segment+Extra amount added to the end point
vertexIdx = 0
#First apex
start =bone[0]
end =bone[1]
lastRad=0
lastUsedRad=0
radY = widenDir(start,end)
lineRad=lineDir(start,end)
fp.write(u"0th vertex")
printRadian(fp,u"lineRad",lineRad)
originalRad=radY
#Indicates the direction of bending
cornerDir=radY-lastRad
printRadian(fp,u"radY",radY)
diffRad=0
printRadian(fp,u"diffRad:",diffRad)
printRadian(fp,u"radY-lineRad:",radY-lineRad)
printRadian(fp,u"sin(radY-lineRad:)",math.sin(radY-lineRad))
adjustedRad=radY
printRadian(fp,u"The first drawing angle",adjustedRad)
fp.write("\n")
direction=True
lastRad=radY
lastUsedRad=adjustedRad
LEFT=Vertex(linewidth,0)
RIGHT=Vertex(-linewidth,0)
#variable
v=Vertex(0,0)
v.set(LEFT)
v.rotate(adjustedRad)
flag = False #if radY< 0 else False
outVertexArray.append([start+v,flag])
v.set(RIGHT)
v.rotate(adjustedRad)
flag = True# if radY< 0 else False
outVertexArray.append([start+v,flag])
for i in range(1,segmentNum):
start =bone[i]
end =bone[i+1]
originalRad = widenDir(start,end)
radY=(originalRad+lastRad)*0.5#Values from 0 to 360 degrees
fp.write(str(i)+u"Th vertex")
diffRad=(originalRad-lastRad)
if math.fabs(math.fabs(diffRad)-math.pi)<=(45.0*math.pi/180.0):#To erase the pointed triangle when making a U-turn
printRadian(fp,u"Correction of U-turn point:diffRad",diffRad)
fp.write(u"Difference"+str(math.fabs(math.fabs(diffRad)-math.pi)))
radY=originalRad
printRadian(fp,u"radY:",radY)
printRadian(fp,u"diffRad:",diffRad)
printRadian(fp,u"radY-lineRad:",radY-lineRad)
printRadian(fp,u"sin(radY-lineRad:)",math.sin(radY-lineRad))
#Twist prevention
if math.sin(radY-lineRad)>0:
radY=invert(radY)
lineRad=lineDir(start,end)
printRadian(fp,u"lineRad:",lineRad)
adjustedRad=radY
printRadian(fp,u"diffRad:",diffRad)
squareRad=lineDir(start,end)
#printRadian(u"squareRad",squareRad)
printRadian(fp,u"Drawing angle after conversion:",radY)
v.set(LEFT)
#1〜√2 I want you to be in the range
coef=(1+0.41421356237*math.fabs(math.sin(diffRad*0.5)))
fp.write("coef="+str(coef))
v.x*=coef
v.rotate(adjustedRad)
flag = False
outVertexArray.append([start+v,flag])
v.set(RIGHT)
v.x*=coef
v.rotate(adjustedRad)
flag = True
outVertexArray.append([start+v,flag])
lastRad=originalRad
lastUsedRad=adjustedRad
fp.write("\n")
#The last round
fp.write(str(i)+u"Th vertex")
adjustedRad=originalRad
printRadian(fp,u"Last drawing angle:",originalRad)
v.set(LEFT)
v.rotate(adjustedRad)
flag = False# if originalRad< 0 else False
outVertexArray.append([end+v,flag])
v.set(RIGHT)
v.rotate(adjustedRad)
flag = True# if originalRad< 0 else False
outVertexArray.append([end+v,flag])
fp.close()
return outVertexArray
class StripLine(inkex.EffectExtension):
def add_arguments(self, pars):
pars.add_argument("--linewidth", type=int, default="10", help="Line thickness")
pars.add_argument("--logfilename", default="10", help="Log file name")
def effect(self):
linewidth=self.options.linewidth
# Get the main root element SVG
svg = self.document.getroot()
pathlist = svg.findall(ALL+"{"+inkex.NSS['svg']+"}path")
for path in pathlist:
if path == None:
inkex.errormsg("Please write the path! !")
#Get vertex coordinates of path
vals=path.path.to_arrays()
bone=[]
for cmd,vert in vals:
#Sometimes there is an empty, so countermeasures against it
if len(vert) != 0:
bone.append(Vertex(vert[0],vert[1]))
if len(bone) != 0:
outVertexArray=stripline(bone,linewidth,self.options.logfilename)
pointer=0
for t in range(len(outVertexArray)-2):
tri=Triangle(outVertexArray[pointer][0],outVertexArray[pointer+1][0],outVertexArray[pointer+2][0])
stripstr=tri.toSVG()
color2="blue"
if outVertexArray[pointer][1]:
color="blue"
else:
color="red"
pointer+=1
attributes={"points":stripstr,
"style":"fill:"+color2+";stroke:"+color2+";stroke-width:"+str(linewidth/3),"fill-opacity":"0.5"}
pth =etree.Element("polygon",attributes)
svg.append(pth)
pointer=0
#Draw a point indicating +-
for t in range(len(outVertexArray)):
if outVertexArray[pointer][1]:
point=Plus(outVertexArray[pointer][0].x,outVertexArray[pointer][0].y,linewidth/3)
color="blue"
else:
point=Minus(outVertexArray[pointer][0].x,outVertexArray[pointer][0].y,linewidth/3)
color="red"
if pointer==0:
color="#6f0018"#Dark red
point.appendToSVG(color,svg)
#svg.append(Circle.toSVG(outVertexArray[pointer][0].x,outVertexArray[pointer][0].y,linewidth/3,color,0))
pointer+=1
pointer=0
pathstr="M "
for t in range(len(outVertexArray)):
pathstr+=str(outVertexArray[pointer][0].x)+" "+str(outVertexArray[pointer][0].y)+" "
pointer+=1
att3={"d":pathstr,"r":"1","fill":"none","stroke-width":"1","stroke":"white"}
pt=etree.Element("path",att3)
if __name__ == '__main__':
StripLine().run()