コード例 #1
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  //HERMITE:  p1=p0   p2=p1    p3=r0   p4=r1
  //BEZIER:   p1 = p0 p2 = other point 2  p3 = other point 1 p4 = p1
  struct matrix * coefs = new_matrix(4, 1); 
  struct matrix * inverse = new_matrix(4, 4); 
  if (type == HERMITE_MODE){
    coefs->m[0][0] = p1; 
    coefs->m[1][0] = p2; 
    coefs->m[2][0] = p3-p1;
    coefs->m[3][0] = p4-p2;
    inverse = make_hermite(); 
  }
  else if (type == BEZIER_MODE){
    coefs->m[0][0] = p1; 
    coefs->m[1][0] = p3;
    coefs->m[2][0] = p2;
    coefs->m[3][0] = p4;
    inverse = make_bezier(); 
  }

  matrix_mult(inverse, coefs);
  free_matrix(inverse); 
  return coefs; 


}
コード例 #2
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
				      	
  struct matrix *temp;
  temp = new_matrix(4,1);

  //Bezier Curve co
  if(type == 1){
    temp->m[0][0] = p1;
    temp->m[1][0] = p2;
    temp->m[2][0] = p3;
    temp->m[3][0] = p4;

    struct matrix *newBez;
    newBez = make_bezier();
    matrix_mult(newBez,temp);
  }

  if(type == 0){
    temp->m[0][0] = p1;
    temp->m[1][0] = p3;
    temp->m[2][0] = p2-p1;
    temp->m[3][0] = p4-p3;
    
    struct matrix *newHerm;
    newHerm = make_hermite();
    matrix_mult(newHerm,temp);
   

}
  return temp;
}
コード例 #3
0
ファイル: matrix.c プロジェクト: stuydw/3d
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  
  struct matrix * inverse;
  struct matrix * coefs;

  if ( type == BEZIER_MODE )    
    inverse = make_bezier();
  else
    inverse = make_hermite();

  coefs = new_matrix(4, 1);

  if ( type == BEZIER_MODE ) {
    coefs->m[0][0] = p1;
    coefs->m[1][0] = p2;
    coefs->m[2][0] = p3;
    coefs->m[3][0] = p4;
  }  

  else {
    coefs->m[0][0] = p1;
    coefs->m[1][0] = p3;
    coefs->m[2][0] = p2 - p1;
    coefs->m[3][0] = p4 - p3;
  }
 
  matrix_mult(inverse, coefs);

  free_matrix(inverse);
    
  return coefs;  
}
コード例 #4
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  struct matrix * bh;;
  struct matrix * given = new_matrix(4, 1);
  given->lastcol = 1;

  if (type == 0){
    bh = make_bezier();

    given->m[0][0] = p1;
    given->m[1][0] = p2;
    given->m[2][0] = p3;
    given->m[3][0] = p4;
  }
  else{
    bh = make_hermite();

    given->m[0][0] = p1;
    given->m[1][0] = p3;
    given->m[2][0] = p1 - p2;
    given->m[3][0] = p3 - p4;
  }
  matrix_mult(bh, given);

  free_matrix(bh);
  return given;
}
コード例 #5
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
   double p3
   double p4
   int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
     double p3, double p4, int type) {

  struct matrix * coeffs = new_matrix(4, 1);

  //Hermite Curve
  if (type == 0) {
    struct matrix *h = make_hermite();

    coeffs->m[0][0] = p1;
    coeffs->m[1][0] = p3;
    coeffs->m[2][0] = p2-p1;
    coeffs->m[3][0] = p4-p3;

    matrix_mult(h, coeffs);
    free_matrix(h);
  }

  //Bezier Curve
  if (type == 1) {
    struct matrix *b = make_bezier();

    coeffs->m[0][0] = p1;
    coeffs->m[1][0] = p2;
    coeffs->m[2][0] = p3;
    coeffs->m[3][0] = p4;

    matrix_mult(b, coeffs);
    free_matrix(b);
  }
  return coeffs;
}
コード例 #6
0
ファイル: matrix.c プロジェクト: hrxiao/graphics03
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
			double p2
		double p3
		double p4
		int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite
  ====================*/
  struct matrix * generate_curve_coefs( double p1, double p2, 
  	double p3, double p4, int type) {
  	struct matrix * m = new_matrix(4, 1);
  	m->m[0][0] = p1;
  	m->m[1][0] = p2;
  	m->m[2][0] = p3;
  	m->m[3][0] = p4;
  	if (type == HERMITE_MODE) {
  		matrix_mult(make_hermite(),m);
  	}
  	else {
  		matrix_mult(make_bezier(),m);
  	}
	return m;
  }
コード例 #7
0
ファイル: matrix.c プロジェクト: sallybao29/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {

	struct matrix* coefs = new_matrix(4, 1);
	coefs -> m[0][0] = p1;
	coefs -> m[1][0] = p2;
	coefs -> m[2][0] = p3;
	coefs -> m[3][0] = p4;

	if (type == HERMITE_MODE)
		matrix_mult(make_hermite(), coefs);
	else
		matrix_mult(make_bezier(), coefs);
	return coefs;
}
コード例 #8
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs(
 /*Hermite: p0  Bezier:p0*/ double p1,
 /*Hermite: p1 Bezier: p1*/ double p2, 
 /*Hermite: r1 Bezier: p2*/ double p3,
 /*Hermite: r2 Bezier: p3*/ double p4, int type) {
  struct matrix *curve_coefs = new_matrix(4,1);
  curve_coefs->m[0][0] = p1;
  curve_coefs->m[1][0] = p2;
  curve_coefs->m[2][0] = p3;
  curve_coefs->m[3][0] = p4;
  if(type == HERMITE_MODE)
    matrix_mult(make_hermite(),curve_coefs);
  if(type == BEZIER_MODE)
    matrix_mult(make_bezier(),curve_coefs);
  return curve_coefs;
}
コード例 #9
0
ファイル: matrix.c プロジェクト: emmaavera/my_curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
    struct matrix * g = new_matrix(4, 1);
    g->m[0][0] = p1;
    g->m[1][0] = p2;
    g->m[2][0] = p3;
    g->m[3][0] = p4;
    struct matrix *c;
    if (type == HERMITE_MODE) {
      c = make_hermite();
    }
    if (type == BEZIER_MODE) {
      c = make_bezier();
    }
    matrix_mult(c, g);
    return g;
}
コード例 #10
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  struct matrix * m = new_matrix(4, 4);
  if (type){
    m->m[0][0]=p1;
    m->m[1][0]=p2;
    m->m[2][0]=p3;
    m->m[3][0]=p4;
    matrix_mult(make_bezier(),m);
  }
  else{
    m->m[0][0]=p1;
    m->m[1][0]=p3;
    m->m[2][0]=p2-p1;
    m->m[3][0]=p4-p3;
    matrix_mult(make_hermite(),m);
  }
  m->lastcol=1;
  return m;
}
コード例 #11
0
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {

  struct matrix * m = new_matrix(1, 4);
  struct matrix * hermite = make_hermite();
  struct matrix * bezier = make_bezier();
  m->m[0][0] = p1;
  m->m[0][0] = p2;
  m->m[0][0] = p3;
  m->m[0][0] = p4;
  
  if (type == 0) { //Hermite
    matrix_mult( hermite, m );
  }
  else { //Bezier
    matrix_mult( bezier, m );
  }
  return m;
  
}
コード例 #12
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  struct matrix * m = new_matrix(1,4);
  if(HERMITE_MODE == type) {
    m->m[0][0] = p1;
    m->m[0][1] = p3;
    m->m[0][2] = (p2 - p1);
    m->m[0][3] = (p4 - p3);
    matrix_mult(make_hermite(), m);
  }
  else{
    m->m[0][0] = p1;
    m->m[0][1] = p2;
    m->m[0][2] = p3;
    m->m[0][3] = p4;
    matrix_mult(make_bezier(), m);
  }
    
  return m;

}
コード例 #13
0
ファイル: matrix.c プロジェクト: margarthebar/mycurves
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  struct matrix *m;
  struct matrix *a = new_matrix(4,1);
  a->lastcol = 1;
  if(type==0){//hermite
    m = make_hermite();
    a->m[0][0] = p1;//p0
    a->m[1][0] = p3;//p1
    a->m[2][0] = p2;//r0
    a->m[3][0] = p4;//r1
  }else{//bezier
    m = make_bezier();
    a->m[0][0] = p1;
    a->m[1][0] = p2;
    a->m[2][0] = p3;
    a->m[3][0] = p4;
  }
  matrix_mult(m,a);
  return a;
}
コード例 #14
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
Inputs: double p1
double p2
double p3
double p4
int type
Returns:
A matrix containing the values for a, b, c and d of the
equation at^3 + bt^2 + ct + d for the curve defined
by p1, p2, p3 and p4.
Type determines whether the curve is bezier or hermite

03/16/12 14:42:46
jdyrlandweaver
====================*/
struct matrix * generate_curve_coefs( double p1, double p2,
double p3, double p4, int type) {
  struct matrix * k = new_matrix(4,4);
  struct matrix * m = new_matrix(4, 1);
  if(type == 0){ //hermite
    m->m[0][0] = p1;
    m->m[1][0] = p2;
    m->m[2][0] = p3 - p1;
    m->m[3][0] = p4 - p2;
    k = make_hermite();
  }
  else if(type == 1){ //bezier
    m->m[0][0] = p1;
    m->m[1][0] = p3;
    m->m[2][0] = p2;
    m->m[3][0] = p4;
    k = make_bezier();
  }
  matrix_mult(k, m);
  free_matrix(k);
  return m;
}
コード例 #15
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  struct matrix * m = new_matrix(4,4);
  ident(m);
  struct matrix * points = new_matrix(4,1);
  if (type == 0 ){
    points->m[0][0] = p1;
    points->m[1][0] = p2;
    points->m[2][0] = p2-p1;
    points->m[3][0] = p4-p3;
    matrix_mult(make_hermite(), points);
  }
   if (type == 1 ){
     points->m[0][0] = p1;
     points->m[1][0] = p2;
     points->m[2][0] = p3;
     points->m[3][0] = p4;
    matrix_mult(make_bezier(), points);
   }
  return m;

}
コード例 #16
0
ファイル: matrix.c プロジェクト: stuydw/curves
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
    
    struct matrix * inverse = new_matrix(4, 4);
    struct matrix * m = new_matrix(4, 1);
    
    m -> m[0][0] = p1;
    m -> m[1][0] = p4;
    m -> m[2][0] = (p2 - p1);
    m -> m[3][0] = (p4 - p3);
                                                                                                                                                                                                                                                                                                                                                              
    if (type == 0) {
      inverse = make_hermite();
      matrix_mult(inverse, m);
      return m;
    }
    else {
      inverse = make_bezier();
      matrix_mult(inverse, m);
      return m;
    }
}
コード例 #17
0
ファイル: matrix.c プロジェクト: kmejia/3-Graphics
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs: double p1
  double p2
  double p3
  double p4
  int type
  Returns:
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined
  by p1, p2, p3 and p4.
  Type determines whether the curve is bezier or hermite
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2,
				      double p3, double p4, int type) {
  struct matrix *B= new_matrix(4,1);
  B->m[0][0]=p1;
  B->m[0][1]=p2;
  B->m[0][2]=p3;
  B->m[0][3]=p4;
  struct matrix *A;
  if (type){//zero means hermite,1 is bezier
    A =make_bezier();
  }
  else{
    A = make_hermite();
  }
  matrix_mult(A,B);
  return B;
  //now Matrtix B is in the form
  /*
  [a]
  [b]
  [c]
  [d] */
}
コード例 #18
0
ファイル: matrix.c プロジェクト: Zilby/Stuy-Stuff
/*======== struct matrix * generate_curve_coefs() ==========
  Inputs:   double p1
            double p2
	    double p3
	    double p4
	    int type
  Returns: 
  
  A matrix containing the values for a, b, c and d of the
  equation at^3 + bt^2 + ct + d for the curve defined 
  by p1, p2, p3 and p4.
  
  Type determines whether the curve is bezier or hermite

  03/16/12 14:42:46
  jdyrlandweaver
  ====================*/
struct matrix * generate_curve_coefs( double p1, double p2, 
				      double p3, double p4, int type) {
  struct matrix * coef = new_matrix(4,1);
  coef->m[0][0] = p1;
  coef->m[1][0] = p2;
  coef->m[2][0] = p3;
  coef->m[3][0] = p4;
  if(type == HERMITE_MODE){
    struct matrix * herm = make_hermite();
    matrix_mult(herm, coef);
    free_matrix(herm);
    return coef;
  }
  else if(type == BEZIER_MODE){
    struct matrix * bez = make_bezier();
    matrix_mult(bez, coef);
    free_matrix(bez);
    return coef;
  }
  else{
    return NULL;
  }

}
コード例 #19
0
ファイル: extrude.cpp プロジェクト: DarkOfTheMoon/Carve
void parsePath(std::istream &in, std::vector<std::vector<carve::geom2d::P2> > &paths) {
  carve::geom2d::P2 curr, curr_ctrl;

  std::string pathname;
  // while (in.good() && !std::isspace(in.peek())) pathname.push_back(in.get());
  in >> pathname;
  std::cerr << "parsing: [" << pathname << "]" << std::endl;

  std::vector<double> vals;
  
  std::vector<carve::geom2d::P2> points;
  while (in.good()) {
    char c;

    in >> c;
    if (in.eof()) break;
    if (std::isspace(c)) continue;
    std::cerr << "[" << c << "]";

    vals.clear();
    switch (c) {
      case 'M': {
        readVals(in, vals);
        points.clear();
        for (unsigned i = 0; i < vals.size(); i += 2) {
          curr = carve::geom::VECTOR(vals[i], vals[i+1]);
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'm': {
        readVals(in, vals);
        points.clear();
        curr = carve::geom::VECTOR(0.0, 0.0);
        for (unsigned i = 0; i < vals.size(); i += 2) {
          curr += carve::geom::VECTOR(vals[i], vals[i+1]);
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'L': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); i += 2) {
          curr = carve::geom::VECTOR(vals[i], vals[i+1]);
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'l': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); i += 2) {
          curr += carve::geom::VECTOR(vals[i], vals[i+1]);
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'H': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); ++i) {
          curr.x = vals[i];
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'h': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); ++i) {
          curr.x += vals[i];
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'V': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); ++i) {
          curr.y = vals[i];
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'v': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); ++i) {
          curr.y += vals[i];
          add(points, curr);
        }
        curr_ctrl = curr;
        break;
      }
      case 'S': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); i += 4) {
          carve::geom2d::P2 c1 = curr - (curr_ctrl - curr);
          carve::geom2d::P2 c2 = carve::geom::VECTOR(vals[i+0], vals[i+1]);
          carve::geom2d::P2 p2 = carve::geom::VECTOR(vals[i+2], vals[i+3]);
          add(points, make_bezier(curr, c1, c2, p2));
          curr_ctrl = c2;
          curr = p2;
        }
        break;
      }
      case 's': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); i += 4) {
          carve::geom2d::P2 c1 = curr - (curr_ctrl - curr);
          carve::geom2d::P2 c2 = curr + carve::geom::VECTOR(vals[i+0], vals[i+1]);
          carve::geom2d::P2 p2 = curr + carve::geom::VECTOR(vals[i+2], vals[i+3]);
          add(points, make_bezier(curr, c1, c2, p2));
          curr_ctrl = c2;
          curr = p2;
        }
        break;
      }
      case 'C': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); i += 6) {
          carve::geom2d::P2 c1 = carve::geom::VECTOR(vals[i+0], vals[i+1]);
          carve::geom2d::P2 c2 = carve::geom::VECTOR(vals[i+2], vals[i+3]);
          carve::geom2d::P2 p2 = carve::geom::VECTOR(vals[i+4], vals[i+5]);
          add(points, make_bezier(curr, c1, c2, p2));
          curr_ctrl = c2;
          curr = p2;
        }
        break;
      }
      case 'c': {
        readVals(in, vals);
        for (unsigned i = 0; i < vals.size(); i += 6) {
          carve::geom2d::P2 c1 = curr + carve::geom::VECTOR(vals[i+0], vals[i+1]);
          carve::geom2d::P2 c2 = curr + carve::geom::VECTOR(vals[i+2], vals[i+3]);
          carve::geom2d::P2 p2 = curr + carve::geom::VECTOR(vals[i+4], vals[i+5]);
          add(points, make_bezier(curr, c1, c2, p2));
          curr_ctrl = c2;
          curr = p2;
        }
        break;
      }
      case 'Z':
      case 'z': {

        std::cerr << "path coords: " << std::endl;
        for (size_t i = 0; i < points.size(); ++i) {
          std::cerr << " " << i << ": " << points[i].x << "," << points[i].y;
        }
        if (points.back() == points.front()) points.pop_back();
        std::cerr << std::endl;
        paths.push_back(points);                     
        curr = curr_ctrl = carve::geom::VECTOR(0.0, 0.0);
        break;
      }
      default: {
        std::cerr << "unhandled path op: [" << c << "]" << std::endl;
        throw std::runtime_error("failed");
      }
    }
  }
}