dia r4034 - in trunk: . app lib objects/Database objects/Istar objects/standard



Author: hans
Date: Sun May 18 12:44:31 2008
New Revision: 4034
URL: http://svn.gnome.org/viewvc/dia?rev=4034&view=rev

Log:
2008-05-19  Hans Breuer  <hans breuer org>

	[finally use dia_object_get_enclosing_box() to ... ]
	* app/commands.c : ... have bezier control points in field of view 
	when "show all" with selected bezier objects
	* app/object_ops.c ... get rid of bezier control line traces, because
	they are not included with the bounding box. Fixes bug #300055
	* objects/standard/bezier.c objects/standard/beziergon.c : calculate
	the enclosing box as control points plus bounding box

	* objects/Database/table.c : don't use dia_object_get_enclosing_box()
	where dia_object_get_bounding_box() was meant

	* lib/libdia.def lib/bounding_box.[hc] : export some bezier helper
	functions instead of copy and pasting them to ...
	* objects/Istar/link.c : ... other users

	* lib/bounding_box.c : added some API documentation for the helpers
	(bicubicbezier_extrema) : special casing for quadratic curves to avoid
	division by (almost) zero and improve/fix bounding box calculation for
	symmetric bezier curves


Modified:
   trunk/ChangeLog
   trunk/app/commands.c
   trunk/app/object_ops.c
   trunk/lib/boundingbox.c
   trunk/lib/boundingbox.h
   trunk/lib/libdia.def
   trunk/objects/Database/table.c
   trunk/objects/Istar/link.c
   trunk/objects/standard/bezier.c
   trunk/objects/standard/beziergon.c

Modified: trunk/app/commands.c
==============================================================================
--- trunk/app/commands.c	(original)
+++ trunk/app/commands.c	Sun May 18 12:44:31 2008
@@ -960,11 +960,11 @@
   /* if there is something selected show that instead of all exisiting objects */
   if (dia->data->selected) {
     GList *list = dia->data->selected;
-    Rectangle extents = ((DiaObject*)list->data)->bounding_box;
+    Rectangle extents = *dia_object_get_enclosing_box ((DiaObject*)list->data);
     list = g_list_next(list);
     while (list) {
       DiaObject *obj = (DiaObject *)list->data;
-      rectangle_union(&extents, &(obj->bounding_box));
+      rectangle_union(&extents, dia_object_get_enclosing_box (obj));
       list = g_list_next(list);
     }
     magnify_x = (real)width / (extents.right - extents.left) / ddisp->zoom_factor;

Modified: trunk/app/object_ops.c
==============================================================================
--- trunk/app/object_ops.c	(original)
+++ trunk/app/object_ops.c	Sun May 18 12:44:31 2008
@@ -38,7 +38,7 @@
   if (obj->highlight_color != NULL) {
     diagram_add_update_with_border(dia, &obj->bounding_box, 5);
   } else {
-    diagram_add_update(dia, &obj->bounding_box);
+    diagram_add_update(dia, dia_object_get_enclosing_box (obj));
   }
 
   /* Handles */

Modified: trunk/lib/boundingbox.c
==============================================================================
--- trunk/lib/boundingbox.c	(original)
+++ trunk/lib/boundingbox.c	Sun May 18 12:44:31 2008
@@ -25,32 +25,32 @@
 #include "geometry.h"
 #include "boundingbox.h"
 
-/** 
- * @param p 
+/** Translates x- or y- part of bezier points to Bernstein polynom coefficients
+ * @param p x- or y-part of the four points
  * @param A 
  * @param B 
  * @param C 
  * @param D 
- * @bug I don't know what this does.
+ * See: Foley et al., Computer Graphics, Bezier Curves or
+ * http://en.wikipedia.org/wiki/B%C3%A9zier_curve
  */
-static void
+void
 bernstein_develop(const real p[4], real *A, real *B, real *C, real *D)
 {
-  *A = -p[0]+3*p[1]-3*p[2]+p[3];
-  *B = 3*p[0]-6*p[1]+3*p[2];
-  *C = 3*p[1]-3*p[0];
-  *D = p[0];
+  *A =   -p[0]+3*p[1]-3*p[2]+p[3];
+  *B =  3*p[0]-6*p[1]+3*p[2];
+  *C = -3*p[0]+3*p[1];
+  *D =    p[0];
   /* if Q(u)=Sum(i=0..3)piBi(u) (Bi(u) being the Bernstein stuff),
      then Q(u)=Au^3+Bu^2+Cu+p[0]. */
 }
 
-/** ?
- * @param p 
- * @param u 
- * @returns 
- * @bug I don't know what this does.
+/** Evaluates the Bernstein polynoms for a given position
+ * @param p x- or y-values of four points describing the bezier
+ * @param u position on the curve [0 .. 1]
+ * @returns the evaluate x- or y-part of the point
  */
-static real
+real
 bezier_eval(const real p[4], real u)
 {
   real A,B,C,D;
@@ -58,13 +58,12 @@
   return A*u*u*u+B*u*u+C*u+D;
 }
 
-/** ?
- * @param p 
- * @param u 
- * @return 
- * @bug I don't know what this does.
+/** Calculates the tangent for a given point on a bezier curve
+ * @param p x- or y-values of four points describing the bezier
+ * @param u position on the curve between[0 .. 1]
+ * @return the x- or y-part of the tangent vector
  */
-static real
+real
 bezier_eval_tangent(const real p[4], real u)
 {
   real A,B,C,D;
@@ -72,11 +71,11 @@
   return 3*A*u*u+2*B*u+C;
 }  
 
-/** ?
- * @param p
- * @param u
- * @return
- * @bug I don't know what this does.
+/**
+ * Calculates the extrma of the given curve in x- or y-direction.
+ * @param p x- or y-values of four points describing the bezier
+ * @param u The position of the extrema [0 .. 1]
+ * @return The number of extrema found.
  */
 static int
 bicubicbezier_extrema(const real p[4],real u[2])
@@ -89,6 +88,12 @@
   u[0] = u[1] = 0.0;
   if (delta<0) return 0;
 
+  /* just a quadratic contribution? */
+  if (fabs(A) < 1e-6) {
+    u[0] = -C/(2*B);
+    return 1;
+  }
+
   u[0] = (-2*B + sqrt(delta)) / (6*A);
   if (delta==0) return 1;
   u[1] = (-2*B - sqrt(delta)) / (6*A);
@@ -126,13 +131,12 @@
 }
 
 /** Calculate the boundingbox for a 2D bezier curve segment.
- * @param p0 
- * @param p1 
- * @param p2 
- * @param p3 
- * @param extra 
+ * @param p0 start point
+ * @param p1 1st control point
+ * @param p2 2nd control point
+ * @param p3 end point
+ * @param extra information about extra space from linewidth and arrow to add to the bounding box
  * @param rect The rectangle that the segment fits inside.
- * @bug I don't know exactly what the other parameters are.
  */
 void
 bicubicbezier2D_bbox(const Point *p0,const Point *p1,

Modified: trunk/lib/boundingbox.h
==============================================================================
--- trunk/lib/boundingbox.h	(original)
+++ trunk/lib/boundingbox.h	Sun May 18 12:44:31 2008
@@ -66,4 +66,9 @@
                      const PolyBBExtras *extra, gboolean closed,
                      Rectangle *rect);
 
+/* helpers for bezier curve calculation */
+void bernstein_develop(const real p[4],real *A,real *B,real *C,real *D);
+real bezier_eval(const real p[4],real u);
+real bezier_eval_tangent(const real p[4],real u);
+
 #endif /* BOUNDINGBOX_H */

Modified: trunk/lib/libdia.def
==============================================================================
--- trunk/lib/libdia.def	(original)
+++ trunk/lib/libdia.def	Sun May 18 12:44:31 2008
@@ -75,6 +75,10 @@
  beziershape_update_boundingbox
  beziershape_update_data
 
+ bernstein_develop
+ bezier_eval
+ bezier_eval_tangent
+
  calculate_arrow_point
 
  color_convert
@@ -682,6 +686,7 @@
  prop_get_data_from_widgets
  prop_dialog_from_widget
  find_prop_by_name
+ dia_object_get_bounding_box
  dia_object_get_enclosing_box
 
  calculate_object_edge

Modified: trunk/objects/Database/table.c
==============================================================================
--- trunk/objects/Database/table.c	(original)
+++ trunk/objects/Database/table.c	Sun May 18 12:44:31 2008
@@ -768,7 +768,7 @@
   DiaObject * obj;
 
   obj = &table->element.object;
-  rect = dia_object_get_enclosing_box (obj);
+  rect = dia_object_get_bounding_box (obj);
   return distance_rectangle_point (rect, point);
 }
 

Modified: trunk/objects/Istar/link.c
==============================================================================
--- trunk/objects/Istar/link.c	(original)
+++ trunk/objects/Istar/link.c	Sun May 18 12:44:31 2008
@@ -105,10 +105,6 @@
 static void link_set_props(Link *link, GPtrArray *props);
 
 
-static void bernstein_develop(const real p[4],real *A,real *B,real *C,real *D);
-static real bezier_eval(const real p[4],real u);
-static real bezier_eval_tangent(const real p[4],real u);
-static Point bezier_line_eval(BezPoint *line,int p,real u);
 static Point compute_annot(Point* p1, Point* p2, Point* pm, double f, double d);
 static void compute_dependency(BezPoint *line, BezPoint *bpl);
 static void compute_line(Point* p1, Point* p2, Point *pm, BezPoint* line);
@@ -266,32 +262,9 @@
   return NULL;
 }
 
-static void
-bernstein_develop(const real p[4],real *A,real *B,real *C,real *D)
+static Point 
+bezier_line_eval(BezPoint *line,int p,real u) 
 {
-  *A = -p[0]+3*p[1]-3*p[2]+p[3];
-  *B = 3*p[0]-6*p[1]+3*p[2];
-  *C = 3*p[1]-3*p[0];
-  *D = p[0];
-  /* if Q(u)=Sum(i=0..3)piBi(u) (Bi(u) being the Bernstein stuff),
-     then Q(u)=Au^3+Bu^2+Cu+p[0]. */
-}
-
-static real
-bezier_eval(const real p[4],real u) {
-  real A,B,C,D;
-  bernstein_develop(p,&A,&B,&C,&D);
-  return A*u*u*u+B*u*u+C*u+D;
-}
-
-static real
-bezier_eval_tangent(const real p[4],real u) {
-  real A,B,C,D;
-  bernstein_develop(p,&A,&B,&C,&D);
-  return 3*A*u*u+2*B*u+C;
-}
-
-static Point bezier_line_eval(BezPoint *line,int p,real u) {
   real bx[4],by[4];
   Point res;
 
@@ -317,7 +290,9 @@
   d is lateral offset
   cx,cy are text width/height
 */
-static Point compute_annot(Point* p1, Point* p2, Point* pm, double f, double d) {
+static Point 
+compute_annot(Point* p1, Point* p2, Point* pm, double f, double d) 
+{
   Point res;
   double dx,dy,k;
 

Modified: trunk/objects/standard/bezier.c
==============================================================================
--- trunk/objects/standard/bezier.c	(original)
+++ trunk/objects/standard/bezier.c	Sun May 18 12:44:31 2008
@@ -415,7 +415,7 @@
    * only checking while selected.  But we'll do that if needed.
    */
   if (renderer->is_interactive &&
-      dia_object_is_selected((DiaObject*)bezierline)) {
+      dia_object_is_selected(&bezierline->bez.object)) {
     bezierconn_draw_control_lines(&bezierline->bez, renderer);
   }
 }
@@ -556,7 +556,19 @@
   } else {
     bezierconn_update_boundingbox(bez);
   }
-
+    /* add control points to the bounding box, needed to make them visible when showing all 
+      * and to remove traces from them */
+  {
+    int i, num_points = bez->numpoints;
+    obj->enclosing_box = obj->bounding_box;
+    /* starting with the second point, the first one is MOVE_TO */
+    for (i = 1; i < num_points; ++i) {
+      if (bez->points[i].type != BEZ_CURVE_TO)
+        continue;
+      rectangle_add_point(&obj->enclosing_box, &bez->points[i].p1);      
+      rectangle_add_point(&obj->enclosing_box, &bez->points[i].p2);      
+    }
+  }
 }
 
 static void

Modified: trunk/objects/standard/beziergon.c
==============================================================================
--- trunk/objects/standard/beziergon.c	(original)
+++ trunk/objects/standard/beziergon.c	Sun May 18 12:44:31 2008
@@ -349,6 +349,17 @@
   extra->border_trans = beziergon->line_width / 2.0;
   beziershape_update_boundingbox(bezier);
 
+  /* update the enclosing box using the control points */
+  {
+    int i, num_points = bezier->numpoints;
+    obj->enclosing_box = obj->bounding_box;
+    for (i = 0; i < num_points; ++i) {
+      if (bezier->points[i].type != BEZ_CURVE_TO)
+        continue;
+      rectangle_add_point(&obj->enclosing_box, &bezier->points[i].p1);      
+      rectangle_add_point(&obj->enclosing_box, &bezier->points[i].p2);      
+    }
+  }
   obj->position = bezier->points[0].p1;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]