public static List<double[]> bezierArc(double x1,double y1,double x2,double y2,double startAng,double extent){
  double tmp;
  if (x1 > x2) {
    tmp=x1;
    x1=x2;
    x2=tmp;
  }
  if (y2 > y1) {
    tmp=y1;
    y1=y2;
    y2=tmp;
  }
  double fragAngle;
  int Nfrag;
  if (Math.abs(extent) <= 90f) {
    fragAngle=extent;
    Nfrag=1;
  }
 else {
    Nfrag=(int)Math.ceil(Math.abs(extent) / 90f);
    fragAngle=extent / Nfrag;
  }
  double x_cen=(x1 + x2) / 2f;
  double y_cen=(y1 + y2) / 2f;
  double rx=(x2 - x1) / 2f;
  double ry=(y2 - y1) / 2f;
  double halfAng=(fragAngle * Math.PI / 360.0);
  double kappa=Math.abs(4.0 / 3.0 * (1.0 - Math.cos(halfAng)) / Math.sin(halfAng));
  List<double[]> pointList=new ArrayList<>();
  for (int iter=0; iter < Nfrag; ++iter) {
    double theta0=((startAng + iter * fragAngle) * Math.PI / 180.0);
    double theta1=((startAng + (iter + 1) * fragAngle) * Math.PI / 180.0);
    double cos0=Math.cos(theta0);
    double cos1=Math.cos(theta1);
    double sin0=Math.sin(theta0);
    double sin1=Math.sin(theta1);
    if (fragAngle > 0.0) {
      pointList.add(new double[]{x_cen + rx * cos0,y_cen - ry * sin0,x_cen + rx * (cos0 - kappa * sin0),y_cen - ry * (sin0 + kappa * cos0),x_cen + rx * (cos1 + kappa * sin1),y_cen - ry * (sin1 - kappa * cos1),x_cen + rx * cos1,y_cen - ry * sin1});
    }
 else {
      pointList.add(new double[]{x_cen + rx * cos0,y_cen - ry * sin0,x_cen + rx * (cos0 + kappa * sin0),y_cen - ry * (sin0 - kappa * cos0),x_cen + rx * (cos1 - kappa * sin1),y_cen - ry * (sin1 + kappa * cos1),x_cen + rx * cos1,y_cen - ry * sin1});
    }
  }
  return pointList;
}

public static List < double [ ] > bezierArc ( double x1 , double y1 , double x2 , double y2 , double startAng , double extent ) { double tmp ; if ( x1 > x2 ) { tmp = x1 ; x1 = x2 ; x2 = tmp ; } if ( y2 > y1 ) { tmp = y1 ; y1 = y2 ; y2 = tmp ; } double fragAngle ; int Nfrag ; if ( Math . abs ( extent ) <= 90f ) { fragAngle = extent ; Nfrag = 1 ; } else { Nfrag = ( int ) Math . ceil ( Math . abs ( extent ) / 90f ) ; fragAngle = extent / Nfrag ; } double x_cen = ( x1 + x2 ) / 2f ; double y_cen = ( y1 + y2 ) / 2f ; double rx = ( x2 - x1 ) / 2f ; double ry = ( y2 - y1 ) / 2f ; double halfAng = ( fragAngle * Math . PI / 360.0 ) ; double kappa = Math . abs ( 4.0 / 3.0 * ( 1.0 - Math . cos ( halfAng ) ) / Math . sin ( halfAng ) ) ; List < double [ ] > pointList = new ArrayList < > ( ) ; for ( int iter = 0 ; iter < Nfrag ; ++ iter ) { double theta0 = ( ( startAng + iter * fragAngle ) * Math . PI / 180.0 ) ; double theta1 = ( ( startAng + ( iter + 1 ) * fragAngle ) * Math . PI / 180.0 ) ; double cos0 = Math . cos ( theta0 ) ; double cos1 = Math . cos ( theta1 ) ; double sin0 = Math . sin ( theta0 ) ; double sin1 = Math . sin ( theta1 ) ; if ( fragAngle > 0.0 ) { pointList . add ( new double [ ] { x_cen + rx * cos0 , y_cen - ry * sin0 , x_cen + rx * ( cos0 - kappa * sin0 ) , y_cen - ry * ( sin0 + kappa * cos0 ) , x_cen + rx * ( cos1 + kappa * sin1 ) , y_cen - ry * ( sin1 - kappa * cos1 ) , x_cen + rx * cos1 , y_cen - ry * sin1 } ) ; } else { pointList . add ( new double [ ] { x_cen + rx * cos0 , y_cen - ry * sin0 , x_cen + rx * ( cos0 + kappa * sin0 ) , y_cen - ry * ( sin0 - kappa * cos0 ) , x_cen + rx * ( cos1 - kappa * sin1 ) , y_cen - ry * ( sin1 + kappa * cos1 ) , x_cen + rx * cos1 , y_cen - ry * sin1 } ) ; } } return pointList ; }
generates an array of bezier curves to draw an arc . < p / > ( x1 , y1 ) and ( x2 , y2 ) are the corners of the enclosing rectangle . angles , measured in degrees , start with 0 to the right ( the positive x axis ) and increase counter - clockwise . the arc extends from startang to startang + extent . i . e . startang = 0 and extent = 180 yields an openside - down semi - circle . < p / > the resulting coordinates are of the form double [ ] { x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 } such that the curve goes from ( x1 , y1 ) to ( x4 , y4 ) with ( x2 , y2 ) and ( x3 , y3 ) as their respective bezier control points . < p / > note : this code was taken from reportlab ( www . reportlab . org ) , an excellent pdf generator for python ( bsd license : http : / / www . reportlab . org / devfaq . html # 1 . 3 ) .
