summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Muizelaar <jmuizelaar@mozilla.com>2010-01-24 21:47:20 -0500
committerJeff Muizelaar <jmuizelaar@mozilla.com>2010-01-24 21:47:20 -0500
commit58aec6f0cc19a4ea681e1d1541cd05bac2bb40b4 (patch)
tree29db642434d35debeb497a2bf615ce9f753aa9d8
parent1255c081bf30de4d082038e89c5ad4db32916596 (diff)
Cleanup
-rw-r--r--src/cairo-spline-offset.c168
1 files changed, 85 insertions, 83 deletions
diff --git a/src/cairo-spline-offset.c b/src/cairo-spline-offset.c
index 7a7e49f3..5969873a 100644
--- a/src/cairo-spline-offset.c
+++ b/src/cairo-spline-offset.c
@@ -602,31 +602,33 @@ Which simplifies to the following:
*t = 0.5;
return !is_curvy_t(bzprod, sizeof(bzprod)/sizeof(bzprod[0])-1, max_error, t);
}
-void print_knot(knots_t c) {
+
+void
+print_knot (knots_t c) {
//printf("(%.13a %.13a) (%.13a %.13a) (%.13a %.13a) (%.13a %.13a)\n", c.a.x, c.a.y, c.b.x, c.b.y, c.c.x, c.c.y, c.d.x, c.d.y);
printf("(%.5f %.5f) (%.5f %.5f) (%.5f %.5f) (%.5f %.5f)\n", c.a.x, c.a.y, c.b.x, c.b.y, c.c.x, c.c.y, c.d.x, c.d.y);
}
static knots_t
-convolve_with_circle (knots_t self, double dist)
+convolve_with_circle (knots_t spline, double dist)
{
- vector_t in_normal = normalize(perp(begin_tangent(self)));
- vector_t out_normal = normalize(perp(end_tangent(self)));
+ vector_t in_normal = normalize(perp(begin_tangent(spline)));
+ vector_t out_normal = normalize(perp(end_tangent(spline)));
/* find an arc the goes from the input normal to the output_normal */
knots_t arc_spline = arc_segment_cart(in_normal, out_normal, 1, in_normal, out_normal);
//printf("%f %f, %f %f\n", in_normal.x, in_normal.y, out_normal.x, out_normal.y);
- /* approximate convolving 'self' with the arc spline */
- self.a.x += dist * arc_spline.a.x;
- self.a.y += dist * arc_spline.a.y;
- self.b.x += dist * arc_spline.b.x;
- self.b.y += dist * arc_spline.b.y;
- self.c.x += dist * arc_spline.c.x;
- self.c.y += dist * arc_spline.c.y;
- self.d.x += dist * arc_spline.d.x;
- self.d.y += dist * arc_spline.d.y;
-
- return self;
+ /* approximate convolving 'spline' with the arc spline (XXX: is convolve the right word?) */
+ spline.a.x += dist * arc_spline.a.x;
+ spline.a.y += dist * arc_spline.a.y;
+ spline.b.x += dist * arc_spline.b.x;
+ spline.b.y += dist * arc_spline.b.y;
+ spline.c.x += dist * arc_spline.c.x;
+ spline.c.y += dist * arc_spline.c.y;
+ spline.d.x += dist * arc_spline.d.x;
+ spline.d.y += dist * arc_spline.d.y;
+
+ return spline;
}
/* This approach is inspired by "Approximation of circular arcs and offset curves by Bezier curves of high degree"
@@ -649,11 +651,11 @@ approximate_offset_curve_with_shin (knots_t self, double dist, void (*curve_fn)(
we want to ensure that we don't have any inflection points in our spline */
inflection_points_t t_inflect = inflection_points(self);
+ /* split the curve at the inflection points and convolve each with an approximation of
+ * a circle */
knots_t remaining = self;
double adjusted_inflect = t_inflect.t2;
- printf("WITH SHIN\n");
-
/* check that the first inflection point is in range */
if (t_inflect.t1 > 0 && t_inflect.t1 < 1) {
/* split at the inflection point */
@@ -845,74 +847,74 @@ knot_offset(knots_t self, double width, cairo_bool_t *is_parallel)
* good offset approximation down to the resolution of a double.
*/
void
-curve_offset(knots_t self, double dist, double tolerance, void (*curve_fn)(void *, knots_t), void *closure)
+curve_offset (knots_t self, double dist, double tolerance, void (*curve_fn)(void *, knots_t), void *closure)
{
- cairo_bool_t recurse;
- double break_point;
- double max_error = 0.01;//500;//0.01;//tolerance;
- knots_t offset = knot_offset(self, dist, &recurse);
-
- printf("curve result: ");
- print_knot(offset);
- //double max_error = 0.01;//tolerance;
- //bool recurse = !error_within_bounds(self, offset, dist, max_error);
- //bool recurse = !error_within_bounds_muiz(self, offset, dist, 1.5*max_error/2.4);
- if (!recurse) {
- // we need to make sure we have a finite offset before checking the error
- ensure_finite(offset);
- recurse = !error_within_bounds_elber(self, offset, dist, max_error, &break_point);
- } else {
- /* TODO: we could probably choose a better place to split than halfway
- * for times when we know we're going to recurse */
- break_point = .5;
+ cairo_bool_t recurse;
+ double break_point;
+ double max_error = 0.01;//500;//0.01;//tolerance;
+ knots_t offset = knot_offset(self, dist, &recurse);
+
+ printf("curve result: ");
+ print_knot(offset);
+ //double max_error = 0.01;//tolerance;
+ //bool recurse = !error_within_bounds(self, offset, dist, max_error);
+ //bool recurse = !error_within_bounds_muiz(self, offset, dist, 1.5*max_error/2.4);
+ if (!recurse) {
+ // we need to make sure we have a finite offset before checking the error
+ ensure_finite(offset);
+ recurse = !error_within_bounds_elber(self, offset, dist, max_error, &break_point);
+ } else {
+ /* TODO: we could probably choose a better place to split than halfway
+ * for times when we know we're going to recurse */
+ break_point = .5;
+ }
+ printf("recurse?: %d\n", recurse);
+ if (recurse) {
+ // error is too large. subdivide on max t and try again.
+ knots_t left = self;
+ knots_t right;
+
+ cairo_bool_t is_continuous;
+
+ /* We need to do something to handle regions of high curvature
+ *
+ * skia uses the first and second derivitives at the points of 'max curvature' to check for
+ * pinchynes.
+ * qt tests whether the points are close and reverse direction.
+ * float l = (orig->x1 - orig->x2)*(orig->x1 - orig->x2) + (orig->y3 - orig->y4)*(orig->y3 - orig->y4);
+ * float dot = (orig->x1 - orig->x2)*(orig->x3 - orig->x4) + (orig->y1 - orig->y2)*(orig->y3 - orig->y4);
+ *
+ * we just check if the knot is flat and has large error.
+ */
+ if (is_knot_flat(self)) {
+ /* we don't want to recurse anymore because we're pretty flat,
+ * instead approximate the offset curve with an arc.
+ *
+ * The previously generated offset curve can become really bad if the the intersections
+ * are far away from the original curve (self) */
+
+ approximate_offset_curve_with_shin (self, dist, curve_fn, closure);
+ return;
}
- printf("recurse?: %d\n", recurse);
- if (recurse) {
- // error is too large. subdivide on max t and try again.
- knots_t left = self;
- knots_t right;
-
- cairo_bool_t is_continuous;
-
- /* We need to do something to handle regions of high curvature
- *
- * skia uses the first and second derivitives at the points of 'max curvature' to check for
- * pinchynes.
- * qt tests whether the points are close and reverse direction.
- * float l = (orig->x1 - orig->x2)*(orig->x1 - orig->x2) + (orig->y3 - orig->y4)*(orig->y3 - orig->y4);
- * float dot = (orig->x1 - orig->x2)*(orig->x3 - orig->x4) + (orig->y1 - orig->y2)*(orig->y3 - orig->y4);
- *
- * we just check if the knot is flat and has large error.
- */
- if (is_knot_flat(self)) {
- /* we don't want to recurse anymore because we're pretty flat,
- * instead approximate the offset curve with an arc.
- *
- * The previously generated offset curve can become really bad if the the intersections
- * are far away from the original curve (self) */
-
- approximate_offset_curve_with_shin (self, dist, curve_fn, closure);
- return;
- }
-
- is_continuous = _de_casteljau_t(&left, &right, break_point);
-
- //printf("offset left\n");
- //print_knot(left);
- curve_offset(left, dist, tolerance, curve_fn, closure);
-
- if (!is_continuous) {
- // add circle
- /* we can use the exit the normal from the left side
- as the begining normal of our cusp */
- vector_t normal = perp (end_tangent (left));
- printf("semi cusp\n");
- semi_circle (left.d.x, left.d.y, dist, normal, curve_fn, closure);
- }
-
- curve_offset(right, dist, tolerance, curve_fn, closure);
- } else {
- curve_fn(closure, offset);
+
+ is_continuous = _de_casteljau_t(&left, &right, break_point);
+
+ //printf("offset left\n");
+ //print_knot(left);
+ curve_offset(left, dist, tolerance, curve_fn, closure);
+
+ if (!is_continuous) {
+ // add circle
+ /* we can use the exit the normal from the left side
+ as the begining normal of our cusp */
+ vector_t normal = perp (end_tangent (left));
+ printf("semi cusp\n");
+ semi_circle (left.d.x, left.d.y, dist, normal, curve_fn, closure);
}
+
+ curve_offset(right, dist, tolerance, curve_fn, closure);
+ } else {
+ curve_fn(closure, offset);
+ }
}