@@ -43,8 +43,7 @@ namespace agg
4343 };
4444
4545 // 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
4847
4948 // --------------------------------------------------------stroke_calc_arc
5049 template <class VertexConsumer >
@@ -125,50 +124,27 @@ namespace agg
125124 double xi = v1.x ;
126125 double yi = v1.y ;
127126
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))
133132 {
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)
138138 {
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));
143142 }
144143 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)
168144 {
169145 // Miter limit exceeded
170146 // ------------------------
171- if (revert_flag)
147+ if (revert_flag || d1 < intersection_epsilon )
172148 {
173149 // For the compatibility with SVG, PDF, etc,
174150 // we use a simple bevel join instead of
@@ -195,11 +171,44 @@ namespace agg
195171 out_vertices.add (coord_type (x2, y2));
196172 }
197173 }
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+ }
198195 else
199196 {
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+ }
203212 }
204213 }
205214 }
@@ -223,18 +232,27 @@ namespace agg
223232
224233 out_vertices.remove_all ();
225234
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;
228237 double dx2 = 0 ;
229238 double dy2 = 0 ;
230239
231- if (line_cap == square_cap)
240+ dx1 *= width;
241+ dy1 *= width;
242+
243+ if (line_cap != round_cap)
232244 {
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));
235254 }
236-
237- if (line_cap == round_cap)
255+ else
238256 {
239257 double a1 = atan2 (dy1, -dx1);
240258 double a2 = a1 + pi;
@@ -247,11 +265,6 @@ namespace agg
247265 }
248266 out_vertices.add (coord_type (v0.x + dx1, v0.y - dy1));
249267 }
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- }
255268 }
256269
257270
@@ -283,7 +296,7 @@ namespace agg
283296
284297 out_vertices.remove_all ();
285298
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 )
287300 {
288301 // Inner join
289302 // ---------------
0 commit comments