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]

Precondition:
dstep > 0.

is_unit_vector(*hat1).

Postcondition:
is_unit_vector(*hat2).

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

References sp_spiral_get_tangent(), and sp_spiral_get_xy().

{
#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 estimatimating
                     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);

      /* Fixme:
         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