Example #1
0
void bicubicbezier2D_bbox(const Point *p0,const Point *p1,
                          const Point *p2,const Point *p3,
                          const PolyBBExtras *extra,
                          Rectangle *rect)
{
    double x[4],y[4];
    Point vl,vt,p,tt;
    double *xy;
    int i,extr;
    double u[2];

    rect->setLeft(p0->x());
    rect->setRight(p0->x());
    rect->setTop(p0->y());
    rect->setBottom(p0->y());

    rectangle_add_point(rect,p3);

    point_copy_add_scaled(&vl,p0,p1,-1);
    point_normalize(&vl);

    add_arrow_rectangle(rect,p0,&vl,extra->startLong,
            qMax(extra->startTrans, extra->middleTrans));

    point_copy_add_scaled(&vl,p3,p2,-1);
    point_normalize(&vl);

    add_arrow_rectangle(rect,p3,&vl,extra->endLong,
            qMax(extra->endTrans, extra->middleTrans));

    x[0] = p0->x(); x[1] = p1->x(); x[2] = p2->x(); x[3] = p3->x();
    y[0] = p0->y(); y[1] = p1->y(); y[2] = p2->y(); y[3] = p3->y();

    for (xy = x; xy ; xy=(xy==x?y:NULL) ) {
        extr = bicubicbezier_extrema(xy,u);
        for (i=0;i<extr;i++) {
            if ((u[i]<0) || (u[i]>1)) continue;
            p.setX(bezier_eval(x,u[i]));
            vl.setX(bezier_eval_tangent(x,u[i]));
            p.setY(bezier_eval(y,u[i]));
            vl.setY(bezier_eval_tangent(y,u[i]));
            point_normalize(&vl);
            point_get_perp(&vt,&vl);

            point_copy_add_scaled(&tt,&p,&vt,extra->middleTrans);
            rectangle_add_point(rect,&tt);
            point_copy_add_scaled(&tt,&p,&vt,-extra->middleTrans);
            rectangle_add_point(rect,&tt);
        }
    }
}
Example #2
0
/** Calculate the boundingbox for a 2D bezier curve segment.
 * @param p0 start point
 * @param p1 1st control point
 * @param p2 2nd control point
 * @param p3 end point
 * @param extra information about extra space from linewidth and arrow to add to the bounding box
 * @param rect The rectangle that the segment fits inside.
 */
void
bicubicbezier2D_bbox(const Point *p0,const Point *p1,
                     const Point *p2,const Point *p3,
                     const PolyBBExtras *extra,
                     Rectangle *rect)
{
  real x[4],y[4];
  Point vl,vt,p,tt;
  real *xy;
  int i,extr;
  real u[2];

  rect->left = rect->right = p0->x;
  rect->top = rect->bottom = p0->y;

  rectangle_add_point(rect,p3);
  /* start point */  
  point_copy_add_scaled(&vl,p0,p1,-1);
  point_normalize(&vl); 
  add_arrow_rectangle(rect,p0,&vl,extra->start_long,MAX(extra->start_trans,
                                                         extra->middle_trans));

  /* end point */
  point_copy_add_scaled(&vl,p3,p2,-1);
  point_normalize(&vl); 
  add_arrow_rectangle(rect,p3,&vl,extra->end_long,MAX(extra->end_trans,
                                                      extra->middle_trans));

  /* middle part */  
  x[0] = p0->x; x[1] = p1->x; x[2] = p2->x; x[3] = p3->x;
  y[0] = p0->y; y[1] = p1->y; y[2] = p2->y; y[3] = p3->y;

  for (xy = x; xy ; xy=(xy==x?y:NULL) ) { /* sorry */
    extr = bicubicbezier_extrema(xy,u);
    for (i=0;i<extr;i++) {
      if ((u[i]<0) || (u[i]>1)) continue;
      p.x = bezier_eval(x,u[i]);
      vl.x = bezier_eval_tangent(x,u[i]);
      p.y = bezier_eval(y,u[i]);
      vl.y = bezier_eval_tangent(y,u[i]);
      point_normalize(&vl);
      point_get_perp(&vt,&vl);

      point_copy_add_scaled(&tt,&p,&vt,extra->middle_trans);
      rectangle_add_point(rect,&tt);
      point_copy_add_scaled(&tt,&p,&vt,-extra->middle_trans);
      rectangle_add_point(rect,&tt);
    }
  }
}