spiro.cpp File Reference

Go to the source code of this file.

Classes

struct  spiro_seg_s
struct  bandmat

Defines

#define ORDER   12

Functions

void integrate_spiro (const double ks[4], double xy[2])
static double compute_ends (const double ks[4], double ends[2][4], double seg_ch)
static void compute_pderivs (const spiro_seg *s, double ends[2][4], double derivs[4][2][4], int jinc)
static double mod_2pi (double th)
static spiro_segsetup_path (const spiro_cp *src, int n)
static void bandec11 (bandmat *m, int *perm, int n)
static void banbks11 (const bandmat *m, const int *perm, double *v, int n)
int compute_jinc (char ty0, char ty1)
int count_vec (const spiro_seg *s, int nseg)
static void add_mat_line (bandmat *m, double *v, double derivs[4], double x, double y, int j, int jj, int jinc, int nmat)
static double spiro_iter (spiro_seg *s, bandmat *m, int *perm, double *v, int n)
int solve_spiro (spiro_seg *s, int nseg)
static void spiro_seg_to_bpath (const double ks[4], double x0, double y0, double x1, double y1, bezctx *bc, int depth)
spiro_segrun_spiro (const spiro_cp *src, int n)
void free_spiro (spiro_seg *s)
void spiro_to_bpath (const spiro_seg *s, int n, bezctx *bc)
double get_knot_th (const spiro_seg *s, int i)

Variables

int n = 4

Define Documentation

#define ORDER   12

Definition at line 53 of file spiro.cpp.


Function Documentation

static void add_mat_line ( bandmat m,
double v,
double  derivs[4],
double  x,
double  y,
int  j,
int  jj,
int  jinc,
int  nmat 
) [static]

Definition at line 630 of file spiro.cpp.

References org::w3c::dom::svg::a.

Referenced by spiro_iter().

00633 {
00634     int k;
00635 
00636     if (jj >= 0) {
00637     int joff =  (j + 5 - jj + nmat) % nmat;
00638     if (nmat < 6) {
00639         joff = j + 5 - jj;
00640     } else if (nmat == 6) {
00641         joff = 2 + (j + 3 - jj + nmat) % nmat;
00642     }
00643 #ifdef VERBOSE
00644     printf("add_mat_line j=%d jj=%d jinc=%d nmat=%d joff=%d\n", j, jj, jinc, nmat, joff);
00645 #endif
00646     v[jj] += x;
00647     for (k = 0; k < jinc; k++)
00648         m[jj].a[joff + k] += y * derivs[k];
00649     }
00650 }

static void banbks11 ( const bandmat m,
const int *  perm,
double v,
int  n 
) [static]

Definition at line 576 of file spiro.cpp.

References bandmat::a, org::w3c::dom::svg::a, Barcode::Code39Ext::i, and voronoi::x.

Referenced by spiro_iter().

00577 {
00578     int i, k, l;
00579 
00580     /* forward substitution */
00581     l = 5;
00582     for (k = 0; k < n; k++) {
00583     i = perm[k];
00584     if (i != k) {
00585         double tmp = v[k];
00586         v[k] = v[i];
00587         v[i] = tmp;
00588     }
00589     if (l < n) l++;
00590     for (i = k + 1; i < l; i++)
00591         v[i] -= m[k].al[i - k - 1] * v[k];
00592     }
00593 
00594     /* back substitution */
00595     l = 1;
00596     for (i = n - 1; i >= 0; i--) {
00597     double x = v[i];
00598     for (k = 1; k < l; k++)
00599         x -= m[i].a[k] * v[k + i];
00600     v[i] = x / m[i].a[0];
00601     if (l < 11) l++;
00602     }
00603 }

static void bandec11 ( bandmat m,
int *  perm,
int  n 
) [static]

Definition at line 528 of file spiro.cpp.

References bandmat::a, org::w3c::dom::svg::a, bandmat::al, addnodes::e, Barcode::Code39Ext::i, and voronoi::x.

Referenced by spiro_iter().

00529 {
00530     int i, j, k;
00531     int l;
00532 
00533     /* pack top triangle to the left. */
00534     for (i = 0; i < 5; i++) {
00535     for (j = 0; j < i + 6; j++)
00536         m[i].a[j] = m[i].a[j + 5 - i];
00537     for (; j < 11; j++)
00538         m[i].a[j] = 0.;
00539     }
00540     l = 5;
00541     for (k = 0; k < n; k++) {
00542     int pivot = k;
00543     double pivot_val = m[k].a[0];
00544     double pivot_scale;
00545 
00546     l = l < n ? l + 1 : n;
00547 
00548     for (j = k + 1; j < l; j++)
00549         if (fabs(m[j].a[0]) > fabs(pivot_val)) {
00550         pivot_val = m[j].a[0];
00551         pivot = j;
00552         }
00553 
00554     perm[k] = pivot;
00555     if (pivot != k) {
00556         for (j = 0; j < 11; j++) {
00557         double tmp = m[k].a[j];
00558         m[k].a[j] = m[pivot].a[j];
00559         m[pivot].a[j] = tmp;
00560         }
00561     }
00562 
00563     if (fabs(pivot_val) < 1e-12) pivot_val = 1e-12;
00564     pivot_scale = 1. / pivot_val;
00565     for (i = k + 1; i < l; i++) {
00566         double x = m[i].a[0] * pivot_scale;
00567         m[k].al[i - k - 1] = x;
00568         for (j = 1; j < 11; j++)
00569         m[i].a[j - 1] = m[i].a[j] - x * m[k].a[j];
00570         m[i].a[10] = 0.;
00571     }
00572     }
00573 }

static double compute_ends ( const double  ks[4],
double  ends[2][4],
double  seg_ch 
) [static]

Definition at line 422 of file spiro.cpp.

References Geom::atan2(), integrate_spiro(), and polyhedron_3d::th.

Referenced by compute_pderivs(), and get_knot_th().

00423 {
00424     double xy[2];
00425     double ch, th;
00426     double l, l2, l3;
00427     double th_even, th_odd;
00428     double k0_even, k0_odd;
00429     double k1_even, k1_odd;
00430     double k2_even, k2_odd;
00431 
00432     integrate_spiro(ks, xy);
00433     ch = hypot(xy[0], xy[1]);
00434     th = atan2(xy[1], xy[0]);
00435     l = ch / seg_ch;
00436 
00437     th_even = .5 * ks[0] + (1./48) * ks[2];
00438     th_odd = .125 * ks[1] + (1./384) * ks[3] - th;
00439     ends[0][0] = th_even - th_odd;
00440     ends[1][0] = th_even + th_odd;
00441     k0_even = l * (ks[0] + .125 * ks[2]);
00442     k0_odd = l * (.5 * ks[1] + (1./48) * ks[3]);
00443     ends[0][1] = k0_even - k0_odd;
00444     ends[1][1] = k0_even + k0_odd;
00445     l2 = l * l;
00446     k1_even = l2 * (ks[1] + .125 * ks[3]);
00447     k1_odd = l2 * .5 * ks[2];
00448     ends[0][2] = k1_even - k1_odd;
00449     ends[1][2] = k1_even + k1_odd;
00450     l3 = l2 * l;
00451     k2_even = l3 * ks[2];
00452     k2_odd = l3 * .5 * ks[3];
00453     ends[0][3] = k2_even - k2_odd;
00454     ends[1][3] = k2_even + k2_odd;
00455 
00456     return l;
00457 }

int compute_jinc ( char  ty0,
char  ty1 
)

Definition at line 605 of file spiro.cpp.

Referenced by count_vec(), and spiro_iter().

00606 {
00607     if (ty0 == 'o' || ty1 == 'o' ||
00608     ty0 == ']' || ty1 == '[')
00609     return 4;
00610     else if (ty0 == 'c' && ty1 == 'c')
00611     return 2;
00612     else if (((ty0 == '{' || ty0 == 'v' || ty0 == '[') && ty1 == 'c') ||
00613          (ty0 == 'c' && (ty1 == '}' || ty1 == 'v' || ty1 == ']')))
00614     return 1;
00615     else
00616     return 0;
00617 }

static void compute_pderivs ( const spiro_seg s,
double  ends[2][4],
double  derivs[4][2][4],
int  jinc 
) [static]

Definition at line 460 of file spiro.cpp.

References compute_ends(), CxxTest::delta(), Barcode::Code39Ext::i, spiro_seg_s::ks, and spiro_seg_s::seg_ch.

Referenced by spiro_iter().

00462 {
00463     double recip_d = 2e6;
00464     double delta = 1./ recip_d;
00465     double try_ks[4];
00466     double try_ends[2][4];
00467     int i, j, k;
00468 
00469     compute_ends(s->ks, ends, s->seg_ch);
00470     for (i = 0; i < jinc; i++) {
00471     for (j = 0; j < 4; j++)
00472         try_ks[j] = s->ks[j];
00473     try_ks[i] += delta;
00474     compute_ends(try_ks, try_ends, s->seg_ch);
00475     for (k = 0; k < 2; k++)
00476         for (j = 0; j < 4; j++)
00477         derivs[j][k][i] = recip_d * (try_ends[k][j] - ends[k][j]);
00478     }
00479 }

int count_vec ( const spiro_seg s,
int  nseg 
)

Definition at line 619 of file spiro.cpp.

References compute_jinc(), Barcode::Code39Ext::i, and n.

Referenced by solve_spiro(), and spiro_iter().

00620 {
00621     int i;
00622     int n = 0;
00623 
00624     for (i = 0; i < nseg; i++)
00625     n += compute_jinc(s[i].ty, s[i + 1].ty);
00626     return n;
00627 }

void free_spiro ( spiro_seg s  ) 

Definition at line 889 of file spiro.cpp.

00890 {
00891     free(s);
00892 }

double get_knot_th ( const spiro_seg s,
int  i 
)

Definition at line 914 of file spiro.cpp.

References compute_ends(), and spiro_seg_s::seg_th.

00915 {
00916     double ends[2][4];
00917 
00918     if (i == 0) {
00919     compute_ends(s[i].ks, ends, s[i].seg_ch);
00920     return s[i].seg_th - ends[0][0];
00921     } else {
00922     compute_ends(s[i - 1].ks, ends, s[i - 1].seg_ch);
00923     return s[i - 1].seg_th + ends[1][0];
00924     }
00925 }

void integrate_spiro ( const double  ks[4],
double  xy[2] 
)

Definition at line 58 of file spiro.cpp.

References Geom::cos(), addnodes::e, Barcode::Code39Ext::i, n, Geom::sin(), polyhedron_3d::th, voronoi::x, and voronoi::y.

Referenced by compute_ends(), and spiro_seg_to_bpath().

00059 {
00060 #if 0
00061     int n = 1024;
00062 #endif
00063     double th1 = ks[0];
00064     double th2 = .5 * ks[1];
00065     double th3 = (1./6) * ks[2];
00066     double th4 = (1./24) * ks[3];
00067     double x, y;
00068     double ds = 1. / n;
00069     double ds2 = ds * ds;
00070     double ds3 = ds2 * ds;
00071     double k0 = ks[0] * ds;
00072     double k1 = ks[1] * ds;
00073     double k2 = ks[2] * ds;
00074     double k3 = ks[3] * ds;
00075     int i;
00076     double s = .5 * ds - .5;
00077 
00078     x = 0;
00079     y = 0;
00080 
00081     for (i = 0; i < n; i++) {
00082 
00083 #if ORDER > 2
00084     double u, v;
00085     double km0, km1, km2, km3;
00086 
00087     if (n == 1) {
00088         km0 = k0;
00089         km1 = k1 * ds;
00090         km2 = k2 * ds2;
00091     } else {
00092         km0 = (((1./6) * k3 * s + .5 * k2) * s + k1) * s + k0;
00093         km1 = ((.5 * k3 * s + k2) * s + k1) * ds;
00094         km2 = (k3 * s + k2) * ds2;
00095     }
00096     km3 = k3 * ds3;
00097 #endif
00098 
00099     {
00100 
00101 #if ORDER == 4
00102     double km0_2 = km0 * km0;
00103     u = 24 - km0_2;
00104     v = km1;
00105 #endif
00106 
00107 #if ORDER == 6
00108     double km0_2 = km0 * km0;
00109     double km0_4 = km0_2 * km0_2;
00110     u = 24 - km0_2 + (km0_4 - 4 * km0 * km2 - 3 * km1 * km1) * (1./80);
00111     v = km1 + (km3 - 6 * km0_2 * km1) * (1./80);
00112 #endif
00113 
00114 #if ORDER == 8
00115     double t1_1 = km0;
00116     double t1_2 = .5 * km1;
00117     double t1_3 = (1./6) * km2;
00118     double t1_4 = (1./24) * km3;
00119     double t2_2 = t1_1 * t1_1;
00120     double t2_3 = 2 * (t1_1 * t1_2);
00121     double t2_4 = 2 * (t1_1 * t1_3) + t1_2 * t1_2;
00122     double t2_5 = 2 * (t1_1 * t1_4 + t1_2 * t1_3);
00123     double t2_6 = 2 * (t1_2 * t1_4) + t1_3 * t1_3;
00124     double t3_4 = t2_2 * t1_2 + t2_3 * t1_1;
00125     double t3_6 = t2_2 * t1_4 + t2_3 * t1_3 + t2_4 * t1_2 + t2_5 * t1_1;
00126     double t4_4 = t2_2 * t2_2;
00127     double t4_5 = 2 * (t2_2 * t2_3);
00128     double t4_6 = 2 * (t2_2 * t2_4) + t2_3 * t2_3;
00129     double t5_6 = t4_4 * t1_2 + t4_5 * t1_1;
00130     double t6_6 = t4_4 * t2_2;
00131     u = 1;
00132     v = 0;
00133     v += (1./12) * t1_2 + (1./80) * t1_4;
00134     u -= (1./24) * t2_2 + (1./160) * t2_4 + (1./896) * t2_6;
00135     v -= (1./480) * t3_4 + (1./2688) * t3_6;
00136     u += (1./1920) * t4_4 + (1./10752) * t4_6;
00137     v += (1./53760) * t5_6;
00138     u -= (1./322560) * t6_6;
00139 #endif
00140 
00141 #if ORDER == 10
00142     double t1_1 = km0;
00143     double t1_2 = .5 * km1;
00144     double t1_3 = (1./6) * km2;
00145     double t1_4 = (1./24) * km3;
00146     double t2_2 = t1_1 * t1_1;
00147     double t2_3 = 2 * (t1_1 * t1_2);
00148     double t2_4 = 2 * (t1_1 * t1_3) + t1_2 * t1_2;
00149     double t2_5 = 2 * (t1_1 * t1_4 + t1_2 * t1_3);
00150     double t2_6 = 2 * (t1_2 * t1_4) + t1_3 * t1_3;
00151     double t2_7 = 2 * (t1_3 * t1_4);
00152     double t2_8 = t1_4 * t1_4;
00153     double t3_4 = t2_2 * t1_2 + t2_3 * t1_1;
00154     double t3_6 = t2_2 * t1_4 + t2_3 * t1_3 + t2_4 * t1_2 + t2_5 * t1_1;
00155     double t3_8 = t2_4 * t1_4 + t2_5 * t1_3 + t2_6 * t1_2 + t2_7 * t1_1;
00156     double t4_4 = t2_2 * t2_2;
00157     double t4_5 = 2 * (t2_2 * t2_3);
00158     double t4_6 = 2 * (t2_2 * t2_4) + t2_3 * t2_3;
00159     double t4_7 = 2 * (t2_2 * t2_5 + t2_3 * t2_4);
00160     double t4_8 = 2 * (t2_2 * t2_6 + t2_3 * t2_5) + t2_4 * t2_4;
00161     double t5_6 = t4_4 * t1_2 + t4_5 * t1_1;
00162     double t5_8 = t4_4 * t1_4 + t4_5 * t1_3 + t4_6 * t1_2 + t4_7 * t1_1;
00163     double t6_6 = t4_4 * t2_2;
00164     double t6_7 = t4_4 * t2_3 + t4_5 * t2_2;
00165     double t6_8 = t4_4 * t2_4 + t4_5 * t2_3 + t4_6 * t2_2;
00166     double t7_8 = t6_6 * t1_2 + t6_7 * t1_1;
00167     double t8_8 = t6_6 * t2_2;
00168     u = 1;
00169     v = 0;
00170     v += (1./12) * t1_2 + (1./80) * t1_4;
00171     u -= (1./24) * t2_2 + (1./160) * t2_4 + (1./896) * t2_6 + (1./4608) * t2_8;
00172     v -= (1./480) * t3_4 + (1./2688) * t3_6 + (1./13824) * t3_8;
00173     u += (1./1920) * t4_4 + (1./10752) * t4_6 + (1./55296) * t4_8;
00174     v += (1./53760) * t5_6 + (1./276480) * t5_8;
00175     u -= (1./322560) * t6_6 + (1./1.65888e+06) * t6_8;
00176     v -= (1./1.16122e+07) * t7_8;
00177     u += (1./9.28973e+07) * t8_8;
00178 #endif
00179 
00180 #if ORDER == 12
00181     double t1_1 = km0;
00182     double t1_2 = .5 * km1;
00183     double t1_3 = (1./6) * km2;
00184     double t1_4 = (1./24) * km3;
00185     double t2_2 = t1_1 * t1_1;
00186     double t2_3 = 2 * (t1_1 * t1_2);
00187     double t2_4 = 2 * (t1_1 * t1_3) + t1_2 * t1_2;
00188     double t2_5 = 2 * (t1_1 * t1_4 + t1_2 * t1_3);
00189     double t2_6 = 2 * (t1_2 * t1_4) + t1_3 * t1_3;
00190     double t2_7 = 2 * (t1_3 * t1_4);
00191     double t2_8 = t1_4 * t1_4;
00192     double t3_4 = t2_2 * t1_2 + t2_3 * t1_1;
00193     double t3_6 = t2_2 * t1_4 + t2_3 * t1_3 + t2_4 * t1_2 + t2_5 * t1_1;
00194     double t3_8 = t2_4 * t1_4 + t2_5 * t1_3 + t2_6 * t1_2 + t2_7 * t1_1;
00195     double t3_10 = t2_6 * t1_4 + t2_7 * t1_3 + t2_8 * t1_2;
00196     double t4_4 = t2_2 * t2_2;
00197     double t4_5 = 2 * (t2_2 * t2_3);
00198     double t4_6 = 2 * (t2_2 * t2_4) + t2_3 * t2_3;
00199     double t4_7 = 2 * (t2_2 * t2_5 + t2_3 * t2_4);
00200     double t4_8 = 2 * (t2_2 * t2_6 + t2_3 * t2_5) + t2_4 * t2_4;
00201     double t4_9 = 2 * (t2_2 * t2_7 + t2_3 * t2_6 + t2_4 * t2_5);
00202     double t4_10 = 2 * (t2_2 * t2_8 + t2_3 * t2_7 + t2_4 * t2_6) + t2_5 * t2_5;
00203     double t5_6 = t4_4 * t1_2 + t4_5 * t1_1;
00204     double t5_8 = t4_4 * t1_4 + t4_5 * t1_3 + t4_6 * t1_2 + t4_7 * t1_1;
00205     double t5_10 = t4_6 * t1_4 + t4_7 * t1_3 + t4_8 * t1_2 + t4_9 * t1_1;
00206     double t6_6 = t4_4 * t2_2;
00207     double t6_7 = t4_4 * t2_3 + t4_5 * t2_2;
00208     double t6_8 = t4_4 * t2_4 + t4_5 * t2_3 + t4_6 * t2_2;
00209     double t6_9 = t4_4 * t2_5 + t4_5 * t2_4 + t4_6 * t2_3 + t4_7 * t2_2;
00210     double t6_10 = t4_4 * t2_6 + t4_5 * t2_5 + t4_6 * t2_4 + t4_7 * t2_3 + t4_8 * t2_2;
00211     double t7_8 = t6_6 * t1_2 + t6_7 * t1_1;
00212     double t7_10 = t6_6 * t1_4 + t6_7 * t1_3 + t6_8 * t1_2 + t6_9 * t1_1;
00213     double t8_8 = t6_6 * t2_2;
00214     double t8_9 = t6_6 * t2_3 + t6_7 * t2_2;
00215     double t8_10 = t6_6 * t2_4 + t6_7 * t2_3 + t6_8 * t2_2;
00216     double t9_10 = t8_8 * t1_2 + t8_9 * t1_1;
00217     double t10_10 = t8_8 * t2_2;
00218     u = 1;
00219     v = 0;
00220     v += (1./12) * t1_2 + (1./80) * t1_4;
00221     u -= (1./24) * t2_2 + (1./160) * t2_4 + (1./896) * t2_6 + (1./4608) * t2_8;
00222     v -= (1./480) * t3_4 + (1./2688) * t3_6 + (1./13824) * t3_8 + (1./67584) * t3_10;
00223     u += (1./1920) * t4_4 + (1./10752) * t4_6 + (1./55296) * t4_8 + (1./270336) * t4_10;
00224     v += (1./53760) * t5_6 + (1./276480) * t5_8 + (1./1.35168e+06) * t5_10;
00225     u -= (1./322560) * t6_6 + (1./1.65888e+06) * t6_8 + (1./8.11008e+06) * t6_10;
00226     v -= (1./1.16122e+07) * t7_8 + (1./5.67706e+07) * t7_10;
00227     u += (1./9.28973e+07) * t8_8 + (1./4.54164e+08) * t8_10;
00228     v += (1./4.08748e+09) * t9_10;
00229     u -= (1./4.08748e+10) * t10_10;
00230 #endif
00231 
00232 #if ORDER == 14
00233     double t1_1 = km0;
00234     double t1_2 = .5 * km1;
00235     double t1_3 = (1./6) * km2;
00236     double t1_4 = (1./24) * km3;
00237     double t2_2 = t1_1 * t1_1;
00238     double t2_3 = 2 * (t1_1 * t1_2);
00239     double t2_4 = 2 * (t1_1 * t1_3) + t1_2 * t1_2;
00240     double t2_5 = 2 * (t1_1 * t1_4 + t1_2 * t1_3);
00241     double t2_6 = 2 * (t1_2 * t1_4) + t1_3 * t1_3;
00242     double t2_7 = 2 * (t1_3 * t1_4);
00243     double t2_8 = t1_4 * t1_4;
00244     double t3_4 = t2_2 * t1_2 + t2_3 * t1_1;
00245     double t3_6 = t2_2 * t1_4 + t2_3 * t1_3 + t2_4 * t1_2 + t2_5 * t1_1;
00246     double t3_8 = t2_4 * t1_4 + t2_5 * t1_3 + t2_6 * t1_2 + t2_7 * t1_1;
00247     double t3_10 = t2_6 * t1_4 + t2_7 * t1_3 + t2_8 * t1_2;
00248     double t3_12 = t2_8 * t1_4;
00249     double t4_4 = t2_2 * t2_2;
00250     double t4_5 = 2 * (t2_2 * t2_3);
00251     double t4_6 = 2 * (t2_2 * t2_4) + t2_3 * t2_3;
00252     double t4_7 = 2 * (t2_2 * t2_5 + t2_3 * t2_4);
00253     double t4_8 = 2 * (t2_2 * t2_6 + t2_3 * t2_5) + t2_4 * t2_4;
00254     double t4_9 = 2 * (t2_2 * t2_7 + t2_3 * t2_6 + t2_4 * t2_5);
00255     double t4_10 = 2 * (t2_2 * t2_8 + t2_3 * t2_7 + t2_4 * t2_6) + t2_5 * t2_5;
00256     double t4_11 = 2 * (t2_3 * t2_8 + t2_4 * t2_7 + t2_5 * t2_6);
00257     double t4_12 = 2 * (t2_4 * t2_8 + t2_5 * t2_7) + t2_6 * t2_6;
00258     double t5_6 = t4_4 * t1_2 + t4_5 * t1_1;
00259     double t5_8 = t4_4 * t1_4 + t4_5 * t1_3 + t4_6 * t1_2 + t4_7 * t1_1;
00260     double t5_10 = t4_6 * t1_4 + t4_7 * t1_3 + t4_8 * t1_2 + t4_9 * t1_1;
00261     double t5_12 = t4_8 * t1_4 + t4_9 * t1_3 + t4_10 * t1_2 + t4_11 * t1_1;
00262     double t6_6 = t4_4 * t2_2;
00263     double t6_7 = t4_4 * t2_3 + t4_5 * t2_2;
00264     double t6_8 = t4_4 * t2_4 + t4_5 * t2_3 + t4_6 * t2_2;
00265     double t6_9 = t4_4 * t2_5 + t4_5 * t2_4 + t4_6 * t2_3 + t4_7 * t2_2;
00266     double t6_10 = t4_4 * t2_6 + t4_5 * t2_5 + t4_6 * t2_4 + t4_7 * t2_3 + t4_8 * t2_2;
00267     double t6_11 = t4_4 * t2_7 + t4_5 * t2_6 + t4_6 * t2_5 + t4_7 * t2_4 + t4_8 * t2_3 + t4_9 * t2_2;
00268     double t6_12 = t4_4 * t2_8 + t4_5 * t2_7 + t4_6 * t2_6 + t4_7 * t2_5 + t4_8 * t2_4 + t4_9 * t2_3 + t4_10 * t2_2;
00269     double t7_8 = t6_6 * t1_2 + t6_7 * t1_1;
00270     double t7_10 = t6_6 * t1_4 + t6_7 * t1_3 + t6_8 * t1_2 + t6_9 * t1_1;
00271     double t7_12 = t6_8 * t1_4 + t6_9 * t1_3 + t6_10 * t1_2 + t6_11 * t1_1;
00272     double t8_8 = t6_6 * t2_2;
00273     double t8_9 = t6_6 * t2_3 + t6_7 * t2_2;
00274     double t8_10 = t6_6 * t2_4 + t6_7 * t2_3 + t6_8 * t2_2;
00275     double t8_11 = t6_6 * t2_5 + t6_7 * t2_4 + t6_8 * t2_3 + t6_9 * t2_2;
00276     double t8_12 = t6_6 * t2_6 + t6_7 * t2_5 + t6_8 * t2_4 + t6_9 * t2_3 + t6_10 * t2_2;
00277     double t9_10 = t8_8 * t1_2 + t8_9 * t1_1;
00278     double t9_12 = t8_8 * t1_4 + t8_9 * t1_3 + t8_10 * t1_2 + t8_11 * t1_1;
00279     double t10_10 = t8_8 * t2_2;
00280     double t10_11 = t8_8 * t2_3 + t8_9 * t2_2;
00281     double t10_12 = t8_8 * t2_4 + t8_9 * t2_3 + t8_10 * t2_2;
00282     double t11_12 = t10_10 * t1_2 + t10_11 * t1_1;
00283     double t12_12 = t10_10 * t2_2;
00284     u = 1;
00285     v = 0;
00286     v += (1./12) * t1_2 + (1./80) * t1_4;
00287     u -= (1./24) * t2_2 + (1./160) * t2_4 + (1./896) * t2_6 + (1./4608) * t2_8;
00288     v -= (1./480) * t3_4 + (1./2688) * t3_6 + (1./13824) * t3_8 + (1./67584) * t3_10 + (1./319488) * t3_12;
00289     u += (1./1920) * t4_4 + (1./10752) * t4_6 + (1./55296) * t4_8 + (1./270336) * t4_10 + (1./1.27795e+06) * t4_12;
00290     v += (1./53760) * t5_6 + (1./276480) * t5_8 + (1./1.35168e+06) * t5_10 + (1./6.38976e+06) * t5_12;
00291     u -= (1./322560) * t6_6 + (1./1.65888e+06) * t6_8 + (1./8.11008e+06) * t6_10 + (1./3.83386e+07) * t6_12;
00292     v -= (1./1.16122e+07) * t7_8 + (1./5.67706e+07) * t7_10 + (1./2.6837e+08) * t7_12;
00293     u += (1./9.28973e+07) * t8_8 + (1./4.54164e+08) * t8_10 + (1./2.14696e+09) * t8_12;
00294     v += (1./4.08748e+09) * t9_10 + (1./1.93226e+10) * t9_12;
00295     u -= (1./4.08748e+10) * t10_10 + (1./1.93226e+11) * t10_12;
00296     v -= (1./2.12549e+12) * t11_12;
00297     u += (1./2.55059e+13) * t12_12;
00298 #endif
00299 
00300 #if ORDER == 16
00301     double t1_1 = km0;
00302     double t1_2 = .5 * km1;
00303     double t1_3 = (1./6) * km2;
00304     double t1_4 = (1./24) * km3;
00305     double t2_2 = t1_1 * t1_1;
00306     double t2_3 = 2 * (t1_1 * t1_2);
00307     double t2_4 = 2 * (t1_1 * t1_3) + t1_2 * t1_2;
00308     double t2_5 = 2 * (t1_1 * t1_4 + t1_2 * t1_3);
00309     double t2_6 = 2 * (t1_2 * t1_4) + t1_3 * t1_3;
00310     double t2_7 = 2 * (t1_3 * t1_4);
00311     double t2_8 = t1_4 * t1_4;
00312     double t3_4 = t2_2 * t1_2 + t2_3 * t1_1;
00313     double t3_6 = t2_2 * t1_4 + t2_3 * t1_3 + t2_4 * t1_2 + t2_5 * t1_1;
00314     double t3_8 = t2_4 * t1_4 + t2_5 * t1_3 + t2_6 * t1_2 + t2_7 * t1_1;
00315     double t3_10 = t2_6 * t1_4 + t2_7 * t1_3 + t2_8 * t1_2;
00316     double t3_12 = t2_8 * t1_4;
00317     double t4_4 = t2_2 * t2_2;
00318     double t4_5 = 2 * (t2_2 * t2_3);
00319     double t4_6 = 2 * (t2_2 * t2_4) + t2_3 * t2_3;
00320     double t4_7 = 2 * (t2_2 * t2_5 + t2_3 * t2_4);
00321     double t4_8 = 2 * (t2_2 * t2_6 + t2_3 * t2_5) + t2_4 * t2_4;
00322     double t4_9 = 2 * (t2_2 * t2_7 + t2_3 * t2_6 + t2_4 * t2_5);
00323     double t4_10 = 2 * (t2_2 * t2_8 + t2_3 * t2_7 + t2_4 * t2_6) + t2_5 * t2_5;
00324     double t4_11 = 2 * (t2_3 * t2_8 + t2_4 * t2_7 + t2_5 * t2_6);
00325     double t4_12 = 2 * (t2_4 * t2_8 + t2_5 * t2_7) + t2_6 * t2_6;
00326     double t4_13 = 2 * (t2_5 * t2_8 + t2_6 * t2_7);
00327     double t4_14 = 2 * (t2_6 * t2_8) + t2_7 * t2_7;
00328     double t5_6 = t4_4 * t1_2 + t4_5 * t1_1;
00329     double t5_8 = t4_4 * t1_4 + t4_5 * t1_3 + t4_6 * t1_2 + t4_7 * t1_1;
00330     double t5_10 = t4_6 * t1_4 + t4_7 * t1_3 + t4_8 * t1_2 + t4_9 * t1_1;
00331     double t5_12 = t4_8 * t1_4 + t4_9 * t1_3 + t4_10 * t1_2 + t4_11 * t1_1;
00332     double t5_14 = t4_10 * t1_4 + t4_11 * t1_3 + t4_12 * t1_2 + t4_13 * t1_1;
00333     double t6_6 = t4_4 * t2_2;
00334     double t6_7 = t4_4 * t2_3 + t4_5 * t2_2;
00335     double t6_8 = t4_4 * t2_4 + t4_5 * t2_3 + t4_6 * t2_2;
00336     double t6_9 = t4_4 * t2_5 + t4_5 * t2_4 + t4_6 * t2_3 + t4_7 * t2_2;
00337     double t6_10 = t4_4 * t2_6 + t4_5 * t2_5 + t4_6 * t2_4 + t4_7 * t2_3 + t4_8 * t2_2;
00338     double t6_11 = t4_4 * t2_7 + t4_5 * t2_6 + t4_6 * t2_5 + t4_7 * t2_4 + t4_8 * t2_3 + t4_9 * t2_2;
00339     double t6_12 = t4_4 * t2_8 + t4_5 * t2_7 + t4_6 * t2_6 + t4_7 * t2_5 + t4_8 * t2_4 + t4_9 * t2_3 + t4_10 * t2_2;
00340     double t6_13 = t4_5 * t2_8 + t4_6 * t2_7 + t4_7 * t2_6 + t4_8 * t2_5 + t4_9 * t2_4 + t4_10 * t2_3 + t4_11 * t2_2;
00341     double t6_14 = t4_6 * t2_8 + t4_7 * t2_7 + t4_8 * t2_6 + t4_9 * t2_5 + t4_10 * t2_4 + t4_11 * t2_3 + t4_12 * t2_2;
00342     double t7_8 = t6_6 * t1_2 + t6_7 * t1_1;
00343     double t7_10 = t6_6 * t1_4 + t6_7 * t1_3 + t6_8 * t1_2 + t6_9 * t1_1;
00344     double t7_12 = t6_8 * t1_4 + t6_9 * t1_3 + t6_10 * t1_2 + t6_11 * t1_1;
00345     double t7_14 = t6_10 * t1_4 + t6_11 * t1_3 + t6_12 * t1_2 + t6_13 * t1_1;
00346     double t8_8 = t6_6 * t2_2;
00347     double t8_9 = t6_6 * t2_3 + t6_7 * t2_2;
00348     double t8_10 = t6_6 * t2_4 + t6_7 * t2_3 + t6_8 * t2_2;
00349     double t8_11 = t6_6 * t2_5 + t6_7 * t2_4 + t6_8 * t2_3 + t6_9 * t2_2;
00350     double t8_12 = t6_6 * t2_6 + t6_7 * t2_5 + t6_8 * t2_4 + t6_9 * t2_3 + t6_10 * t2_2;
00351     double t8_13 = t6_6 * t2_7 + t6_7 * t2_6 + t6_8 * t2_5 + t6_9 * t2_4 + t6_10 * t2_3 + t6_11 * t2_2;
00352     double t8_14 = t6_6 * t2_8 + t6_7 * t2_7 + t6_8 * t2_6 + t6_9 * t2_5 + t6_10 * t2_4 + t6_11 * t2_3 + t6_12 * t2_2;
00353     double t9_10 = t8_8 * t1_2 + t8_9 * t1_1;
00354     double t9_12 = t8_8 * t1_4 + t8_9 * t1_3 + t8_10 * t1_2 + t8_11 * t1_1;
00355     double t9_14 = t8_10 * t1_4 + t8_11 * t1_3 + t8_12 * t1_2 + t8_13 * t1_1;
00356     double t10_10 = t8_8 * t2_2;
00357     double t10_11 = t8_8 * t2_3 + t8_9 * t2_2;
00358     double t10_12 = t8_8 * t2_4 + t8_9 * t2_3 + t8_10 * t2_2;
00359     double t10_13 = t8_8 * t2_5 + t8_9 * t2_4 + t8_10 * t2_3 + t8_11 * t2_2;
00360     double t10_14 = t8_8 * t2_6 + t8_9 * t2_5 + t8_10 * t2_4 + t8_11 * t2_3 + t8_12 * t2_2;
00361     double t11_12 = t10_10 * t1_2 + t10_11 * t1_1;
00362     double t11_14 = t10_10 * t1_4 + t10_11 * t1_3 + t10_12 * t1_2 + t10_13 * t1_1;
00363     double t12_12 = t10_10 * t2_2;
00364     double t12_13 = t10_10 * t2_3 + t10_11 * t2_2;
00365     double t12_14 = t10_10 * t2_4 + t10_11 * t2_3 + t10_12 * t2_2;
00366     double t13_14 = t12_12 * t1_2 + t12_13 * t1_1;
00367     double t14_14 = t12_12 * t2_2;
00368     u = 1;
00369     u -= 1./24 * t2_2 + 1./160 * t2_4 + 1./896 * t2_6 + 1./4608 * t2_8;
00370     u += 1./1920 * t4_4 + 1./10752 * t4_6 + 1./55296 * t4_8 + 1./270336 * t4_10 + 1./1277952 * t4_12 + 1./5898240 * t4_14;
00371     u -= 1./322560 * t6_6 + 1./1658880 * t6_8 + 1./8110080 * t6_10 + 1./38338560 * t6_12 + 1./176947200 * t6_14;
00372     u += 1./92897280 * t8_8 + 1./454164480 * t8_10 + 4.6577500191e-10 * t8_12 + 1.0091791708e-10 * t8_14;
00373     u -= 2.4464949595e-11 * t10_10 + 5.1752777990e-12 * t10_12 + 1.1213101898e-12 * t10_14;
00374     u += 3.9206649992e-14 * t12_12 + 8.4947741650e-15 * t12_14;
00375     u -= 4.6674583324e-17 * t14_14;
00376     v = 0;
00377     v += 1./12 * t1_2 + 1./80 * t1_4;
00378     v -= 1./480 * t3_4 + 1./2688 * t3_6 + 1./13824 * t3_8 + 1./67584 * t3_10 + 1./319488 * t3_12;
00379     v += 1./53760 * t5_6 + 1./276480 * t5_8 + 1./1351680 * t5_10 + 1./6389760 * t5_12 + 1./29491200 * t5_14;
00380     v -= 1./11612160 * t7_8 + 1./56770560 * t7_10 + 1./268369920 * t7_12 + 8.0734333664e-10 * t7_14;
00381     v += 2.4464949595e-10 * t9_10 + 5.1752777990e-11 * t9_12 + 1.1213101898e-11 * t9_14;
00382     v -= 4.7047979991e-13 * t11_12 + 1.0193728998e-13 * t11_14;
00383     v += 6.5344416654e-16 * t13_14;
00384 #endif
00385 
00386     }
00387 
00388     if (n == 1) {
00389 #if ORDER == 2
00390         x = 1;
00391         y = 0;
00392 #else
00393         x = u;
00394         y = v;
00395 #endif
00396     } else {
00397         double th = (((th4 * s + th3) * s + th2) * s + th1) * s;
00398         double cth = cos(th);
00399         double sth = sin(th);
00400 
00401 #if ORDER == 2
00402         x += cth;
00403         y += sth;
00404 #else
00405         x += cth * u - sth * v;
00406         y += cth * v + sth * u;
00407 #endif
00408         s += ds;
00409     }
00410     }
00411 
00412 #if ORDER == 4 || ORDER == 6
00413     xy[0] = x * (1./24 * ds);
00414     xy[1] = y * (1./24 * ds);
00415 #else
00416     xy[0] = x * ds;
00417     xy[1] = y * ds;
00418 #endif
00419 }

static double mod_2pi ( double  th  )  [static]

Definition at line 482 of file spiro.cpp.

References M_PI.

Referenced by setup_path(), and spiro_iter().

00483 {
00484     double u = th / (2 * M_PI);
00485     return 2 * M_PI * (u - floor(u + 0.5));
00486 }

spiro_seg* run_spiro ( const spiro_cp src,
int  n 
)

Definition at line 879 of file spiro.cpp.

References setup_path(), solve_spiro(), and spiro_cp::ty.

Referenced by Inkscape::LivePathEffect::LPESpiro::doEffect().

00880 {
00881     int nseg = src[0].ty == '{' ? n - 1 : n;
00882     spiro_seg *s = setup_path(src, n);
00883     if (nseg > 1)
00884     solve_spiro(s, nseg);
00885     return s;
00886 }

static spiro_seg* setup_path ( const spiro_cp src,
int  n 
) [static]

Definition at line 489 of file spiro.cpp.

References Geom::atan2(), spiro_seg_s::bend_th, Barcode::Code39Ext::i, spiro_seg_s::ks, mod_2pi(), polyhedron_3d::r, spiro_seg_s::seg_ch, spiro_seg_s::seg_th, spiro_seg_s::ty, spiro_cp::ty, spiro_cp::x, spiro_seg_s::x, spiro_cp::y, and spiro_seg_s::y.

Referenced by run_spiro().

00490 {
00491     int n_seg = src[0].ty == '{' ? n - 1 : n;
00492     spiro_seg *r = (spiro_seg *)malloc((n_seg + 1) * sizeof(spiro_seg));
00493     int i;
00494     int ilast;
00495 
00496     for (i = 0; i < n_seg; i++) {
00497     r[i].x = src[i].x;
00498     r[i].y = src[i].y;
00499     r[i].ty = src[i].ty;
00500     r[i].ks[0] = 0.;
00501     r[i].ks[1] = 0.;
00502     r[i].ks[2] = 0.;
00503     r[i].ks[3] = 0.;
00504     }
00505     r[n_seg].x = src[n_seg % n].x;
00506     r[n_seg].y = src[n_seg % n].y;
00507     r[n_seg].ty = src[n_seg % n].ty;
00508 
00509     for (i = 0; i < n_seg; i++) {
00510     double dx = r[i + 1].x - r[i].x;
00511     double dy = r[i + 1].y - r[i].y;
00512     r[i].seg_ch = hypot(dx, dy);
00513     r[i].seg_th = atan2(dy, dx);
00514     }
00515 
00516     ilast = n_seg - 1;
00517     for (i = 0; i < n_seg; i++) {
00518     if (r[i].ty == '{' || r[i].ty == '}' || r[i].ty == 'v')
00519         r[i].bend_th = 0.;
00520     else
00521         r[i].bend_th = mod_2pi(r[i].seg_th - r[ilast].seg_th);
00522     ilast = i;
00523     }
00524     return r;
00525 }

int solve_spiro ( spiro_seg s,
int  nseg 
)

Definition at line 784 of file spiro.cpp.

References count_vec(), addnodes::e, Barcode::Code39Ext::i, cubicsuperpath::norm(), and spiro_iter().

Referenced by run_spiro().

00785 {
00786     bandmat *m;
00787     double *v;
00788     int *perm;
00789     int nmat = count_vec(s, nseg);
00790     int n_alloc = nmat;
00791     double norm;
00792     int i;
00793 
00794     if (nmat == 0)
00795     return 0;
00796     if (s[0].ty != '{' && s[0].ty != 'v')
00797     n_alloc *= 3;
00798     if (n_alloc < 5)
00799     n_alloc = 5;
00800     m = (bandmat *)malloc(sizeof(bandmat) * n_alloc);
00801     v = (double *)malloc(sizeof(double) * n_alloc);
00802     perm = (int *)malloc(sizeof(int) * n_alloc);
00803 
00804     for (i = 0; i < 10; i++) {
00805     norm = spiro_iter(s, m, perm, v, nseg);
00806 #ifdef VERBOSE
00807     printf("%% norm = %g\n", norm);
00808 #endif
00809     if (norm < 1e-12) break;
00810     }
00811 
00812     free(m);
00813     free(v);
00814     free(perm);
00815     return 0;
00816 }

static double spiro_iter ( spiro_seg s,
bandmat m,
int *  perm,
double v,
int  n 
) [static]

Definition at line 653 of file spiro.cpp.

References org::w3c::dom::svg::a, add_mat_line(), banbks11(), bandec11(), spiro_seg_s::bend_th, compute_jinc(), compute_pderivs(), count_vec(), cyclic(), Barcode::Code39Ext::i, spiro_seg_s::ks, mod_2pi(), cubicsuperpath::norm(), polyhedron_3d::th, and spiro_seg_s::ty.

Referenced by solve_spiro().

00654 {
00655     int cyclic = s[0].ty != '{' && s[0].ty != 'v';
00656     int i, j, jj;
00657     int nmat = count_vec(s, n);
00658     double norm;
00659     int n_invert;
00660 
00661     for (i = 0; i < nmat; i++) {
00662     v[i] = 0.;
00663     for (j = 0; j < 11; j++)
00664         m[i].a[j] = 0.;
00665     for (j = 0; j < 5; j++)
00666         m[i].al[j] = 0.;
00667     }
00668 
00669     j = 0;
00670     if (s[0].ty == 'o')
00671     jj = nmat - 2;
00672     else if (s[0].ty == 'c')
00673     jj = nmat - 1;
00674     else
00675     jj = 0;
00676     for (i = 0; i < n; i++) {
00677     char ty0 = s[i].ty;
00678     char ty1 = s[i + 1].ty;
00679     int jinc = compute_jinc(ty0, ty1);
00680     double th = s[i].bend_th;
00681     double ends[2][4];
00682     double derivs[4][2][4];
00683     int jthl = -1, jk0l = -1, jk1l = -1, jk2l = -1;
00684     int jthr = -1, jk0r = -1, jk1r = -1, jk2r = -1;
00685 
00686     compute_pderivs(&s[i], ends, derivs, jinc);
00687 
00688     /* constraints crossing left */
00689     if (ty0 == 'o' || ty0 == 'c' || ty0 == '[' || ty0 == ']') {
00690         jthl = jj++;
00691         jj %= nmat;
00692         jk0l = jj++;
00693     }
00694     if (ty0 == 'o') {
00695         jj %= nmat;
00696         jk1l = jj++;
00697         jk2l = jj++;
00698     }
00699 
00700     /* constraints on left */
00701     if ((ty0 == '[' || ty0 == 'v' || ty0 == '{' || ty0 == 'c') &&
00702         jinc == 4) {
00703         if (ty0 != 'c')
00704         jk1l = jj++;
00705         jk2l = jj++;
00706     }
00707 
00708     /* constraints on right */
00709     if ((ty1 == ']' || ty1 == 'v' || ty1 == '}' || ty1 == 'c') &&
00710         jinc == 4) {
00711         if (ty1 != 'c')
00712         jk1r = jj++;
00713         jk2r = jj++;
00714     }
00715 
00716     /* constraints crossing right */
00717     if (ty1 == 'o' || ty1 == 'c' || ty1 == '[' || ty1 == ']') {
00718         jthr = jj;
00719         jk0r = (jj + 1) % nmat;
00720     }
00721     if (ty1 == 'o') {
00722         jk1r = (jj + 2) % nmat;
00723         jk2r = (jj + 3) % nmat;
00724     }
00725 
00726     add_mat_line(m, v, derivs[0][0], th - ends[0][0], 1, j, jthl, jinc, nmat);
00727     add_mat_line(m, v, derivs[1][0], ends[0][1], -1, j, jk0l, jinc, nmat);
00728     add_mat_line(m, v, derivs[2][0], ends[0][2], -1, j, jk1l, jinc, nmat);
00729     add_mat_line(m, v, derivs[3][0], ends[0][3], -1, j, jk2l, jinc, nmat);
00730     add_mat_line(m, v, derivs[0][1], -ends[1][0], 1, j, jthr, jinc, nmat);
00731     add_mat_line(m, v, derivs[1][1], -ends[1][1], 1, j, jk0r, jinc, nmat);
00732     add_mat_line(m, v, derivs[2][1], -ends[1][2], 1, j, jk1r, jinc, nmat);
00733     add_mat_line(m, v, derivs[3][1], -ends[1][3], 1, j, jk2r, jinc, nmat);
00734     if (jthl >= 0)
00735         v[jthl] = mod_2pi(v[jthl]);
00736     if (jthr >= 0)
00737         v[jthr] = mod_2pi(v[jthr]);
00738     j += jinc;
00739     }
00740     if (cyclic) {
00741     memcpy(m + nmat, m, sizeof(bandmat) * nmat);
00742     memcpy(m + 2 * nmat, m, sizeof(bandmat) * nmat);
00743     memcpy(v + nmat, v, sizeof(double) * nmat);
00744     memcpy(v + 2 * nmat, v, sizeof(double) * nmat);
00745     n_invert = 3 * nmat;
00746     j = nmat;
00747     } else {
00748     n_invert = nmat;
00749     j = 0;
00750     }
00751 #ifdef VERBOSE
00752     for (i = 0; i < n; i++) {
00753     int k;
00754     for (k = 0; k < 11; k++)
00755         printf(" %2.4f", m[i].a[k]);
00756     printf(": %2.4f\n", v[i]);
00757     }
00758     printf("---\n");
00759 #endif
00760     bandec11(m, perm, n_invert);
00761     banbks11(m, perm, v, n_invert);
00762     norm = 0.;
00763     for (i = 0; i < n; i++) {
00764     char ty0 = s[i].ty;
00765     char ty1 = s[i + 1].ty;
00766     int jinc = compute_jinc(ty0, ty1);
00767     int k;
00768 
00769     for (k = 0; k < jinc; k++) {
00770         double dk = v[j++];
00771 
00772 #ifdef VERBOSE
00773         printf("s[%d].ks[%d] += %f\n", i, k, dk);
00774 #endif
00775         s[i].ks[k] += dk;
00776         norm += dk * dk;
00777     }
00778         s[i].ks[0] = 2.0*mod_2pi(s[i].ks[0]/2.0);
00779     }
00780     return norm;
00781 }

static void spiro_seg_to_bpath ( const double  ks[4],
double  x0,
double  y0,
double  x1,
double  y1,
bezctx bc,
int  depth 
) [static]

Definition at line 819 of file spiro.cpp.

References Geom::atan2(), Inkscape::LivePathEffect::bend(), bezctx_curveto(), bezctx_lineto(), Geom::cos(), addnodes::e, integrate_spiro(), dxf_input::scale, Geom::sin(), and polyhedron_3d::th.

Referenced by spiro_to_bpath().

00822 {
00823     double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) +
00824     fabs((1./48) * ks[3]);
00825 
00826     if (!bend > 1e-8) {
00827     bezctx_lineto(bc, x1, y1);
00828     } else {
00829     double seg_ch = hypot(x1 - x0, y1 - y0);
00830     double seg_th = atan2(y1 - y0, x1 - x0);
00831     double xy[2];
00832     double ch, th;
00833     double scale, rot;
00834     double th_even, th_odd;
00835     double ul, vl;
00836     double ur, vr;
00837 
00838     integrate_spiro(ks, xy);
00839     ch = hypot(xy[0], xy[1]);
00840     th = atan2(xy[1], xy[0]);
00841     scale = seg_ch / ch;
00842     rot = seg_th - th;
00843     if (depth > 5 || bend < 1.) {
00844         th_even = (1./384) * ks[3] + (1./8) * ks[1] + rot;
00845         th_odd = (1./48) * ks[2] + .5 * ks[0];
00846         ul = (scale * (1./3)) * cos(th_even - th_odd);
00847         vl = (scale * (1./3)) * sin(th_even - th_odd);
00848         ur = (scale * (1./3)) * cos(th_even + th_odd);
00849         vr = (scale * (1./3)) * sin(th_even + th_odd);
00850         bezctx_curveto(bc, x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
00851     } else {
00852         /* subdivide */
00853         double ksub[4];
00854         double thsub;
00855         double xysub[2];
00856         double xmid, ymid;
00857         double cth, sth;
00858 
00859         ksub[0] = .5 * ks[0] - .125 * ks[1] + (1./64) * ks[2] - (1./768) * ks[3];
00860         ksub[1] = .25 * ks[1] - (1./16) * ks[2] + (1./128) * ks[3];
00861         ksub[2] = .125 * ks[2] - (1./32) * ks[3];
00862         ksub[3] = (1./16) * ks[3];
00863         thsub = rot - .25 * ks[0] + (1./32) * ks[1] - (1./384) * ks[2] + (1./6144) * ks[3];
00864         cth = .5 * scale * cos(thsub);
00865         sth = .5 * scale * sin(thsub);
00866         integrate_spiro(ksub, xysub);
00867         xmid = x0 + cth * xysub[0] - sth * xysub[1];
00868         ymid = y0 + cth * xysub[1] + sth * xysub[0];
00869         spiro_seg_to_bpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
00870         ksub[0] += .25 * ks[1] + (1./384) * ks[3];
00871         ksub[1] += .125 * ks[2];
00872         ksub[2] += (1./16) * ks[3];
00873         spiro_seg_to_bpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
00874     }
00875     }
00876 }

void spiro_to_bpath ( const spiro_seg s,
int  n,
bezctx bc 
)

Definition at line 895 of file spiro.cpp.

References bezctx_mark_knot(), bezctx_moveto(), Barcode::Code39Ext::i, spiro_seg_to_bpath(), spiro_seg_s::ty, spiro_seg_s::x, and spiro_seg_s::y.

Referenced by Inkscape::LivePathEffect::LPESpiro::doEffect().

00896 {
00897     int i;
00898     int nsegs = s[n - 1].ty == '}' ? n - 1 : n;
00899 
00900     for (i = 0; i < nsegs; i++) {
00901     double x0 = s[i].x;
00902     double y0 = s[i].y;
00903     double x1 = s[i + 1].x;
00904     double y1 = s[i + 1].y;
00905 
00906     if (i == 0)
00907         bezctx_moveto(bc, x0, y0, s[0].ty == '{');
00908     bezctx_mark_knot(bc, i);
00909     spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0);
00910     }
00911 }


Variable Documentation

int n = 4

Definition at line 50 of file spiro.cpp.

Referenced by Inkscape::UI::Node::_linearGrow(), Inkscape::UI::Dialogs::_loadPaletteFile(), Inkscape::UI::Node::_next(), SweepTreeList::add(), SweepEventQueue::add(), IntLigne::AddBord(), FloatLigne::AddBord(), FloatLigne::AddBordR(), Shape::AddEdge(), Path::AddForcedPoint(), Shape::AddPoint(), Path::AddPoint(), IntLigne::AddRun(), FloatLigne::AddRun(), adjust_vertices(), Geom::detail::bezier_clipping::angle(), FloatLigne::AppendBord(), bestpolygon(), Inkscape::UI::PathManipulator::breakNodes(), calc_lon(), calc_sums(), Inkscape::Extension::Internal::SingularValueDecomposition::calculate(), Geom::ConvexHull::centroid_and_area(), char_index_of_iterator(), Shape::CheckAdjacencies(), Geom::detail::bezier_clipping::clip_interval(), clonetiler_change_selection(), clonetiler_number_of_clones(), Inkscape::IO::GzipOutputStream::close(), UStringPrivate::Composition::Composition(), StringPrivate::Composition::Composition(), cola::connectedComponents(), cola::ConstrainedMajorizationLayout::ConstrainedMajorizationLayout(), Path::ConvertWithBackData(), Geom::detail::bezier_clipping::convex_hull(), count_vec(), Inkscape::Whiteboard::SessionManager::createSessionId(), Inkscape::LivePathEffect::LPEKnotNS::CrossingPoints::CrossingPoints(), Geom::MonoCrosser::crossings(), Geom::Crosser< Path >::crossings(), Path::DashSubPath(), Geom::detail::bezier_clipping::derivative(), Geom::detail::bezier_clipping::distance_control_points(), Inkscape::LivePathEffect::LPETextLabel::doEffect_pwd2(), Inkscape::LivePathEffect::LPERuler::doEffect_pwd2(), Inkscape::LivePathEffect::LPERecursiveSkeleton::doEffect_pwd2(), Inkscape::LivePathEffect::LPEPatternAlongPath::doEffect_pwd2(), Inkscape::LivePathEffect::LPEOffset::doEffect_pwd2(), Inkscape::LivePathEffect::LPEDynastroke::doEffect_pwd2(), Path::DoJoin(), doXmlTest(), Inkscape::UI::Node::dragged(), dxf_get_sections(), filter_onefield(), Inkscape::UI::Dialog::Find::filter_types(), filter_types(), Geom::Bernsteins::find_bernstein_roots(), Inkscape::ObjectSnapper::freeSnap(), Inkscape::LivePathEffect::LPERoughHatches::generateLevels(), Geom::detail::bezier_clipping::get_precision(), Inkscape::XML::get_prev(), org::w3c::dom::NodeImpl::getTextContent(), gm_readbody_bmp(), graphlayout(), Geom::Bernsteins::horner(), Inkscape::LivePathEffect::LPEKnotNS::CrossingPoints::inherit_signs(), inkscape_crash_handler(), org::w3c::dom::NodeImpl::insertBefore(), integrate_spiro(), Geom::intersect_polish_root(), Geom::detail::bezier_clipping::left_portion(), Inkscape::LivePathEffect::LPERoughHatches::linearSnake(), Geom::detail::bezier_clipping::make_focus(), makeCrcTable(), SweepEvent::MakeDelete(), matrix_times_vector(), Geom::ConvexHull::narrowest_diameter(), Geom::detail::ellipse_equation::normal(), Inkscape::Preferences::PrefNodeObserver::notifyAttributeChanged(), octreePrune(), Inkscape::UI::Dialog::Find::onFind(), Geom::OldBezier::operator()(), font_style_hash::operator()(), operator<<(), Pedro::Parser::parse(), buildtool::Parser::parse(), org::w3c::dom::svg::SVGReader::parseElement(), Pedro::Parser::parseElement(), buildtool::Parser::parseElement(), Pedro::Parser::parseFile(), buildtool::Parser::parseFile(), penalty3(), pointslope(), Shape::PushIncidence(), Shape::ReFormeBezierTo(), SweepEventQueue::remove(), org::w3c::dom::NodeImpl::removeChild(), org::w3c::dom::NodeImpl::replaceChild(), Path::ReplacePoint(), Geom::detail::bezier_clipping::right_portion(), sel_matches_node_real(), cola::separateComponents(), Inkscape::UI::Dialog::DualSpinButton::set_from_attribute(), set_pos_and_anchor(), Inkscape::LivePathEffect::TextParam::setPosAndAnchor(), Inkscape::UI::PathManipulator::shiftSelection(), Shape::SortEdges(), sp_dyna_draw_apply(), sp_eraser_apply(), sp_export_export_clicked(), sp_find_dialog_find(), sp_font_selector_init(), sp_guide_create(), sp_key_name(), sp_png_write_rgba_striped(), sp_selection_apply_affine(), sp_shape_number_of_markers(), sp_text_description(), Inkscape::UI::PathManipulator::subdivideSegment(), SVGColorTest::testReadColor(), SvgAffineTest::testReadIdentity(), Inkscape::LivePathEffect::LPEKnotNS::CrossingPoints::to_vector(), buildtool::trex_charclass(), buildtool::trex_matchnode(), buildtool::trex_newnode(), unclump_average(), Geom::Curve::unitTangentAt(), Geom::Piecewise< Geom::D2< Geom::SBasis > >::valueAndDerivatives(), Geom::Piecewise< Geom::D2< Geom::SBasis > >::valueAt(), Geom::Bezier::valueAt(), and CycleDetector::visit().