Logo Search packages:      
Sourcecode: inkscape version File versions

static void sp_spiral_fit_and_draw ( SPSpiral const *  spiral,
SPCurve c,
double  dstep,
NR::Point  darray[],
NR::Point const &  hat1,
NR::Point hat2,
double *  t 
) [static]

Fit beziers together to spiral and draw it.

Precondition:
dstep > 0.

is_unit_vector(*hat1).

Postcondition:
is_unit_vector(*hat2).

We mustn't increase dstep for subsequent values of i: for large spiral.exp values, rate of growth increases very rapidly.

Todo:
Get the function itself to decide what value of d to use next: ensure that we move at least 0.25 * stroke width, for example. The derivative (as used for get_tangent before normalization) would be useful for estimating the appropriate d value. Or perhaps just start with a small dstep and scale by some small number until we move >= 0.25 * stroke_width. Must revert to the original dstep value for next iteration to avoid the problem mentioned above.

Todo:
We should use better algorithm to specify maximum error.

Definition at line 343 of file sp-spiral.cpp.

References SPSpiral::arg, SAMPLE_SIZE, sp_bezier_fit_cubic_full(), sp_curve_curveto(), sp_curve_lineto(), sp_spiral_get_tangent(), sp_spiral_get_xy(), and SPSpiral::t0.

{
#define BEZIER_SIZE   4
#define FITTING_MAX_BEZIERS 4
#define BEZIER_LENGTH (BEZIER_SIZE * FITTING_MAX_BEZIERS)
      g_assert (dstep > 0);
      g_assert (is_unit_vector (hat1));

      NR::Point bezier[BEZIER_LENGTH];
      double d;
      int depth, i;

      for (d = *t, i = 0; i <= SAMPLE_SIZE; d += dstep, i++) {
            darray[i] = sp_spiral_get_xy(spiral, d);

            /* Avoid useless adjacent dups.  (Otherwise we can have all of darray filled with
               the same value, which upsets chord_length_parameterize.) */
            if ((i != 0)
                && (darray[i] == darray[i - 1])
                && (d < 1.0)) {
                  i--;
                  d += dstep;
                  /** We mustn't increase dstep for subsequent values of
                         * i: for large spiral.exp values, rate of growth
                         * increases very rapidly.
                         */
                        /** \todo
                         * Get the function itself to decide what value of d
                         * to use next: ensure that we move at least 0.25 *
                         * stroke width, for example.  The derivative (as used
                         * for get_tangent before normalization) would be
                         * useful for estimating the appropriate d value.  Or
                         * perhaps just start with a small dstep and scale by
                         * some small number until we move >= 0.25 *
                         * stroke_width.  Must revert to the original dstep
                         * value for next iteration to avoid the problem
                         * mentioned above.
                         */
            }
      }

      double const next_t = d - 2 * dstep;
      /* == t + (SAMPLE_SIZE - 1) * dstep, in absence of dups. */

      hat2 = -sp_spiral_get_tangent (spiral, next_t);

      /** \todo
         * We should use better algorithm to specify maximum error.
         */
      depth = sp_bezier_fit_cubic_full (bezier, NULL, darray, SAMPLE_SIZE,
                                hat1, hat2,
                                SPIRAL_TOLERANCE*SPIRAL_TOLERANCE,
                                FITTING_MAX_BEZIERS);
      g_assert(depth * BEZIER_SIZE <= gint(G_N_ELEMENTS(bezier)));
#ifdef SPIRAL_DEBUG
      if (*t == spiral->t0 || *t == 1.0)
            g_print ("[%s] depth=%d, dstep=%g, t0=%g, t=%g, arg=%g\n",
                   debug_state, depth, dstep, spiral->t0, *t, spiral->arg);
#endif
      if (depth != -1) {
            for (i = 0; i < 4*depth; i += 4) {
                  sp_curve_curveto (c,
                                bezier[i + 1],
                                bezier[i + 2],
                                bezier[i + 3]);
            }
      } else {
#ifdef SPIRAL_VERBOSE
            g_print ("cant_fit_cubic: t=%g\n", *t);
#endif
            for (i = 1; i < SAMPLE_SIZE; i++)
                  sp_curve_lineto (c, darray[i]);
      }
      *t = next_t;
      g_assert (is_unit_vector (hat2));
}


Generated by  Doxygen 1.6.0   Back to index