summaryrefslogtreecommitdiffstats
path: root/src/2geom/ellipse.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2015-04-30 09:17:07 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2015-04-30 09:17:07 +0000
commit6a9762c7603a32c7ec5cc0aaed8048d84daee6e8 (patch)
tree8cd98ce46dad85fc325bdd01ba60458de0801701 /src/2geom/ellipse.cpp
parentFix calls to Geom::cross() - sign change. (diff)
downloadinkscape-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.cpp50
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;