[dia] path: Fix bezier bounding box calculation glitches
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] path: Fix bezier bounding box calculation glitches
- Date: Fri, 26 Sep 2014 12:52:29 +0000 (UTC)
commit 7ef29f3c807610cd24d65ae21e0db3c1d69aab59
Author: Hans Breuer <hans breuer org>
Date: Fri Sep 26 14:13:08 2014 +0200
path: Fix bezier bounding box calculation glitches
Without a 'pointy join' there is no point in calculating the overshot,
actually this was growing the bounding box arbitrarily. (First line
of bezier-extreme.dia)
Also handle slightly degenerated bezier where the control point and
the start or end point are in the same place. Now we are using the
other control point to have a direction for add_arrow_rectangle()
in bicubicbezier2D_bbox(). Otherwise there would be no bounding box
contribution from line ends of this kind (see second line of
bezier-extreme.dia)
Having this fix also seems to be a precondition for properly behaving
StdPath::move_handle(). Previously, e.g. with commit 14e05d51d99e1457
it was possible to go over the constraints implemented, presumably
due to bounding box miscalculations leading to wrong handle positions.
Still with line-join round the bezier is drawn a bit outside of the box.
lib/boundingbox.c | 25 +++++++++++++++++--------
samples/bezier-extreme.dia | Bin 0 -> 4724 bytes
2 files changed, 17 insertions(+), 8 deletions(-)
---
diff --git a/lib/boundingbox.c b/lib/boundingbox.c
index 4c14892..83c7350 100644
--- a/lib/boundingbox.c
+++ b/lib/boundingbox.c
@@ -158,12 +158,16 @@ bicubicbezier2D_bbox(const Point *p0,const Point *p1,
rectangle_add_point(rect,p3);
/* start point */
point_copy_add_scaled(&vl,p0,p1,-1);
+ if (point_len(&vl) == 0)
+ point_copy_add_scaled(&vl,p0,p2,-1);
point_normalize(&vl);
add_arrow_rectangle(rect,p0,&vl,extra->start_long,MAX(extra->start_trans,
extra->middle_trans));
/* end point */
point_copy_add_scaled(&vl,p3,p2,-1);
+ if (point_len(&vl) == 0)
+ point_copy_add_scaled(&vl,p3,p1,-1);
point_normalize(&vl);
add_arrow_rectangle(rect,p3,&vl,extra->end_long,MAX(extra->end_trans,
extra->middle_trans));
@@ -312,7 +316,7 @@ polybezier_bbox(const BezPoint *pts, int numpoints,
Point vx,vn,vsc,vp;
int i,prev,next;
Rectangle rt;
- PolyBBExtras bextra,start_bextra,end_bextra;
+ PolyBBExtras bextra,start_bextra,end_bextra,full_bextra;
LineBBExtras lextra,start_lextra,end_lextra,full_lextra;
gboolean start,end;
@@ -342,6 +346,11 @@ polybezier_bbox(const BezPoint *pts, int numpoints,
full_lextra.start_trans = MAX(extra->start_trans,extra->middle_trans);
full_lextra.end_long = extra->end_long;
full_lextra.end_trans = MAX(extra->end_trans,extra->middle_trans);
+ full_bextra.start_long = extra->start_long;
+ full_bextra.start_trans = MAX(extra->start_trans,extra->middle_trans);
+ full_bextra.middle_trans = extra->middle_trans;
+ full_bextra.end_long = extra->end_long;
+ full_bextra.end_trans = MAX(extra->end_trans,extra->middle_trans);
if (!closed) {
lextra.start_long = 0;
@@ -453,7 +462,7 @@ polybezier_bbox(const BezPoint *pts, int numpoints,
if (end) {
bicubicbezier2D_bbox(&vsc,
&pts[i].p1,&pts[i].p2,&pts[i].p3,
- extra,
+ &full_bextra,
&rt);
} else {
bicubicbezier2D_bbox(&vsc,
@@ -497,12 +506,7 @@ polybezier_bbox(const BezPoint *pts, int numpoints,
point_normalize(&vxn);
co = point_dot(&vpx,&vxn);
- if (co >= 1.0)
- alpha = 0.0;
- else if (co <= -1.0)
- alpha = M_PI;
- else
- alpha = dia_acos(-co);
+ alpha = dia_acos(-co);
if (co > -0.9816) { /* 0.9816 = cos(11deg) */
/* we have a pointy join. */
real overshoot;
@@ -520,6 +524,10 @@ polybezier_bbox(const BezPoint *pts, int numpoints,
rectangle_add_point(rect,&pto);
} else {
/* we don't have a pointy join. */
+#if 0
+ /* so nothing to do really - this code would be growing the
+ * bounding box arbitrarily. See e.g with bezier-extreme.dia
+ */
Point vpxt,vxnt,tmp;
point_get_perp(&vpxt,&vpx);
@@ -533,6 +541,7 @@ polybezier_bbox(const BezPoint *pts, int numpoints,
rectangle_add_point(rect,&tmp);
point_copy_add_scaled(&tmp,&vx,&vxnt,-1);
rectangle_add_point(rect,&tmp);
+#endif
}
}
}
diff --git a/samples/bezier-extreme.dia b/samples/bezier-extreme.dia
new file mode 100644
index 0000000..63262da
Binary files /dev/null and b/samples/bezier-extreme.dia differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]