Comment dessiner une roue de couleurs RVB en Java


J'essaie de dessiner une roue de couleurs RVB en Java, mais je ne peux pas obtenir le dégradé par une forme circulaire. Je veux juste le dessiner à l'écran, sans aucune interaction de l'utilisateur.

C'est tout ce que j'ai pour l'instant:

public void paint (Graphics g){
        super.paint(g);

        int red = 255;
        int green = 0;
        int blue = 0;
        int x1 = 500;
        int y1 = 305;
        int x2 = 500;
        int y2 = 50;

        while (green != 255){
            g.setColor(new Color(red, green, blue));
            green++;
            g.drawLine(x1, y1, x2, y2);
            x2++;
            if (y2 < y1){
                y2++;
            }
        }
        while (red != 0){
            g.setColor(new Color(red, green, blue));
            red--;
            g.drawLine(x1, y1, x2, y2);
            x2--;
            y2++;
        }
        x2 = 500;
        while (blue != 255){
            g.setColor(new Color(red, green, blue));
            blue++;
            g.drawLine(x1, y1, x2, y2);
            x2--;
            if (y2 > y1){
                y2--;
            }
        }

        while (red != 255){
            green--;
            g.setColor(new Color(red, green, blue));
            red++;
            g.drawLine(x1, y1, x2, y2);
            x2++;
            y2--;
        }
    }                
}

Qui attire le dégradé comme ceci

C'est ce que je veux

Author: Leonardo, 2016-03-28

2 answers

Voici ma solution pour dessiner une roue de couleurs RVB en Java:

public class Main {

    public static void main(String[] args) {
        int rad = 1024;
        BufferedImage img = new BufferedImage(rad, rad, BufferedImage.TYPE_INT_RGB);

        // Center Point (MIDDLE, MIDDLE)
        int centerX = img.getWidth() / 2;
        int centerY = img.getHeight() / 2;
        int radius = (img.getWidth() / 2) * (img.getWidth() / 2);

        // Red Source is (RIGHT, MIDDLE)
        int redX = img.getWidth();
        int redY = img.getHeight() / 2;
        int redRad = img.getWidth() * img.getWidth();

        // Green Source is (LEFT, MIDDLE)
        int greenX = 0;
        int greenY = img.getHeight() / 2;
        int greenRad = img.getWidth() * img.getWidth();

        // Blue Source is (MIDDLE, BOTTOM)
        int blueX = img.getWidth() / 2;
        int blueY = img.getHeight();
        int blueRad = img.getWidth() * img.getWidth();

        for (int i = 0; i < img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
                int a = i - centerX;
                int b = j - centerY;

                int distance = a * a + b * b;
                if (distance < radius) {
                    int rdx = i - redX;
                    int rdy = j - redY;
                    int redDist = (rdx * rdx + rdy * rdy);
                    int redVal = (int) (255 - ((redDist / (float) redRad) * 256));

                    int gdx = i - greenX;
                    int gdy = j - greenY;
                    int greenDist = (gdx * gdx + gdy * gdy);
                    int greenVal = (int) (255 - ((greenDist / (float) greenRad) * 256));

                    int bdx = i - blueX;
                    int bdy = j - blueY;
                    int blueDist = (bdx * bdx + bdy * bdy);
                    int blueVal = (int) (255 - ((blueDist / (float) blueRad) * 256));

                    Color c = new Color(redVal, greenVal, blueVal);

                    float hsbVals[] = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);

                    Color highlight = Color.getHSBColor(hsbVals[0], hsbVals[1], 1);

                    img.setRGB(i, j, RGBtoHEX(highlight));
                } else {
                    img.setRGB(i, j, 0xFFFFFF);
                }
            }
        }

        try {
            ImageIO.write(img, "png", new File("wheel.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static int RGBtoHEX(Color color) {
        String hex = Integer.toHexString(color.getRGB() & 0xffffff);
        if (hex.length() < 6) {
            if (hex.length() == 5)
                hex = "0" + hex;
            if (hex.length() == 4)
                hex = "00" + hex;
            if (hex.length() == 3)
                hex = "000" + hex;
        }
        hex = "#" + hex;
        return Integer.decode(hex);
    }
}
 1
Author: Teddy Clapp, 2017-02-06 03:57:40

Modification de la luminosité

À partir de là, il semble que le moyen le plus simple d'éclaircir une couleur soit de la convertir en HSB.

float hsbVals[] = Color.RGBtoHSB( originalColor.getRed(),
                                   originalColor.getGreen(),
                                   originalColor.getBlue(), null );

    Color highlight = Color.getHSBColor( hsbVals[0], hsbVals[1], 
      0.5f * ( 1f + hsbVals[2] )); // Play with this part to modify rate of change

Rendre circulaire

D'après ce que vous avez, il semble que vous ayez essentiellement besoin d'effacer tout sauf une région circulaire au milieu.

De cette réponse , il semble que la classe Area soit la plus facile.

 public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g.create();
        Rectangle2D rectangleNotToDrawIn = new Rectangle2D.Double(100, 100, 20, 30); 
           // You will need to find out what size ellipse you need
        Area outside = calculateOutside(rectangleNotToDrawIn);

        // draw color wheel here

        g2.setPaint(Color.black); // assuming you want black
        g2.setClip(outside);
        g2.drawLine(0, 0, getWidth(), getHeight());

    }

// Change this method to take in an ellipse shape.
    private Area calculateOutside(Rectangle2D r) {
        Area outside = new Area(new Rectangle2D.Double(0, 0, getWidth(), getHeight()));
        outside.subtract(new Area(r));
        return outside;
    }
 0
Author: Laurel, 2017-05-23 12:00:07