|
Lines 123-140
art_vpath_render_bez (ArtVpath **p_vpath, int *pn, int *pn_max,
Link Here
|
| 123 |
double x3, double y3, |
123 |
double x3, double y3, |
| 124 |
double flatness) |
124 |
double flatness) |
| 125 |
{ |
125 |
{ |
| 126 |
double x3_0, y3_0; |
|
|
| 127 |
double z3_0_dot; |
| 128 |
double z1_dot, z2_dot; |
| 129 |
double z1_perp, z2_perp; |
| 130 |
double max_perp_sq; |
| 131 |
|
| 132 |
double x_m, y_m; |
| 133 |
double xa1, ya1; |
| 134 |
double xa2, ya2; |
| 135 |
double xb1, yb1; |
| 136 |
double xb2, yb2; |
| 137 |
|
| 138 |
/* It's possible to optimize this routine a fair amount. |
126 |
/* It's possible to optimize this routine a fair amount. |
| 139 |
|
127 |
|
| 140 |
First, once the _dot conditions are met, they will also be met in |
128 |
First, once the _dot conditions are met, they will also be met in |
|
Lines 157-226
art_vpath_render_bez (ArtVpath **p_vpath, int *pn, int *pn_max,
Link Here
|
| 157 |
just that I have this undying quest for more speed... |
145 |
just that I have this undying quest for more speed... |
| 158 |
|
146 |
|
| 159 |
*/ |
147 |
*/ |
| 160 |
|
148 |
do |
| 161 |
x3_0 = x3 - x0; |
|
|
| 162 |
y3_0 = y3 - y0; |
| 163 |
|
| 164 |
/* z3_0_dot is dist z0-z3 squared */ |
| 165 |
z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0; |
| 166 |
|
| 167 |
if (z3_0_dot < 0.001) |
| 168 |
{ |
149 |
{ |
| 169 |
/* if start and end point are almost identical, the flatness tests |
150 |
/* don't subdivide inside this */ |
| 170 |
* don't work properly, so fall back on testing whether both of |
151 |
double x3_0, y3_0; |
| 171 |
* the other two control points are the same as the start point, |
152 |
double z3_0_dot; |
| 172 |
* too. |
153 |
double z1_dot, z2_dot; |
| 173 |
*/ |
154 |
double z1_perp, z2_perp; |
| 174 |
if (hypot(x1 - x0, y1 - y0) < 0.001 |
155 |
double max_perp_sq; |
| 175 |
&& hypot(x2 - x0, y2 - y0) < 0.001) |
|
|
| 176 |
goto nosubdivide; |
| 177 |
else |
| 178 |
goto subdivide; |
| 179 |
} |
| 180 |
|
156 |
|
| 181 |
/* we can avoid subdivision if: |
157 |
x3_0 = x3 - x0; |
|
|
158 |
y3_0 = y3 - y0; |
| 182 |
|
159 |
|
| 183 |
z1 has distance no more than flatness from the z0-z3 line |
160 |
/* z3_0_dot is dist z0-z3 squared */ |
|
|
161 |
z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0; |
| 184 |
|
162 |
|
| 185 |
z1 is no more z0'ward than flatness past z0-z3 |
163 |
if (z3_0_dot > 0.001) |
|
|
164 |
{ |
| 165 |
/* we can avoid subdivision if: |
| 186 |
|
166 |
|
| 187 |
z1 is more z0'ward than z3'ward on the line traversing z0-z3 |
167 |
z1 has distance no more than flatness from the z0-z3 line |
| 188 |
|
168 |
|
| 189 |
and correspondingly for z2 */ |
169 |
z1 is no more z0'ward than flatness past z0-z3 |
| 190 |
|
170 |
|
| 191 |
/* perp is distance from line, multiplied by dist z0-z3 */ |
171 |
z1 is more z0'ward than z3'ward on the line traversing z0-z3 |
| 192 |
max_perp_sq = flatness * flatness * z3_0_dot; |
|
|
| 193 |
|
172 |
|
| 194 |
z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0; |
173 |
and correspondingly for z2 */ |
| 195 |
if (z1_perp * z1_perp > max_perp_sq) |
|
|
| 196 |
goto subdivide; |
| 197 |
|
174 |
|
| 198 |
z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0; |
175 |
/* perp is distance from line, multiplied by dist z0-z3 */ |
| 199 |
if (z2_perp * z2_perp > max_perp_sq) |
176 |
max_perp_sq = flatness * flatness * z3_0_dot; |
| 200 |
goto subdivide; |
|
|
| 201 |
|
177 |
|
| 202 |
z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0; |
178 |
z1_perp = (y1 - y0) * x3_0 - (x1 - x0) * y3_0; |
| 203 |
if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq) |
179 |
if (z1_perp * z1_perp > max_perp_sq) |
| 204 |
goto subdivide; |
180 |
break; |
| 205 |
|
181 |
|
| 206 |
z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0; |
182 |
z2_perp = (y3 - y2) * x3_0 - (x3 - x2) * y3_0; |
| 207 |
if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq) |
183 |
if (z2_perp * z2_perp > max_perp_sq) |
| 208 |
goto subdivide; |
184 |
break; |
| 209 |
|
185 |
|
| 210 |
if (z1_dot + z1_dot > z3_0_dot) |
186 |
z1_dot = (x1 - x0) * x3_0 + (y1 - y0) * y3_0; |
| 211 |
goto subdivide; |
187 |
if (z1_dot < 0 && z1_dot * z1_dot > max_perp_sq) |
|
|
188 |
break; |
| 212 |
|
189 |
|
| 213 |
if (z2_dot + z2_dot > z3_0_dot) |
190 |
if (z1_dot + z1_dot > z3_0_dot) |
| 214 |
goto subdivide; |
191 |
break; |
| 215 |
|
192 |
|
| 216 |
|
193 |
z2_dot = (x3 - x2) * x3_0 + (y3 - y2) * y3_0; |
| 217 |
nosubdivide: |
194 |
if (z2_dot < 0 && z2_dot * z2_dot > max_perp_sq) |
| 218 |
/* don't subdivide */ |
195 |
break; |
| 219 |
art_vpath_add_point (p_vpath, pn, pn_max, |
|
|
| 220 |
ART_LINETO, x3, y3); |
| 221 |
return; |
| 222 |
|
196 |
|
| 223 |
subdivide: |
197 |
if (z2_dot + z2_dot > z3_0_dot) |
|
|
198 |
break; |
| 199 |
} |
| 200 |
else |
| 201 |
{ |
| 202 |
/* if start and end point are almost identical, the flatness tests |
| 203 |
* don't work properly, so fall back on testing whether both of |
| 204 |
* the other two control points are the same as the start point, |
| 205 |
* too. |
| 206 |
*/ |
| 207 |
if (hypot(x1 - x0, y1 - y0) > 0.001 |
| 208 |
|| hypot(x2 - x0, y2 - y0) > 0.001) |
| 209 |
break; |
| 210 |
} |
| 211 |
|
| 212 |
art_vpath_add_point (p_vpath, pn, pn_max, |
| 213 |
ART_LINETO, x3, y3); |
| 214 |
return; |
| 215 |
} while (0); |
| 216 |
double x_m, y_m; |
| 217 |
double xa1, ya1; |
| 218 |
double xa2, ya2; |
| 219 |
double xb1, yb1; |
| 220 |
double xb2, yb2; |
| 224 |
|
221 |
|
| 225 |
xa1 = (x0 + x1) * 0.5; |
222 |
xa1 = (x0 + x1) * 0.5; |
| 226 |
ya1 = (y0 + y1) * 0.5; |
223 |
ya1 = (y0 + y1) * 0.5; |