home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Inkscape / Inkscape-0.48.2-1-win32.exe / share / extensions / cubicsuperpath.py < prev    next >
Text File  |  2011-07-08  |  5KB  |  170 lines

  1. #!/usr/bin/env python
  2. """
  3. cubicsuperpath.py
  4.  
  5. Copyright (C) 2005 Aaron Spike, aaron@ekips.org
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  
  21. """
  22. import simplepath 
  23. from math import *
  24.  
  25. def matprod(mlist):
  26.     prod=mlist[0]
  27.     for m in mlist[1:]:
  28.         a00=prod[0][0]*m[0][0]+prod[0][1]*m[1][0]
  29.         a01=prod[0][0]*m[0][1]+prod[0][1]*m[1][1]
  30.         a10=prod[1][0]*m[0][0]+prod[1][1]*m[1][0]
  31.         a11=prod[1][0]*m[0][1]+prod[1][1]*m[1][1]
  32.         prod=[[a00,a01],[a10,a11]]
  33.     return prod
  34. def rotmat(teta):
  35.     return [[cos(teta),-sin(teta)],[sin(teta),cos(teta)]]
  36. def applymat(mat, pt):
  37.     x=mat[0][0]*pt[0]+mat[0][1]*pt[1]
  38.     y=mat[1][0]*pt[0]+mat[1][1]*pt[1]
  39.     pt[0]=x
  40.     pt[1]=y
  41. def norm(pt):
  42.     return sqrt(pt[0]*pt[0]+pt[1]*pt[1])
  43.  
  44. def ArcToPath(p1,params):
  45.     A=p1[:]
  46.     rx,ry,teta,longflag,sweepflag,x2,y2=params[:]
  47.     teta = teta*pi/180.0
  48.     B=[x2,y2]
  49.     if rx==0 or ry==0:
  50.         return([[A,A,A],[B,B,B]])
  51.     mat=matprod((rotmat(teta),[[1/rx,0],[0,1/ry]],rotmat(-teta)))
  52.     applymat(mat, A)
  53.     applymat(mat, B)
  54.     k=[-(B[1]-A[1]),B[0]-A[0]]
  55.     d=k[0]*k[0]+k[1]*k[1]
  56.     k[0]/=sqrt(d)
  57.     k[1]/=sqrt(d)
  58.     d=sqrt(max(0,1-d/4))
  59.     if longflag==sweepflag:
  60.         d*=-1
  61.     O=[(B[0]+A[0])/2+d*k[0],(B[1]+A[1])/2+d*k[1]]
  62.     OA=[A[0]-O[0],A[1]-O[1]]
  63.     OB=[B[0]-O[0],B[1]-O[1]]
  64.     start=acos(OA[0]/norm(OA))
  65.     if OA[1]<0:
  66.         start*=-1
  67.     end=acos(OB[0]/norm(OB))
  68.     if OB[1]<0:
  69.         end*=-1
  70.  
  71.     if sweepflag and start>end:
  72.         end +=2*pi
  73.     if (not sweepflag) and start<end:
  74.         end -=2*pi
  75.  
  76.     NbSectors=int(abs(start-end)*2/pi)+1
  77.     dTeta=(end-start)/NbSectors
  78.     #v=dTeta*2/pi*0.552
  79.     #v=dTeta*2/pi*4*(sqrt(2)-1)/3
  80.     v = 4*tan(dTeta/4)/3
  81.     #if not sweepflag:
  82.     #    v*=-1
  83.     p=[]
  84.     for i in range(0,NbSectors+1,1):
  85.         angle=start+i*dTeta
  86.         v1=[O[0]+cos(angle)-(-v)*sin(angle),O[1]+sin(angle)+(-v)*cos(angle)]
  87.         pt=[O[0]+cos(angle)                ,O[1]+sin(angle)                ]
  88.         v2=[O[0]+cos(angle)-  v *sin(angle),O[1]+sin(angle)+  v *cos(angle)]
  89.         p.append([v1,pt,v2])
  90.     p[ 0][0]=p[ 0][1][:]
  91.     p[-1][2]=p[-1][1][:]
  92.  
  93.     mat=matprod((rotmat(teta),[[rx,0],[0,ry]],rotmat(-teta)))
  94.     for pts in p:
  95.         applymat(mat, pts[0])
  96.         applymat(mat, pts[1])
  97.         applymat(mat, pts[2])
  98.     return(p)
  99.     
  100. def CubicSuperPath(simplepath):
  101.     csp = []
  102.     subpath = -1
  103.     subpathstart = []
  104.     last = []
  105.     lastctrl = []
  106.     for s in simplepath:
  107.         cmd, params = s        
  108.         if cmd == 'M':
  109.             if last:
  110.                 csp[subpath].append([lastctrl[:],last[:],last[:]])
  111.             subpath += 1
  112.             csp.append([])
  113.             subpathstart =  params[:]
  114.             last = params[:]
  115.             lastctrl = params[:]
  116.         elif cmd == 'L':
  117.             csp[subpath].append([lastctrl[:],last[:],last[:]])
  118.             last = params[:]
  119.             lastctrl = params[:]
  120.         elif cmd == 'C':
  121.             csp[subpath].append([lastctrl[:],last[:],params[:2]])
  122.             last = params[-2:]
  123.             lastctrl = params[2:4]
  124.         elif cmd == 'Q':
  125.             q0=last[:]
  126.             q1=params[0:2]
  127.             q2=params[2:4]
  128.             x0=     q0[0]
  129.             x1=1./3*q0[0]+2./3*q1[0]
  130.             x2=           2./3*q1[0]+1./3*q2[0]
  131.             x3=                           q2[0]
  132.             y0=     q0[1]
  133.             y1=1./3*q0[1]+2./3*q1[1]
  134.             y2=           2./3*q1[1]+1./3*q2[1]
  135.             y3=                           q2[1]
  136.             csp[subpath].append([lastctrl[:],[x0,y0],[x1,y1]])
  137.             last = [x3,y3]
  138.             lastctrl = [x2,y2]
  139.         elif cmd == 'A':
  140.             arcp=ArcToPath(last[:],params[:])
  141.             arcp[ 0][0]=lastctrl[:]
  142.             last=arcp[-1][1]
  143.             lastctrl = arcp[-1][0]
  144.             csp[subpath]+=arcp[:-1]
  145.         elif cmd == 'Z':
  146.             csp[subpath].append([lastctrl[:],last[:],last[:]])
  147.             last = subpathstart[:]
  148.             lastctrl = subpathstart[:]
  149.     #append final superpoint
  150.     csp[subpath].append([lastctrl[:],last[:],last[:]])
  151.     return csp    
  152.  
  153. def unCubicSuperPath(csp):
  154.     a = []
  155.     for subpath in csp:
  156.         if subpath:
  157.             a.append(['M',subpath[0][1][:]])
  158.             for i in range(1,len(subpath)):
  159.                 a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]])
  160.     return a
  161.  
  162. def parsePath(d):
  163.     return CubicSuperPath(simplepath.parsePath(d))
  164.  
  165. def formatPath(p):
  166.     return simplepath.formatPath(unCubicSuperPath(p))
  167.  
  168.  
  169. # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
  170.