[dia] Bezier* : fix some more ignorance regarding BEZ_LINE_TO
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] Bezier* : fix some more ignorance regarding BEZ_LINE_TO
- Date: Wed, 3 Oct 2012 20:05:03 +0000 (UTC)
commit 62dab7da687c4898cef9114a2017955c41a177a0
Author: Hans Breuer <hans breuer org>
Date: Wed Oct 3 21:34:14 2012 +0200
Bezier* : fix some more ignorance regarding BEZ_LINE_TO
lib/bezier-common.c | 42 +++++++++++++++++++++++++++-
lib/bezier-common.h | 2 +
lib/bezier_conn.c | 33 ----------------------
lib/bezier_conn.h | 2 -
lib/beziershape.c | 61 +++++++++++++----------------------------
lib/beziershape.h | 2 -
lib/geometry.c | 10 ++++---
lib/geometry.h | 3 +-
objects/standard/bezier.c | 9 +++---
objects/standard/beziergon.c | 4 +-
10 files changed, 76 insertions(+), 92 deletions(-)
---
diff --git a/lib/bezier-common.c b/lib/bezier-common.c
index 52260c1..063bc6e 100644
--- a/lib/bezier-common.c
+++ b/lib/bezier-common.c
@@ -108,6 +108,40 @@ beziercommon_copy (BezierCommon *from, BezierCommon *to)
}
/*!
+ * \brief Return the segment of the bezier closest to a given point.
+ * @param bezier The bezier object
+ * @param point A point to find the closest segment to.
+ * @param line_width Line width of the bezier line.
+ * @return The index of the segment closest to point.
+ * \memberof BezierCommon
+ */
+int
+beziercommon_closest_segment (BezierCommon *bezier,
+ const Point *point,
+ real line_width)
+{
+ Point last;
+ int i;
+ real dist = G_MAXDOUBLE;
+ int closest;
+
+ closest = 0;
+ last = bezier->points[0].p1;
+ for (i = 0; i < bezier->num_points - 1; i++) {
+ real new_dist = distance_bez_seg_point(&last, &bezier->points[i+1], line_width, point);
+ if (new_dist < dist) {
+ dist = new_dist;
+ closest = i;
+ }
+ if (bezier->points[i+1].type == BEZ_CURVE_TO)
+ last = bezier->points[i+1].p3;
+ else
+ last = bezier->points[i+1].p1;
+ }
+ return closest;
+}
+
+/*!
* \brief Draw control lines of the given _BezPoint array
*/
void
@@ -129,7 +163,11 @@ bezier_draw_control_lines (int num_points,
startpoint = points[0].p1;
for (i = 1; i < num_points; i++) {
DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &startpoint, &points[i].p1, &line_colour);
- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &points[i].p2, &points[i].p3, &line_colour);
- startpoint = points[i].p3;
+ if (points[i].type == BEZ_CURVE_TO) {
+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &points[i].p2, &points[i].p3, &line_colour);
+ startpoint = points[i].p3;
+ } else {
+ startpoint = points[i].p1;
+ }
}
}
diff --git a/lib/bezier-common.h b/lib/bezier-common.h
index 7f115da..428de71 100644
--- a/lib/bezier-common.h
+++ b/lib/bezier-common.h
@@ -25,6 +25,7 @@
#define BEZIER_COMMON_H
#include "diatypes.h"
+#include "geometry.h" /* for real */
typedef enum {
BEZ_CORNER_SYMMETRIC,
@@ -46,6 +47,7 @@ struct _BezierCommon {
void beziercommon_set_points (BezierCommon *bezier, int num, const BezPoint *pts);
void beziercommon_copy (BezierCommon *from, BezierCommon *to);
+int beziercommon_closest_segment (BezierCommon *bezier, const Point *point, real line_width);
void bezier_draw_control_lines (int num_points, BezPoint *pts, DiaRenderer *renderer);
diff --git a/lib/bezier_conn.c b/lib/bezier_conn.c
index 3b4b6ed..190bb17 100644
--- a/lib/bezier_conn.c
+++ b/lib/bezier_conn.c
@@ -267,39 +267,6 @@ bezierconn_move (BezierConn *bezier, Point *to)
}
/*!
- * \brief Return the segment of the bezier closest to a given point.
- * @param bezier The bezier object
- * @param point A point to find the closest segment to.
- * @param line_width Line width of the bezier line.
- * @return The index of the segment closest to point.
- * \memberof BezierConn
- */
-int
-bezierconn_closest_segment (BezierConn *bezier,
- Point *point,
- real line_width)
-{
- Point last;
- int i;
- real dist = G_MAXDOUBLE;
- int closest;
-
- closest = 0;
- last = bezier->bezier.points[0].p1;
- for (i = 0; i < bezier->bezier.num_points - 1; i++) {
- real new_dist = distance_bez_seg_point(&last, &bezier->bezier.points[i+1].p1,
- &bezier->bezier.points[i+1].p2, &bezier->bezier.points[i+1].p3,
- line_width, point);
- if (new_dist < dist) {
- dist = new_dist;
- closest = i;
- }
- last = bezier->bezier.points[i+1].p3;
- }
- return closest;
-}
-
-/*!
* \brief Return the handle closest to a given point.
* @param bezier A bezier object
* @param point A point to find distances from
diff --git a/lib/bezier_conn.h b/lib/bezier_conn.h
index ed14fef..b11c9d1 100644
--- a/lib/bezier_conn.h
+++ b/lib/bezier_conn.h
@@ -66,8 +66,6 @@ real bezierconn_distance_from(BezierConn *bez, Point *point,
real line_width);
Handle *bezierconn_closest_handle(BezierConn *bez, Point *point);
Handle *bezierconn_closest_major_handle(BezierConn *bez, Point *point);
-int bezierconn_closest_segment(BezierConn *bez, Point *point,
- real line_width);
#define BEZCONN_COMMON_PROPERTIES \
OBJECT_COMMON_PROPERTIES, \
diff --git a/lib/beziershape.c b/lib/beziershape.c
index 89c3d11..1c0cbde 100644
--- a/lib/beziershape.c
+++ b/lib/beziershape.c
@@ -278,40 +278,6 @@ beziershape_move (BezierShape *bezier, Point *to)
}
/*!
- * \brief Return the segment of the bezier closest to a given point.
- * @param bezier The bezier object
- * @param point A point to find the closest segment to.
- * @param line_width Line width of the bezier line.
- * @return The index of the segment closest to point.
- * \memberof BezierShape
- */
-int
-beziershape_closest_segment (BezierShape *bezier,
- Point *point,
- real line_width)
-{
- Point last;
- int i;
- real dist = G_MAXDOUBLE;
- int closest;
-
- closest = 0;
- last = bezier->bezier.points[0].p1;
- /* the first point is just move-to so there is no need to consider p2,p3 of it */
- for (i = 1; i < bezier->bezier.num_points; i++) {
- real new_dist = distance_bez_seg_point(&last, &bezier->bezier.points[i].p1,
- &bezier->bezier.points[i].p2, &bezier->bezier.points[i].p3,
- line_width, point);
- if (new_dist < dist) {
- dist = new_dist;
- closest = i;
- }
- last = bezier->bezier.points[i].p3;
- }
- return closest;
-}
-
-/*!
* \brief Return the handle closest to a given point.
* @param bezier A bezier object
* @param point A point to find distances from
@@ -484,6 +450,11 @@ beziershape_add_segment (BezierShape *bezier,
Point startpoint;
Point other;
+ g_return_val_if_fail (segment >= 0 && segment < bezier->bezier.num_points, NULL);
+
+ if (segment == 0) /* don't want to add this, just take the next one */
+ ++segment;
+
if (segment != 1)
startpoint = bezier->bezier.points[segment-1].p3;
else
@@ -763,15 +734,23 @@ beziershape_update_data (BezierShape *bezier)
obj->connections[2*i-2]->pos = last;
obj->connections[2*i-2]->directions =
find_slope_directions(last, bezier->bezier.points[i].p1);
- obj->connections[2*i-1]->pos.x =
- (last.x + 3*bezier->bezier.points[i].p1.x + 3*bezier->bezier.points[i].p2.x +
- bezier->bezier.points[i].p3.x)/8;
- obj->connections[2*i-1]->pos.y =
- (last.y + 3*bezier->bezier.points[i].p1.y + 3*bezier->bezier.points[i].p2.y +
- bezier->bezier.points[i].p3.y)/8;
+ if (bezier->bezier.points[i].type == BEZ_CURVE_TO) {
+ obj->connections[2*i-1]->pos.x =
+ (last.x + 3*bezier->bezier.points[i].p1.x + 3*bezier->bezier.points[i].p2.x +
+ bezier->bezier.points[i].p3.x)/8;
+ obj->connections[2*i-1]->pos.y =
+ (last.y + 3*bezier->bezier.points[i].p1.y + 3*bezier->bezier.points[i].p2.y +
+ bezier->bezier.points[i].p3.y)/8;
+ } else {
+ obj->connections[2*i-1]->pos.x = (last.x + bezier->bezier.points[i].p1.x) / 2;
+ obj->connections[2*i-1]->pos.y = (last.y + bezier->bezier.points[i].p1.y) / 2;
+ }
obj->connections[2*i-1]->directions =
find_slope_directions(slopepoint1, slopepoint2);
- last = bezier->bezier.points[i].p3;
+ if (bezier->bezier.points[i].type == BEZ_CURVE_TO)
+ last = bezier->bezier.points[i].p3;
+ else
+ last = bezier->bezier.points[i].p1;
}
/* Find the middle of the object (or some approximation at least) */
diff --git a/lib/beziershape.h b/lib/beziershape.h
index e7ba98b..d5c1bb0 100644
--- a/lib/beziershape.h
+++ b/lib/beziershape.h
@@ -70,8 +70,6 @@ real beziershape_distance_from(BezierShape *bezier, Point *point,
real line_width);
Handle *beziershape_closest_handle(BezierShape *bezier, Point *point);
Handle *beziershape_closest_major_handle(BezierShape *bezier, Point *point);
-int beziershape_closest_segment(BezierShape *bezier, Point *point,
- real line_width);
#define BEZSHAPE_COMMON_PROPERTIES \
OBJECT_COMMON_PROPERTIES, \
diff --git a/lib/geometry.c b/lib/geometry.c
index 12e7bb5..eb0cf3f 100644
--- a/lib/geometry.c
+++ b/lib/geometry.c
@@ -290,12 +290,14 @@ bez_point_distance_and_ray_crosses(const Point *b1,
}
real
-distance_bez_seg_point(const Point *b1, const Point *b2,
- const Point *b3, const Point *b4,
+distance_bez_seg_point(const Point *b1, const BezPoint *b2,
real line_width, const Point *point)
{
- return bez_point_distance_and_ray_crosses(b1, b2, b3, b4,
- line_width, point, NULL);
+ if (b2->type == BEZ_CURVE_TO)
+ return bez_point_distance_and_ray_crosses(b1, &b2->p1, &b2->p2, &b2->p3,
+ line_width, point, NULL);
+ else
+ return distance_line_point(b1, &b2->p1, line_width, point);
}
real
diff --git a/lib/geometry.h b/lib/geometry.h
index 6b48c47..b8cb893 100644
--- a/lib/geometry.h
+++ b/lib/geometry.h
@@ -355,8 +355,7 @@ real distance_polygon_point(const Point *poly, guint npoints,
real line_width, const Point *point);
/* bezier distance calculations */
-real distance_bez_seg_point(const Point *b1, const Point *b2,
- const Point *b3, const Point *b4,
+real distance_bez_seg_point(const Point *b1, const BezPoint *b2,
real line_width, const Point *point);
real distance_bez_line_point(const BezPoint *b, guint npoints,
real line_width, const Point *point);
diff --git a/objects/standard/bezier.c b/objects/standard/bezier.c
index a40c610..63ac1d0 100644
--- a/objects/standard/bezier.c
+++ b/objects/standard/bezier.c
@@ -210,9 +210,11 @@ bezierline_distance_from(Bezierline *bezierline, Point *point)
}
}
-static int bezierline_closest_segment(Bezierline *bezierline, Point *point) {
+static int
+bezierline_closest_segment(Bezierline *bezierline, Point *point)
+{
BezierConn *bez = &bezierline->bez;
- return bezierconn_closest_segment(bez, point, bezierline->line_width);
+ return beziercommon_closest_segment(&bez->bezier, point, bezierline->line_width);
}
static void
@@ -732,8 +734,7 @@ bezierline_delete_segment_callback (DiaObject *obj, Point *clicked, gpointer dat
Bezierline *bezierline = (Bezierline*) obj;
ObjectChange *change;
- seg_nr = bezierconn_closest_segment(&bezierline->bez, clicked,
- bezierline->line_width);
+ seg_nr = beziercommon_closest_segment(&bezierline->bez.bezier, clicked, bezierline->line_width);
change = bezierconn_remove_segment(&bezierline->bez, seg_nr+1);
bezierline_update_data(bezierline);
diff --git a/objects/standard/beziergon.c b/objects/standard/beziergon.c
index de39b1e..db43886 100644
--- a/objects/standard/beziergon.c
+++ b/objects/standard/beziergon.c
@@ -171,8 +171,8 @@ beziergon_distance_from(Beziergon *beziergon, Point *point)
static int
beziergon_closest_segment(Beziergon *beziergon, Point *point)
{
- return beziershape_closest_segment(&beziergon->bezier, point,
- beziergon->line_width);
+ return beziercommon_closest_segment(&beziergon->bezier.bezier, point,
+ beziergon->line_width);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]