Search code examples
javaswinggraphicspaintcomponentspiral

Java Graphics Drawing Custom Circular


I want to draw a shape at center that starts from the center of the panel and keeps expanding out in circular shape like in the picture link below :

https://www.dropbox.com/s/lnxi1be8uogn2zx/20140320_124537.jpg

but i am having difficulty with the center shape , its like it doesnt show up at all on the panel. Here is the class i wrote for the shapes

package graphics.test;


import java.awt.Graphics;
import javax.swing.JPanel;

public class DrawPanel extends JPanel {

public void paintComponent(Graphics g){
    super.paintComponent(g);
    int width = getWidth();
    int height = getHeight();

    //top right corner
    g.drawLine(0, 0, width/4, height/6);
    g.drawLine(0, 0, width/4, height/4);
    g.drawLine(0, 0, width/4, height/3);
    //top left corner
    g.drawLine(width, 0, width - width/4, height/6);
    g.drawLine(width, 0, width - width/4, height/4);
    g.drawLine(width, 0, width - width/4, height/3);
    //bottom left corner
    g.drawLine(width, height, width - width/3, height - height/6);
    g.drawLine(width, height, width - width/4, height - height/4);
    g.drawLine(width, height, width - width/4, height - height/3);
    //bottom right corner
    g.drawLine(0, height, width/3, height - height/6);
    g.drawLine(0, height, width/4, height - height/4);
    g.drawLine(0, height, width/4, height - height/3);
    //center

    for (int i = width/2; i < width/3; i--)
    {
        for (int j = height/2; j < height/3; j--)
        {
            g.drawLine(i,j,i,j);
        }
    }


}

}


Solution

  • That looks like an Archimedean Spiral ( http://en.wikipedia.org/wiki/Archimedean_spiral )

    import java.awt.BasicStroke;
    import java.awt.BorderLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Shape;
    import java.awt.geom.AffineTransform;
    import java.awt.geom.Path2D;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class SpiralDrawPanelTest
    {
        public static void main(String[] args)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    createAndShowGUI();
                }
            });
        }
    
        private static void createAndShowGUI()
        {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().setLayout(new BorderLayout());
            f.getContentPane().add(new SpiralDrawPanel(),BorderLayout.CENTER);
            f.setSize(800, 800);
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    }
    
    class SpiralDrawPanel extends JPanel {
    
        @Override
        public void paintComponent(Graphics gr)
        {
            super.paintComponent(gr);
            Graphics2D g = (Graphics2D)gr;
    
            AffineTransform at = 
                AffineTransform.getTranslateInstance(
                    getWidth()/2, getHeight()/2);
    
            BasicStroke stroke =
                new BasicStroke(1.0f,
                    BasicStroke.CAP_BUTT,
                    BasicStroke.JOIN_MITER,
                    10.0f, new float[]{10.0f}, 0.0f);
            g.setStroke(stroke);
            Shape shape = 
                at.createTransformedShape(
                    createArchimedeanSpiral(Math.PI*10, 10, 250));
            g.draw(shape);
    
        }
    
        private static Shape createArchimedeanSpiral(
            double totalAngleRad, double alpha, int steps)
        {
            Path2D path = new Path2D.Double();
            path.moveTo(0, 0);
            double angleDeltaRad = totalAngleRad / steps;
            for (int i=0; i<=steps; i++)
            {
                double angleRad = i * angleDeltaRad;
                double x = Math.sin(angleRad) * alpha * angleRad;
                double y = Math.cos(angleRad) * alpha * angleRad;
                path.lineTo(x, y);
            }
            return path;
    
        }
    }
    

    EDIT for the comment.

    import java.awt.BorderLayout;
    import java.awt.Graphics;
    import java.awt.geom.Path2D;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class SpiralDrawPanelTest
    {
        public static void main(String[] args)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    createAndShowGUI();
                }
            });
        }
    
        private static void createAndShowGUI()
        {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().setLayout(new BorderLayout());
            f.getContentPane().add(new SpiralDrawPanel(),BorderLayout.CENTER);
            f.setSize(800, 800);
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    }
    
    class SpiralDrawPanel extends JPanel {
    
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            paintArchimedeanSpiral(g, getWidth()/2,  getHeight()/2, Math.PI * 10, 10, 250);
        }
    
        private static void paintArchimedeanSpiral(
            Graphics g, 
            double centerX, double centerY,
            double totalAngleRad, double alpha, int steps)
        {
            Path2D path = new Path2D.Double();
            path.moveTo(0, 0);
            double angleDeltaRad = totalAngleRad / steps;
            for (int i=0; i<=steps; i+=2)
            {
                double angleRad0 = i * angleDeltaRad;
                double angleRad1 = i * angleDeltaRad + angleDeltaRad;
                double x0 = centerX + Math.sin(angleRad0) * alpha * angleRad0;
                double y0 = centerY + Math.cos(angleRad0) * alpha * angleRad0;
                double x1 = centerX + Math.sin(angleRad1) * alpha * angleRad1;
                double y1 = centerY + Math.cos(angleRad1) * alpha * angleRad1;
                g.drawLine((int)x0, (int)y0, (int)x1, (int)y1);
            }
        }
    }