printrun-src/printrun/svg2gcode/bezmisc.py

Thu, 23 Aug 2018 12:32:26 +0200

author
mdd
date
Thu, 23 Aug 2018 12:32:26 +0200
changeset 37
926424f97c8e
parent 16
36d478bde840
permissions
-rw-r--r--

SVG gcode generator: interpret color style if present

16
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
1 #!/usr/bin/env python
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
2 '''
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
3 Copyright (C) 2010 Nick Drobchenko, nick@cnc-club.ru
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
4 Copyright (C) 2005 Aaron Spike, aaron@ekips.org
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
5
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
6 This program is free software; you can redistribute it and/or modify
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
8 the Free Software Foundation; either version 2 of the License, or
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
9 (at your option) any later version.
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
10
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
11 This program is distributed in the hope that it will be useful,
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
14 GNU General Public License for more details.
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
15
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
17 along with this program; if not, write to the Free Software
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
19 '''
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
20
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
21 import math, cmath
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
22
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
23 def rootWrapper(a,b,c,d):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
24 if a:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
25 # Monics formula see http://en.wikipedia.org/wiki/Cubic_function#Monic_formula_of_roots
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
26 a,b,c = (b/a, c/a, d/a)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
27 m = 2.0*a**3 - 9.0*a*b + 27.0*c
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
28 k = a**2 - 3.0*b
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
29 n = m**2 - 4.0*k**3
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
30 w1 = -.5 + .5*cmath.sqrt(-3.0)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
31 w2 = -.5 - .5*cmath.sqrt(-3.0)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
32 if n < 0:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
33 m1 = pow(complex((m+cmath.sqrt(n))/2),1./3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
34 n1 = pow(complex((m-cmath.sqrt(n))/2),1./3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
35 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
36 if m+math.sqrt(n) < 0:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
37 m1 = -pow(-(m+math.sqrt(n))/2,1./3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
38 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
39 m1 = pow((m+math.sqrt(n))/2,1./3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
40 if m-math.sqrt(n) < 0:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
41 n1 = -pow(-(m-math.sqrt(n))/2,1./3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
42 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
43 n1 = pow((m-math.sqrt(n))/2,1./3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
44 x1 = -1./3 * (a + m1 + n1)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
45 x2 = -1./3 * (a + w1*m1 + w2*n1)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
46 x3 = -1./3 * (a + w2*m1 + w1*n1)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
47 return (x1,x2,x3)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
48 elif b:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
49 det=c**2.0-4.0*b*d
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
50 if det:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
51 return (-c+cmath.sqrt(det))/(2.0*b),(-c-cmath.sqrt(det))/(2.0*b)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
52 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
53 return -c/(2.0*b),
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
54 elif c:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
55 return 1.0*(-d/c),
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
56 return ()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
57
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
58 def bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
59 #parametric bezier
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
60 x0=bx0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
61 y0=by0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
62 cx=3*(bx1-x0)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
63 bx=3*(bx2-bx1)-cx
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
64 ax=bx3-x0-cx-bx
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
65 cy=3*(by1-y0)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
66 by=3*(by2-by1)-cy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
67 ay=by3-y0-cy-by
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
68
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
69 return ax,ay,bx,by,cx,cy,x0,y0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
70 #ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
71
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
72 def linebezierintersect(((lx1,ly1),(lx2,ly2)),((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
73 #parametric line
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
74 dd=lx1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
75 cc=lx2-lx1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
76 bb=ly1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
77 aa=ly2-ly1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
78
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
79 if aa:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
80 coef1=cc/aa
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
81 coef2=1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
82 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
83 coef1=1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
84 coef2=aa/cc
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
85
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
86 ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
87 #cubic intersection coefficients
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
88 a=coef1*ay-coef2*ax
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
89 b=coef1*by-coef2*bx
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
90 c=coef1*cy-coef2*cx
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
91 d=coef1*(y0-bb)-coef2*(x0-dd)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
92
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
93 roots = rootWrapper(a,b,c,d)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
94 retval = []
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
95 for i in roots:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
96 if type(i) is complex and i.imag==0:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
97 i = i.real
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
98 if type(i) is not complex and 0<=i<=1:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
99 retval.append(bezierpointatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),i))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
100 return retval
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
101
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
102 def bezierpointatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
103 ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
104 x=ax*(t**3)+bx*(t**2)+cx*t+x0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
105 y=ay*(t**3)+by*(t**2)+cy*t+y0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
106 return x,y
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
107
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
108 def bezierslopeatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
109 ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
110 dx=3*ax*(t**2)+2*bx*t+cx
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
111 dy=3*ay*(t**2)+2*by*t+cy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
112 return dx,dy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
113
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
114 def beziertatslope(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),(dy,dx)):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
115 ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
116 #quadratic coefficents of slope formula
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
117 if dx:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
118 slope = 1.0*(dy/dx)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
119 a=3*ay-3*ax*slope
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
120 b=2*by-2*bx*slope
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
121 c=cy-cx*slope
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
122 elif dy:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
123 slope = 1.0*(dx/dy)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
124 a=3*ax-3*ay*slope
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
125 b=2*bx-2*by*slope
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
126 c=cx-cy*slope
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
127 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
128 return []
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
129
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
130 roots = rootWrapper(0,a,b,c)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
131 retval = []
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
132 for i in roots:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
133 if type(i) is complex and i.imag==0:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
134 i = i.real
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
135 if type(i) is not complex and 0<=i<=1:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
136 retval.append(i)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
137 return retval
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
138
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
139 def tpoint((x1,y1),(x2,y2),t):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
140 return x1+t*(x2-x1),y1+t*(y2-y1)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
141 def beziersplitatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
142 m1=tpoint((bx0,by0),(bx1,by1),t)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
143 m2=tpoint((bx1,by1),(bx2,by2),t)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
144 m3=tpoint((bx2,by2),(bx3,by3),t)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
145 m4=tpoint(m1,m2,t)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
146 m5=tpoint(m2,m3,t)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
147 m=tpoint(m4,m5,t)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
148
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
149 return ((bx0,by0),m1,m4,m),(m,m5,m3,(bx3,by3))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
150
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
151 '''
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
152 Approximating the arc length of a bezier curve
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
153 according to <http://www.cit.gu.edu.au/~anthony/info/graphics/bezier.curves>
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
154
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
155 if:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
156 L1 = |P0 P1| +|P1 P2| +|P2 P3|
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
157 L0 = |P0 P3|
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
158 then:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
159 L = 1/2*L0 + 1/2*L1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
160 ERR = L1-L0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
161 ERR approaches 0 as the number of subdivisions (m) increases
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
162 2^-4m
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
163
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
164 Reference:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
165 Jens Gravesen <gravesen@mat.dth.dk>
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
166 "Adaptive subdivision and the length of Bezier curves"
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
167 mat-report no. 1992-10, Mathematical Institute, The Technical
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
168 University of Denmark.
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
169 '''
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
170 def pointdistance((x1,y1),(x2,y2)):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
171 return math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
172 def Gravesen_addifclose(b, len, error = 0.001):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
173 box = 0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
174 for i in range(1,4):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
175 box += pointdistance(b[i-1], b[i])
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
176 chord = pointdistance(b[0], b[3])
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
177 if (box - chord) > error:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
178 first, second = beziersplitatt(b, 0.5)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
179 Gravesen_addifclose(first, len, error)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
180 Gravesen_addifclose(second, len, error)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
181 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
182 len[0] += (box / 2.0) + (chord / 2.0)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
183 def bezierlengthGravesen(b, error = 0.001):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
184 len = [0]
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
185 Gravesen_addifclose(b, len, error)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
186 return len[0]
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
187
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
188 # balf = Bezier Arc Length Function
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
189 balfax,balfbx,balfcx,balfay,balfby,balfcy = 0,0,0,0,0,0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
190 def balf(t):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
191 retval = (balfax*(t**2) + balfbx*t + balfcx)**2 + (balfay*(t**2) + balfby*t + balfcy)**2
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
192 return math.sqrt(retval)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
193
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
194 def Simpson(f, a, b, n_limit, tolerance):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
195 n = 2
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
196 multiplier = (b - a)/6.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
197 endsum = f(a) + f(b)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
198 interval = (b - a)/2.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
199 asum = 0.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
200 bsum = f(a + interval)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
201 est1 = multiplier * (endsum + (2.0 * asum) + (4.0 * bsum))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
202 est0 = 2.0 * est1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
203 #print multiplier, endsum, interval, asum, bsum, est1, est0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
204 while n < n_limit and abs(est1 - est0) > tolerance:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
205 n *= 2
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
206 multiplier /= 2.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
207 interval /= 2.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
208 asum += bsum
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
209 bsum = 0.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
210 est0 = est1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
211 for i in xrange(1, n, 2):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
212 bsum += f(a + (i * interval))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
213 est1 = multiplier * (endsum + (2.0 * asum) + (4.0 * bsum))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
214 #print multiplier, endsum, interval, asum, bsum, est1, est0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
215 return est1
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
216
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
217 def bezierlengthSimpson(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), tolerance = 0.001):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
218 global balfax,balfbx,balfcx,balfay,balfby,balfcy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
219 ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
220 balfax,balfbx,balfcx,balfay,balfby,balfcy = 3*ax,2*bx,cx,3*ay,2*by,cy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
221 return Simpson(balf, 0.0, 1.0, 4096, tolerance)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
222
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
223 def beziertatlength(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), l = 0.5, tolerance = 0.001):
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
224 global balfax,balfbx,balfcx,balfay,balfby,balfcy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
225 ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
226 balfax,balfbx,balfcx,balfay,balfby,balfcy = 3*ax,2*bx,cx,3*ay,2*by,cy
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
227 t = 1.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
228 tdiv = t
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
229 curlen = Simpson(balf, 0.0, t, 4096, tolerance)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
230 targetlen = l * curlen
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
231 diff = curlen - targetlen
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
232 while abs(diff) > tolerance:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
233 tdiv /= 2.0
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
234 if diff < 0:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
235 t += tdiv
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
236 else:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
237 t -= tdiv
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
238 curlen = Simpson(balf, 0.0, t, 4096, tolerance)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
239 diff = curlen - targetlen
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
240 return t
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
241
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
242 #default bezier length method
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
243 bezierlength = bezierlengthSimpson
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
244
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
245 if __name__ == '__main__':
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
246 # import timing
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
247 #print linebezierintersect(((,),(,)),((,),(,),(,),(,)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
248 #print linebezierintersect(((0,1),(0,-1)),((-1,0),(-.5,0),(.5,0),(1,0)))
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
249 tol = 0.00000001
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
250 curves = [((0,0),(1,5),(4,5),(5,5)),
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
251 ((0,0),(0,0),(5,0),(10,0)),
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
252 ((0,0),(0,0),(5,1),(10,0)),
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
253 ((-10,0),(0,0),(10,0),(10,10)),
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
254 ((15,10),(0,0),(10,0),(-5,10))]
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
255 '''
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
256 for curve in curves:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
257 timing.start()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
258 g = bezierlengthGravesen(curve,tol)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
259 timing.finish()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
260 gt = timing.micro()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
261
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
262 timing.start()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
263 s = bezierlengthSimpson(curve,tol)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
264 timing.finish()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
265 st = timing.micro()
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
266
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
267 print g, gt
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
268 print s, st
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
269 '''
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
270 for curve in curves:
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
271 print beziertatlength(curve,0.5)
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
272
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
273
36d478bde840 Implemented svg, png and hpgl compilers to pronterface
mbayer
parents:
diff changeset
274 # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99

mercurial