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); } } }
/** 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); } } }