summaryrefslogtreecommitdiff
path: root/renderer/support/pogojig/inkscape/cubicsuperpath.py
diff options
context:
space:
mode:
Diffstat (limited to 'renderer/support/pogojig/inkscape/cubicsuperpath.py')
-rw-r--r--renderer/support/pogojig/inkscape/cubicsuperpath.py174
1 files changed, 174 insertions, 0 deletions
diff --git a/renderer/support/pogojig/inkscape/cubicsuperpath.py b/renderer/support/pogojig/inkscape/cubicsuperpath.py
new file mode 100644
index 0000000..a594660
--- /dev/null
+++ b/renderer/support/pogojig/inkscape/cubicsuperpath.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+"""
+cubicsuperpath.py
+
+Copyright (C) 2005 Aaron Spike, aaron@ekips.org
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""
+from . import simplepath
+from math import *
+
+def matprod(mlist):
+ prod=mlist[0]
+ for m in mlist[1:]:
+ a00=prod[0][0]*m[0][0]+prod[0][1]*m[1][0]
+ a01=prod[0][0]*m[0][1]+prod[0][1]*m[1][1]
+ a10=prod[1][0]*m[0][0]+prod[1][1]*m[1][0]
+ a11=prod[1][0]*m[0][1]+prod[1][1]*m[1][1]
+ prod=[[a00,a01],[a10,a11]]
+ return prod
+def rotmat(teta):
+ return [[cos(teta),-sin(teta)],[sin(teta),cos(teta)]]
+def applymat(mat, pt):
+ x=mat[0][0]*pt[0]+mat[0][1]*pt[1]
+ y=mat[1][0]*pt[0]+mat[1][1]*pt[1]
+ pt[0]=x
+ pt[1]=y
+def norm(pt):
+ return sqrt(pt[0]*pt[0]+pt[1]*pt[1])
+
+def ArcToPath(p1,params):
+ A=p1[:]
+ rx,ry,teta,longflag,sweepflag,x2,y2=params[:]
+ teta = teta*pi/180.0
+ B=[x2,y2]
+ if rx==0 or ry==0 or A==B:
+ return([[A[:],A[:],A[:]],[B[:],B[:],B[:]]])
+ mat=matprod((rotmat(teta),[[1/rx,0],[0,1/ry]],rotmat(-teta)))
+ applymat(mat, A)
+ applymat(mat, B)
+ k=[-(B[1]-A[1]),B[0]-A[0]]
+ d=k[0]*k[0]+k[1]*k[1]
+ k[0]/=sqrt(d)
+ k[1]/=sqrt(d)
+ d=sqrt(max(0,1-d/4))
+ if longflag==sweepflag:
+ d*=-1
+ O=[(B[0]+A[0])/2+d*k[0],(B[1]+A[1])/2+d*k[1]]
+ OA=[A[0]-O[0],A[1]-O[1]]
+ OB=[B[0]-O[0],B[1]-O[1]]
+ start=acos(OA[0]/norm(OA))
+ if OA[1]<0:
+ start*=-1
+ end=acos(OB[0]/norm(OB))
+ if OB[1]<0:
+ end*=-1
+
+ if sweepflag and start>end:
+ end +=2*pi
+ if (not sweepflag) and start<end:
+ end -=2*pi
+
+ NbSectors=int(abs(start-end)*2/pi)+1
+ dTeta=(end-start)/NbSectors
+ #v=dTeta*2/pi*0.552
+ #v=dTeta*2/pi*4*(sqrt(2)-1)/3
+ v = 4*tan(dTeta/4)/3
+ #if not sweepflag:
+ # v*=-1
+ p=[]
+ for i in range(0,NbSectors+1,1):
+ angle=start+i*dTeta
+ v1=[O[0]+cos(angle)-(-v)*sin(angle),O[1]+sin(angle)+(-v)*cos(angle)]
+ pt=[O[0]+cos(angle) ,O[1]+sin(angle) ]
+ v2=[O[0]+cos(angle)- v *sin(angle),O[1]+sin(angle)+ v *cos(angle)]
+ p.append([v1,pt,v2])
+
+ mat=matprod((rotmat(teta),[[rx,0],[0,ry]],rotmat(-teta)))
+ for pts in p:
+ applymat(mat, pts[0])
+ applymat(mat, pts[1])
+ applymat(mat, pts[2])
+
+ # Use exact coordinates for the endpoints. This prevents small drifts when relative coordinates are used and guarantees that a path ending with a z command closes perfectly.
+ p[0][0] = p1[:]
+ p[0][1] = p1[:]
+ p[-1][1] = [x2, y2]
+ p[-1][2] = [x2, y2]
+
+ return p
+
+def CubicSuperPath(simplepath):
+ csp = []
+ subpath = -1
+ subpathstart = []
+ last = []
+ lastctrl = []
+ for s in simplepath:
+ cmd, params = s
+ if cmd == 'M':
+ if last:
+ csp[subpath].append([lastctrl[:],last[:],last[:]])
+ subpath += 1
+ csp.append([])
+ subpathstart = params[:]
+ last = params[:]
+ lastctrl = params[:]
+ elif cmd == 'L':
+ csp[subpath].append([lastctrl[:],last[:],last[:]])
+ last = params[:]
+ lastctrl = params[:]
+ elif cmd == 'C':
+ csp[subpath].append([lastctrl[:],last[:],params[:2]])
+ last = params[-2:]
+ lastctrl = params[2:4]
+ elif cmd == 'Q':
+ q0=last[:]
+ q1=params[0:2]
+ q2=params[2:4]
+ x0= q0[0]
+ x1=1./3*q0[0]+2./3*q1[0]
+ x2= 2./3*q1[0]+1./3*q2[0]
+ x3= q2[0]
+ y0= q0[1]
+ y1=1./3*q0[1]+2./3*q1[1]
+ y2= 2./3*q1[1]+1./3*q2[1]
+ y3= q2[1]
+ csp[subpath].append([lastctrl[:],[x0,y0],[x1,y1]])
+ last = [x3,y3]
+ lastctrl = [x2,y2]
+ elif cmd == 'A':
+ arcp=ArcToPath(last[:],params[:])
+ arcp[ 0][0]=lastctrl[:]
+ last=arcp[-1][1]
+ lastctrl = arcp[-1][0]
+ csp[subpath]+=arcp[:-1]
+ elif cmd == 'Z':
+ csp[subpath].append([lastctrl[:],last[:],last[:]])
+ last = subpathstart[:]
+ lastctrl = subpathstart[:]
+ #append final superpoint
+ csp[subpath].append([lastctrl[:],last[:],last[:]])
+ return csp
+
+def unCubicSuperPath(csp):
+ a = []
+ for subpath in csp:
+ if subpath:
+ a.append(['M',subpath[0][1][:]])
+ for i in range(1,len(subpath)):
+ a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]])
+ return a
+
+def parsePath(d):
+ return CubicSuperPath(simplepath.parsePath(d))
+
+def formatPath(p):
+ return simplepath.formatPath(unCubicSuperPath(p))
+
+
+# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99