安德烈斯缺乏精确度

时间:2016-09-06 11:05:47

标签: java precision trigonometry

我写了一个小程序,使用Andres算法绘制圆形色度渐变。 以下是执行的结果:

enter image description here

如果最终用户以弧度为程序提供移位,则将使用后者以此角度开始绘制圆。 因此,渐变将从这个角度开始(这就是我想要的)。

例如,您可以看到渐变从圆圈的底部开始,而不是在下图中的左侧。

enter image description here

但正如您所见,出现了两个问题:

  1. 首先,圈子中有一些空白;
  2. 然后,圆圈的周长非常不精确。
  3. 我认为这是一个精确的问题。所以我问自己是否有一些糟糕的演员阵容但事实并非如此。 好吧,我不知道为什么我的圈子是如此不精确的原因。你能帮帮我吗?

    这是绘制圆的每个像素的类。它采用指定的班次,以弧度为单位。

    /**
     * Constructs a Pixel taking account of a shift and near the position (x0 ; y0)
     * @param x
     * @param y
     * @param color
     * @param angle
     * @param x0
     * @param y0
     */
    Pixel(double x, double y, Color color, double angle, double x0, double y0) {
        this.x = (int) (x0 + (x-x0) * Math.cos(angle) - (y-y0) * Math.sin(angle));
        this.y = (int) (y0 + (y-y0) * Math.cos(angle) + (x-x0) * Math.sin(angle));
        this.color = color;
    }
    

    现在,使用Andres算法和Pixel类绘制圆圈的代码。

    case "Andres' algorithm":
        w = 2 * Math.PI;
    
        for(double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
            x = 0;
            y = (int) (radius + current_thickness);
            double d = radius + current_thickness - 1;
    
            while (y >= x) {
                double octant_1_x = x0 + x, octant_1_y = y0 + y;
                double octant_2_x = x0 + y, octant_2_y = y0 + x;
                double octant_3_x = x0 - x, octant_3_y = y0 + y;
                double octant_4_x = x0 - y, octant_4_y = y0 + x;
                double octant_5_x = x0 + x, octant_5_y = y0 - y;
                double octant_6_x = x0 + y, octant_6_y = y0 - x;
                double octant_7_x = x0 - x, octant_7_y =  y0 - y;
                double octant_8_x = x0 - y, octant_8_y = y0 - x;
    
                max_counter++;
    
                double[] rgb_gradation_octant_1 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_1_y - y0, octant_1_x - x0) + Math.PI, w);
                updates.add(new Pixel(octant_1_x, octant_1_y,
                        Color.color(rgb_gradation_octant_1[0], rgb_gradation_octant_1[1], rgb_gradation_octant_1[2]),
                        circle_gradation_beginning, x0, y0)); // octant n°1
    
                double[] rgb_gradation_octant_2 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_2_y - y0, octant_2_x - x0) + Math.PI, w);
                updates.add(new Pixel(octant_2_x, octant_2_y,
                        Color.color(rgb_gradation_octant_2[0], rgb_gradation_octant_2[1], rgb_gradation_octant_2[2]),
                        circle_gradation_beginning, x0, y0));
    
                double[] rgb_gradation_octant_3 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_3_y - y0, octant_3_x - x0) + Math.PI, w);
                updates.add(new Pixel(octant_3_x, octant_3_y,
                        Color.color(rgb_gradation_octant_3[0], rgb_gradation_octant_3[1], rgb_gradation_octant_3[2]),
                        circle_gradation_beginning, x0, y0));
    
                double[] rgb_gradation_octant_4 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_4_y - y0, octant_4_x - x0) + Math.PI, w);
                updates.add(new Pixel(octant_4_x, octant_4_y,
                        Color.color(rgb_gradation_octant_4[0], rgb_gradation_octant_4[1], rgb_gradation_octant_4[2]),
                        circle_gradation_beginning, x0, y0)); // octant n°4
    
                double[] rgb_gradation_octant_5 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_5_y-y0, octant_5_x-x0) + Math.PI, w);
                updates.add(new Pixel(octant_5_x, octant_5_y,
                        Color.color(rgb_gradation_octant_5[0], rgb_gradation_octant_5[1], rgb_gradation_octant_5[2]),
                        circle_gradation_beginning, x0, y0)); // octant n°5
    
                double[] rgb_gradation_octant_6 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_6_y-y0, octant_6_x-x0) + Math.PI, w);
                updates.add(new Pixel(octant_6_x, octant_6_y,
                        Color.color(rgb_gradation_octant_6[0], rgb_gradation_octant_6[1], rgb_gradation_octant_6[2]),
                        circle_gradation_beginning, x0, y0));
    
                double[] rgb_gradation_octant_7 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_7_y-y0, octant_7_x-x0) + Math.PI, w);
                updates.add(new Pixel(octant_7_x, octant_7_y,
                        Color.color(rgb_gradation_octant_7[0], rgb_gradation_octant_7[1], rgb_gradation_octant_7[2]),
                        circle_gradation_beginning, x0, y0));
    
                double[] rgb_gradation_octant_8 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_8_y-y0, octant_8_x-x0) + Math.PI, w);
                updates.add(new Pixel(octant_8_x, octant_8_y,
                        Color.color(rgb_gradation_octant_8[0], rgb_gradation_octant_8[1], rgb_gradation_octant_8[2]),
                        circle_gradation_beginning, x0, y0)); // octant n°8
    
                if (d >= 2 * x) {
                    d -= 2 * x + 1;
                    x++;
                } else if (d < 2 * (radius + thickness - y)) {
                    d += 2 * y - 1;
                    y--;
                } else {
                    d += 2 * (y - x - 1);
                    y--;
                    x++;
                }
    
            }
        }
    
        gui.getImageAnimation().setMax(max_counter*8);
        break;
    

1 个答案:

答案 0 :(得分:1)

您不必“旋转”像素,只需绘制它们

Pixel(double x, double y, Color color, double angle, double x0, double y0) {
    this.x = (int) (x + x0);
    this.y = (int) (y + y0);
    this.color = getColorForAngle(angle);
}

Bresenham / Andres提供圆圈的所有像素,无需翻译/旋转它们