Disegno di un bel cerchio in Java

Sto usando Java Grafica e continuo a ricevere “brutto” circoli.

Ecco il mio programma Java rende
Disegno di un bel cerchio in Java

E qui è la stessa cosa che si è fatta in Matlab Disegno di un bel cerchio in Java

Penso che sia chiaro che il Java non è “bello”, cercando, come Matlab, in particolare sui bordi del cerchio. Nota che questo non ha nulla a che fare con la risoluzione…queste immagini sono praticamente le stesse dimensioni. Nota anche che ho già l’impostazione di rendering suggerimenti.

Ecco stand-alone con funzione Principale è possibile eseguire per questo test.

package test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class SimplePaint02 {

    private static final int LINE_THICKNESS = 4;
    private static final int LINE_GAP = 10;
    private Color lineColor = Color.red;

    public static void main(String[] args) {
        new SimplePaint02();
    }

    public SimplePaint02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

        @Override
        public void paintComponent(Graphics g) {

            int radius = 50;
            BufferedImage buffer = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = buffer.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);

            Ellipse2D circle = new Ellipse2D.Float(0, 0, radius,radius);
            Shape clip = g2d.getClip();
            g2d.setClip(circle);
            AffineTransform at = g2d.getTransform();

            g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(45),radius / 2, radius / 2));

            int gap = LINE_GAP;

            g2d.setColor(Color.WHITE);
            g2d.fill(circle);

            g2d.setColor(lineColor);
            //g2d.setStroke(new BasicStroke(LINE_THICKNESS));
            for (int index = 0; index < 10; index++) {
                int x1 = index*gap-(LINE_THICKNESS/2);
                int y1 = 0;
                int x2 = index*gap+(LINE_THICKNESS/2);
                int y2 = radius;
                int width = x2 - x1;
                int height = y2 - y1;

                g2d.fillRect(x1, y1, width, height);
                //g2d.drawLine(index * gap, 0, index * gap, getRadius());
            }

            g2d.setTransform(at);
            g2d.setClip(clip);
            g2d.dispose();
            g.drawImage(buffer, 0, 0, this);
        }

    }

}
attivare l’antialiasing? stackoverflow.com/questions/179955/…
1) Per aiutare meglio prima, nel post SSCCE. 2) Mantenere l’aggiunta di rendering suggerimenti. Mi dimentico sempre che quelli a fare la magia.
c’è un equivalente per la grafica? che sembra essere per i font
Ho aggiunto un SSCCE
developmentality.wordpress.com/2010/02/09/…

InformationsquelleAutor CodeGuy | 2013-01-20

5 Replies
  1. 5

    EDIT: si Prega di vedere il Codice di Tizio risposta qui sotto per trovare una soluzione. Questo è contrassegnato in modo corretto, perché era Joey Rohan che capito inizialmente!


    Ho avuto bordo liscio quando ho provato la stessa cosa:

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,    RenderingHints.VALUE_ANTIALIAS_ON);

    Disegno di un bel cerchio in Java

    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import javax.imageio.ImageIO;
    
    public class DrawSmoothCircle {
        public static void main(String[] argv) throws Exception {
            BufferedImage bufferedImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = bufferedImage.createGraphics();
    
            g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setPaint(Color.green);
            g2d.fillOval(10, 10, 50, 50);
            g2d.dispose();
    
            ImageIO.write(bufferedImage, "png", new File("e:\\newimage.png"));
        }
    }

    AGGIORNAMENTO:

    Dopo aver cercato per un sacco:

    Non c’è niente di sbagliato con il codice, ma,

    Bene, purtroppo Java 2D (o almeno del Sole implementazione corrente) non supporta il “soft clipping”.

    Ma Anche un trucco per la clip:
    Seguire Questo link,è possibile ottenere quello che stai chiedendo.

    (Anche, ho preso un buon margine, causa i din non utilizzare clip cose,nella mia immagine sopra)

    Dove ha fatto le righe di passare? Se si esegue il codice, si otterrà un cerchio con linee.
    Non voglio dire din non con la metà delle linee.Ok prova.
    Sì, funziona benissimo senza linee. Qualcosa nel processo di creazione di linee a farlo.
    Il problema non è in realtà quando il disegno di forme, ma in caso di riempimento di pittura o di un Clip.
    Vedo. Quindi non pensate che c’è un altro modo per disegnare questa forma, senza l’utilizzo di un clip?

    InformationsquelleAutor joey rohan

  2. 4

    Ecco la risposta. Ho adattato la maggior parte del codice da questo sito. Date un’occhiata:

    Disegno di un bel cerchio in Java

    Ecco il codice:

    public void paintComponent(Graphics g) {
    
            //Create a translucent intermediate image in which we can perform
            //the soft clipping
            GraphicsConfiguration gc = ((Graphics2D) g).getDeviceConfiguration();
            BufferedImage img = gc.createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT);
            Graphics2D g2 = img.createGraphics();
    
            //Clear the image so all pixels have zero alpha
            g2.setComposite(AlphaComposite.Clear);
            g2.fillRect(0, 0, getWidth(), getHeight());
    
            //Render our clip shape into the image.  Note that we enable
            //antialiasing to achieve the soft clipping effect.  Try
            //commenting out the line that enables antialiasing, and
            //you will see that you end up with the usual hard clipping.
            g2.setComposite(AlphaComposite.Src);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(Color.WHITE);
            g2.fillOval(0, 0, getRadius(), getRadius());
    
            //Here's the trick... We use SrcAtop, which effectively uses the
            //alpha value as a coverage value for each pixel stored in the
            //destination.  For the areas outside our clip shape, the destination
            //alpha will be zero, so nothing is rendered in those areas.  For
            //the areas inside our clip shape, the destination alpha will be fully
            //opaque, so the full color is rendered.  At the edges, the original
            //antialiasing is carried over to give us the desired soft clipping
            //effect.
            g2.setComposite(AlphaComposite.SrcAtop);
            g2.setColor(lineColor);
            int gap = LINE_GAP;
            AffineTransform at = g2.getTransform();
    
            g2.setTransform(AffineTransform.getRotateInstance(Math.toRadians(45),getRadius() / 2, getRadius() / 2));
    
            for (int index = 0; index < 10; index++) {
                int x1 = index*gap-(LINE_THICKNESS/2);
                int y1 = 0;
                int x2 = index*gap+(LINE_THICKNESS/2);
                int y2 = getRadius();
                int width = x2 - x1;
                int height = y2 - y1;
    
                g2.fillRect(x1, y1, width, height);
            }
    
            g2.setTransform(at);
            g2.dispose();
    
            //Copy our intermediate image to the screen
            g.drawImage(img, 0, 0, null);
        }
    Contento che hai capito :)+1

    InformationsquelleAutor CodeGuy

  3. 2

    Aggiornamento

    OK. Quindi l’idea è di non utilizza il clipping a tutti ma invece di fare il ritagliati a forma sottraendo aree l’una dall’altra.

    Disegno di un bel cerchio in Java

    import java.awt.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    public class SimplePaint02 {
    
        private static final int LINE_THICKNESS = 4;
        private static final int LINE_GAP = 10;
        private Color lineColor = Color.red;
    
        public static void main(String[] args) {
            new SimplePaint02();
        }
    
        public SimplePaint02() {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception ex) {
                    }
    
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            int radius = 75;
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(radius, radius);
            }
    
            @Override
            public void paintComponent(Graphics g) {
    
    
                Ellipse2D circle = new Ellipse2D.Float(0, 0, radius, radius);
                Area lines = new Area();
    
                int gap = LINE_GAP;
    
                for (int index = 0; index < 10; index++) {
                    int x1 = index * gap - (LINE_THICKNESS / 2);
                    int y1 = 0;
                    int x2 = index * gap + (LINE_THICKNESS / 2);
                    int y2 = radius;
                    int width = x2 - x1;
                    int height = y2 - y1;
    
                    Shape lineShape = new Rectangle2D.Double(x1, y1, width, height);
                    lines.add(new Area(lineShape));
    
                    //g3d.fillRect(x1, y1, width, height);
                    //g2d.drawLine(index * gap, 0, index * gap, getRadius());
                }
                //g2d.setClip(circle);
    
                Area circleNoLines = new Area(circle);
                circleNoLines.subtract(lines);
    
                Area linesCutToCircle = new Area(circle);
                linesCutToCircle.subtract(circleNoLines);
    
                //g2d.setTransform(at);
                BufferedImage buffer = new BufferedImage(radius * 2, radius * 2, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = buffer.createGraphics();
    
                RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(45), radius / 2, radius / 2));
                g2d.setRenderingHints(rh);
                g2d.setColor(Color.ORANGE);
                g2d.fill(linesCutToCircle);
                g2d.setColor(Color.RED);
                g2d.fill(circleNoLines);
    
                g2d.dispose();
                g.drawImage(buffer, 0, 0, this);
            }
        }
    }

    Vecchio codice

    Parte del problema è che le operazioni di rendering in genere non si applicano a un Clip, anche se si applica per il Shape quando viene disegnato. Io di solito per risolvere (ultimo) pittura Shape stesso. E. G.

    Disegno di un bel cerchio in Java

    1,5 pixel BasicStroke qui è usato per il cerchio rosso che leviga i bordi grezzi prodotto dalla Clip.

    import java.awt.*;
    import java.awt.geom.AffineTransform;
    import java.awt.geom.Ellipse2D;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    
    public class SimplePaint02 {
    
        private static final int LINE_THICKNESS = 4;
        private static final int LINE_GAP = 10;
        private Color lineColor = Color.red;
    
        public static void main(String[] args) {
            new SimplePaint02();
        }
    
        public SimplePaint02() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception ex) {
                    }
    
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            int radius = 75;
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension((int)(1.1*radius), (int)(1.1*radius));
            }
    
            @Override
            public void paintComponent(Graphics g) {
    
                BufferedImage buffer = new BufferedImage(radius*2, radius*2, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = buffer.createGraphics();
    
                RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                rh.put(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE);
                rh.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                g2d.setRenderingHints(rh);
    
                Ellipse2D circle = new Ellipse2D.Float(0, 0, radius,radius);
                Shape clip = g2d.getClip();
                g2d.setClip(circle);
                AffineTransform at = g2d.getTransform();
    
                g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(45),radius / 2, radius / 2));
    
                int gap = LINE_GAP;
    
                g2d.setColor(Color.WHITE);
                g2d.fill(circle);
    
                g2d.setColor(lineColor);
                //g2d.setStroke(new BasicStroke(LINE_THICKNESS));
                for (int index = 0; index < 10; index++) {
                    int x1 = index*gap-(LINE_THICKNESS/2);
                    int y1 = 0;
                    int x2 = index*gap+(LINE_THICKNESS/2);
                    int y2 = radius;
                    int width = x2 - x1;
                    int height = y2 - y1;
    
                    g2d.fillRect(x1, y1, width, height);
                    //g2d.drawLine(index * gap, 0, index * gap, getRadius());
                }
    
                g2d.setTransform(at);
                g2d.setClip(clip);
                g2d.setClip(null);
                g2d.setStroke(new BasicStroke(1.5f));
                g2d.draw(circle);
                g2d.dispose();
                g.drawImage(buffer, 0, 0, this);
            }
        }
    }
    La struttura la rende un aspetto liscio ora. Tuttavia io non includono la struttura nel mio cerchio con linee. Avete una soluzione che non disegna questo schema?
    Ah.. pignola, pignola ( devo tipo di ammirare ;). Vedere l’aggiornamento.
    Ben fatto. Molto bello!
    Sei il benvenuto. 🙂 SrcAtop sembra funzionare abbastanza bene.

    InformationsquelleAutor Andrew Thompson

  4. 1

    Ho usato drawPolygon metodo per tracciare il cerchio, generare un array di la maggior parte dei punti sulla circonferenza del cerchio con la proposta di raggio.
    Codice:

               import java.awt.*;
               import java.applet.*;
    
                /*<applet code="OnlyCircle" width=500 height=500>
                     </applet>*/
    
              public class OnlyCircle extends Applet{
    
                public void paint(Graphics g){
    
    
                  int r=200;//radius
                  int x1=250;//center x coordinate
                  int y1=250;//center y coordinate
                  double x2,y2;
                  double a=0;
                  double pi=3.14159;
                  int count=0; 
                  int i=0;
                  int f=0;
                  int[] x22=new int[628319];
                  int[] y22=new int[628319];
    
                 while(a<=2*pi&&i<628319&&f<628319)
                      {
                       double k=Math.cos(a);
                       double l=Math.sin(a);
                         x2=x1+r*k;
                         y2=y1+r*l;
                      x22[i]=(int)x2;
                      y22[f]=(int)y2;
                       i++;
                       f++;
                       a+=0.00001;
                      }
                   int length=x22.length;
                   g.drawPolygon(x22,y22,length);
                     }
                   }

    InformationsquelleAutor Deepeshkumar

  5. 0

    È possibile attivare l’anti-aliasing:

    Graphics2D g2 = (Graphics2D) g;
    Map<RenderingHints.Key, Object> hints = new HashMap<RenderingHints.Key, Object>();
    hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    g2.setRenderingHints(hints);

    Vi suggerisco anche di disegnare la Grafica di un oggetto si ottiene dal paintComponent metodo piuttosto che la creazione di un intermedio BufferedImage.

    Sto già facendo io credo (vedere il codice che ho postato)…sto solo non si fa con la creazione di una mappa, che è tutto. Sto usando g2d.setRenderingHints
    Voi lo fate il BufferedImage oggetto Graphics2D, non è la Grafica che si ottiene nel metodo paintComponent.
    Ma che non necessariamente modificare l’output, woudld?

    InformationsquelleAutor Dan D.

Lascia un commento