2015-11-12 54 views
3

基本上,我需要做的功能drawArc創建一個PDF文件。 繪製和Arc在PDF生成

drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) 

我搜索在PDF specification但沒有談命令劃出一道弧線(像PostScript)...所以我想我需要以某種方式模擬弧曲線,但似乎過於難治。

任何幫助將感激,謝謝!

編輯。我發現,解決問題的drawEllipse here一個答案,但我需要實現的方法drawArc(而不是drawEllipse)。

回答

4

所以,最後我碼兩種功能劃分的解決方案:

pdfDrawArc

private void pdfDrawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { 
    System.out.println("Arc"); 
    width -= 1; 
    height -= 1; 
    int n = (int)(Math.ceil(Math.abs(arcAngle/maxAnglePerCurve()))); 
    int i; 
    double currentStartAngle = startAngle; 
    double actualArcAngle = ((double)arcAngle)/n; 
    for (i = 0; i < n; i++) { 
     double[] bezier = bezierCurve(this.x + x, this.y + y, width, height, currentStartAngle, actualArcAngle); 
     if (i == 0) 
      this.pdfMoveTo(bezier[0], bezier[1]); 
     this.pdfCurveTo(bezier [2], bezier [3], bezier [4], bezier [5], bezier [6], bezier [7]); 
     this.pdfStroke(); 
     currentStartAngle += actualArcAngle; 
    } 
} 

BeizerCurve 基於L. Maisonobe solution

private double[] bezierCurve(double x, double y, double width, double height, double startAngle, double arcAngle) { 
    double pi = 3.141592; 

    double a = width/2; 
    double b = height/2; 

    //center 
    double cx = x + a; 
    double cy = y + b; 

    //calculate trigonometric operations so we don't need to repeat the calculus 
    double cos1 = Math.cos(startAngle * pi/180); 
    double sin1 = Math.sin(startAngle * pi/180); 
    double cos2 = Math.cos((startAngle + arcAngle) * pi/180); 
    double sin2 = Math.sin((startAngle + arcAngle) * pi/180); 

    //point p1. Start point 
    double p1x = cx + a * cos1; 
    double p1y = cy - b * sin1; 

    //point d1. First derivative at start point. 
    double d1x = -a * sin1; 
    double d1y = -b * cos1; 

    //point p2. End point 
    double p2x = cx + a * cos2; 
    double p2y = cy - b * sin2; 

    //point d2. First derivative at end point 
    double d2x = -a * sin2; 
    double d2y = -b * cos2; 

    //alpha constant 
    double aux = Math.tan((arcAngle/2) * pi/180); 
    double alpha = Math.sin(arcAngle * pi/180) * (Math.sqrt(4 + 3 * aux * aux) - 1.0)/3.0; 

    //point q1. First control point 
    double q1x = p1x + alpha * d1x; 
    double q1y = p1y + alpha * d1y; 

    //point q2. Second control point. 
    double q2x = p2x - alpha * d2x; 
    double q2y = p2y - alpha * d2y; 
    return new double[] { p1x, p1y, q1x, q1y, q2x, q2y, p2x, p2y }; 
} 
+0

爲什麼你從寬度和高度減1?同時,這是什麼'maxAnglePerCurve()'做什麼? – Marius

+0

我見過的最好的最佳的最大角度到目前爲止始終是90度。如我錯了請糾正我!我看到在非常高的變焦範圍內沒有可觀察到的偏差。 – Marius