@@ -43,8 +43,7 @@ namespace agg
43
43
};
44
44
45
45
// Minimal angle to calculate round joins, less than 0.1 degree.
46
- const double stroke_theta = 0.001 ; // ----stroke_theta
47
-
46
+ const double stroke_theta = 0.001 ; // ----stroke_theta
48
47
49
48
// --------------------------------------------------------stroke_calc_arc
50
49
template <class VertexConsumer >
@@ -125,50 +124,27 @@ namespace agg
125
124
double xi = v1.x ;
126
125
double yi = v1.y ;
127
126
128
- if (! calc_intersection (v0.x + dx1, v0.y - dy1,
129
- v1.x + dx1, v1.y - dy1,
130
- v1.x + dx2, v1.y - dy2,
131
- v2.x + dx2, v2.y - dy2,
132
- &xi, &yi))
127
+ if (calc_intersection (v0.x + dx1, v0.y - dy1,
128
+ v1.x + dx1, v1.y - dy1,
129
+ v1.x + dx2, v1.y - dy2,
130
+ v2.x + dx2, v2.y - dy2,
131
+ &xi, &yi))
133
132
{
134
- // The calculation didn't succeed, most probaly
135
- // the three points lie one straight line
136
- // ----------------
137
- if (calc_distance (dx1, -dy1, dx2, -dy2) < width * 0.025 )
133
+ // Calculation of the intersection succeeded
134
+ // ---------------------
135
+ double d1 = calc_distance (v1.x , v1.y , xi, yi);
136
+ double lim = width * miter_limit;
137
+ if (d1 <= lim)
138
138
{
139
- // This case means that the next segment continues
140
- // the previous one (straight line)
141
- // -----------------
142
- out_vertices.add (coord_type (v1.x + dx1, v1.y - dy1));
139
+ // Inside the miter limit
140
+ // ---------------------
141
+ out_vertices.add (coord_type (xi, yi));
143
142
}
144
143
else
145
- {
146
- // This case means that the next segment goes back
147
- // -----------------
148
- if (revert_flag)
149
- {
150
- out_vertices.add (coord_type (v1.x + dx1, v1.y - dy1));
151
- out_vertices.add (coord_type (v1.x + dx2, v1.y - dy2));
152
- }
153
- else
154
- {
155
- // If no miter-revert, calcuate new dx1, dy1, dx2, dy2
156
- out_vertices.add (coord_type (v1.x + dx1 + dy1 * miter_limit,
157
- v1.y - dy1 + dx1 * miter_limit));
158
- out_vertices.add (coord_type (v1.x + dx2 - dy2 * miter_limit,
159
- v1.y - dy2 - dx2 * miter_limit));
160
- }
161
- }
162
- }
163
- else
164
- {
165
- double d1 = calc_distance (v1.x , v1.y , xi, yi);
166
- double lim = width * miter_limit;
167
- if (d1 > lim)
168
144
{
169
145
// Miter limit exceeded
170
146
// ------------------------<
10000
/span>
171
- if (revert_flag)
147
+ if (revert_flag || d1 < intersection_epsilon )
172
148
{
173
149
// For the compatibility with SVG, PDF, etc,
174
150
// we use a simple bevel join instead of
@@ -195,11 +171,44 @@ namespace agg
195
171
out_vertices.add (coord_type (x2, y2));
196
172
}
197
173
}
174
+ }
175
+ else
176
+ {
177
+ // Calculation of the intersection failed, most probaly
178
+ // the three points lie one straight line.
179
+ // First check if v0 and v2 lie on the opposite sides of vector:
180
+ // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
181
+ // to the line determined by vertices v0 and v1.
182
+ // This condition deternines whether the next line segments continues
183
+ // the previous one or goes back.
184
+ // ----------------
185
+ double x2 = v1.x + dx1;
186
+ double y2 = v1.y - dy1;
187
+ if (((x2 - v0.x )*dy1 - (v0.y - y2)*dx1 < 0.0 ) !=
188
+ ((x2 - v2.x )*dy1 - (v2.y - y2)*dx1 < 0.0 ))
189
+ {
190
+ // This case means that the next segment continues
191
+ // the previous one (straight line)
192
+ // -----------------
193
+ out_vertices.add (coord_type (v1.x + dx1, v1.y - dy1));
194
+ }
198
195
else
199
196
{
200
- // Inside the miter limit
201
- // ---------------------
202
- out_vertices.add (coord_type (xi, yi));
197
+ // This case means that the next segment goes back
198
+ // -----------------
199
+ if (revert_flag)
200
+ {
201
+ out_vertices.add (coord_type (v1.x + dx1, v1.y - dy1));
202
+ out_vertices.add (coord_type (v1.x + dx2, v1.y - dy2));
203
+ }
204
+ else
205
+ {
206
+ // If no miter-revert, calcuate new dx1, dy1, dx2, dy2
207
+ out_vertices.add (coord_type (v1.x + dx1 + dy1 * miter_limit,
208
+ v1.y - dy1 + dx1 * miter_limit));
209
+ out_vertices.add (coord_type (v1.x + dx2 - dy2 * miter_limit,
210
+ v1.y - dy2 - dx2 * miter_limit));
211
+ }
203
212
}
204
213
}
205
214
}
@@ -223,18 +232,27 @@ namespace agg
223
232
224
233
out_vertices.remove_all ();
225
234
226
- double dx1 = width * (v1.y - v0.y ) / len;
227
- double dy1 = width * (v1.x - v0.x ) / len;
235
+ double dx1 = (v1.y - v0.y ) / len;
236
+ double dy1 = (v1.x - v0.x ) / len;
228
237
double dx2 = 0 ;
229
238
double dy2 = 0 ;
230
239
231
- if (line_cap == square_cap)
240
+ dx1 *= width;
241
+ dy1 *= width;
242
+
243
+ if (line_cap != round_cap)
232
244
{
233
- dx2 = dy1;
234
- dy2 = dx1;
245
+ if (line_cap == square_cap)
246
+ {
247
+ dx2 = dy1;
248
+ dy2 = dx1;
249
+ }
250
+ double dx = dx1 - dx2;
251
+ double dy = dy1 - dy2;
252
+ out_vertices.add (coord_type (v0.x - dx, v0.y + dy));
253
+ out_vertices.add (coord_type (v0.x + dx, v0.y - dy));
235
254
}
236
-
237
- if (line_cap == round_cap)
255
+ else
238
256
{
239
257
double a1 = atan2 (dy1, -dx1);
240
258
double a2 = a1 + pi;
@@ -247,11 +265,6 @@ namespace agg
247
265
}
248
266
out_vertices.add (coord_type (v0.x + dx1, v0.y - dy1));
249
267
}
250
- else
251
- {
252
- out_vertices.add (coord_type (v0.x - dx1 - dx2, v0.y + dy1 - dy2));
253
- out_vertices.add (coord_type (v0.x + dx1 - dx2, v0.y - dy1 - dy2));
254
- }
255
268
}
256
269
257
270
@@ -283,7 +296,7 @@ namespace agg
283
296
284
297
out_vertices.remove_all ();
285
298
286
- if (calc_point_location (v0.x , v0.y , v1.x , v1.y , v2.x , v2.y ) > 0.0 )
299
+ if (calc_point_location (v0.x , v0.y , v1.x , v1.y , v2.x , v2.y ) > 0 )
287
300
{
288
301
// Inner join
289
302
// ---------------
0 commit comments