diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2015-04-30 09:17:07 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2015-04-30 09:17:07 +0000 |
| commit | 6a9762c7603a32c7ec5cc0aaed8048d84daee6e8 (patch) | |
| tree | 8cd98ce46dad85fc325bdd01ba60458de0801701 /src/2geom/ellipse.cpp | |
| parent | Fix calls to Geom::cross() - sign change. (diff) | |
| download | inkscape-6a9762c7603a32c7ec5cc0aaed8048d84daee6e8.tar.gz inkscape-6a9762c7603a32c7ec5cc0aaed8048d84daee6e8.zip | |
Update 2Geom to r2347
(bzr r14059.2.3)
Diffstat (limited to 'src/2geom/ellipse.cpp')
| -rw-r--r-- | src/2geom/ellipse.cpp | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/src/2geom/ellipse.cpp b/src/2geom/ellipse.cpp index 4e26707ef..9e927c9e8 100644 --- a/src/2geom/ellipse.cpp +++ b/src/2geom/ellipse.cpp @@ -170,33 +170,31 @@ EllipticalArc * Ellipse::arc(Point const &ip, Point const &inner, Point const &fp, bool _svg_compliant) { - Point sp_cp = ip - center(); - Point ep_cp = fp - center(); - Point ip_cp = inner - center(); - - double angle1 = angle_between(sp_cp, ep_cp); - double angle2 = angle_between(sp_cp, ip_cp); - double angle3 = angle_between(ip_cp, ep_cp); - - bool large_arc_flag = true; - bool sweep_flag = true; + // This is resistant to degenerate ellipses: + // both flags evaluate to false in that case. + + bool large_arc_flag = false; + bool sweep_flag = false; + + // Determination of large arc flag: + // The arc is larger than half of the ellipse if the inner point + // is on the same side of the line going from the initial + // to the final point as the center of the ellipse + Line chord(ip, fp); + Point versor = fp - ip; + double sdist_c = cross(versor, _center - ip); + double sdist_inner = cross(versor, inner - ip); + + // if we have exactly half of an arc, do not set the large flag. + if (sdist_c != 0 && sgn(sdist_c) == sgn(sdist_inner)) { + large_arc_flag = true; + } - if (angle1 > 0) { - if (angle2 > 0 && angle3 > 0) { - large_arc_flag = false; - sweep_flag = true; - } else { - large_arc_flag = true; - sweep_flag = false; - } - } else { - if (angle2 < 0 && angle3 < 0) { - large_arc_flag = false; - sweep_flag = false; - } else { - large_arc_flag = true; - sweep_flag = true; - } + // Determination of sweep flag: + // If the inner point is on the left side of the ip-fp line, + // we go in clockwise direction. + if (sdist_inner < 0) { + sweep_flag = true; } EllipticalArc *ret_arc; |
