views:

148

answers:

2

I want to print each digit of pi number as a colored pixel, so, I get an input, with the pi number, then parse it into a list, each node containing a digit (I know, I'll use an array later), but I never get this painted to screen... Can someone help me to see where I'm wrong?

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.MemoryImageSource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

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

public class PiPainter extends JPanel
{
    private static final long   serialVersionUID    = 6416932054834995251L;

    private static int pixels[];
    private static List<Integer> pi = new ArrayList<Integer>();
    private final static int[] color = {
        0xFF000000, 0xFF787878, 0xFF008B00, 0xFF00008B, 0xFF008B8B,
        0xFF008B00, 0xFFCDCD00, 0xFFFF4500, 0xFF8B0000, 0xFFFF0000
        };

    public static void readFile(String name)
    {
        File file = new File(name);
        BufferedReader reader = null;
        char[] digits;

        try
        {
            reader = new BufferedReader(new FileReader(file));

            String text = null;

            while((text = reader.readLine()) != null)
            {
                digits = text.toCharArray();

                for(char el : digits)
                    if(el != ' ')
                    pi.add(Character.getNumericValue(el));
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void paint(Graphics gg) 
    {
        // page containing pi number, http://gc3.net84.net/pi.htm
        // other source, http://newton.ex.ac.uk/research/qsystems/collabs/pi/pi6.txt
        readFile("c:\\pi.txt");
        int h = 300;
        int w = 300;
        int digit;
        int i = 0;  

        pixels = new int[w * h];

        for (int y = 0; y < h; y++) 
        {
          for (int x = 0; x < w; x++) 
          {
              pixels[i] = color[pi.get(i)];
              i++;
          }
        }

        Image art = createImage(new MemoryImageSource(w, h, pixels, 0, w));

        gg.drawImage(art, 0, 0, this);
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.getContentPane().add(new PiPainter(), BorderLayout.CENTER);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,400);
        frame.setVisible(true);
    }
}
+3  A: 

I'm not familiar with MemoryImageSource. Here's the first 16 300 digits of π, repeated in a BufferedImage and using your color table.

Pi.png

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PiRaster extends JPanel {

    private static final int W = 30;
    private static final int H = 30;
    private static List<Integer> pi = new ArrayList<Integer>();
    BufferedImage image;
    private int[] clut = {
        0x000000, 0x787878, 0x008B00, 0x00008B, 0x008B8B,
        0x008B00, 0xCDCD00, 0xFF4500, 0x8B0000, 0xFF0000
    };

    public PiRaster() {
        this.setPreferredSize(new Dimension(W * 16, H * 10));
        String s = ""
            + "31415926535897932384626433832795028841971693993751"
            + "05820974944592307816406286208998628034825342117067"
            + "98214808651328230664709384460955058223172535940812"
            + "84811174502841027019385211055596446229489549303819"
            + "64428810975665933446128475648233786783165271201909"
            + "14564856692346034861045432664821339360726024914127";
        for (int i = 0; i < s.length(); i++) {
            pi.add(s.charAt(i) - '0');
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        if (image == null) {
            image = (BufferedImage) createImage(W, H);
            int i = 0;
            for (int row = 0; row < H; row++) {
                for (int col = 0; col < W; col++) {
                    image.setRGB(col, row, clut[pi.get(i)]);
                    if (++i == pi.size()) {
                        i = 0;
                    }
                }
            }
        }
        g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PiRaster());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
trashgod
A: 

@trashgod

Thanks for your answer, I changed it a little bit to achieve what I was looking for ; )

Now you can change the width easily to achieve a better view of the image and fit the contents, and the number don't repeats, making it easy to perceive patterns (if there might be). Oh, and I added about 2~3 lines at the end, to clarify it.

alt text

package edu.pi;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PiRaster extends JPanel
{
    private static final long       serialVersionUID    = -1298205187260747210L;

    private static int              W;
    private static int              H;
    private static List<Integer>    pi                  = new ArrayList<Integer>();
    BufferedImage                   image;
    private int[]                   clut                = { 
            0x000000, 0x787878, 0x008B00, 0x00008B, 0x008B8B,
            0x008B00, 0xCDCD00, 0xFF4500, 0x8B0000, 0xFF0000
            };

    public PiRaster()
    {
        String s = "3."
                + "14159265358979323846264338327950288419716939937510"
                + "58209749445923078164062862089986280348253421170679"
                + "82148086513282306647093844609550582231725359408128"
                + "48111745028410270193852110555964462294895493038196"
                + "44288109756659334461284756482337867831652712019091"
                + "45648566923460348610454326648213393607260249141273"
                + "72458700660631558817488152092096282925409171536436"
                + "78925903600113305305488204665213841469519415116094"
                + "33057270365759591953092186117381932611793105118548"
                + "07446237996274956735188575272489122793818301194912"
                + "98336733624406566430860213949463952247371907021798"
                + "60943702770539217176293176752384674818467669405132"
                + "00056812714526356082778577134275778960917363717872"
                + "14684409012249534301465495853710507922796892589235"
                + "42019956112129021960864034418159813629774771309960"
                + "51870721134999999837297804995105973173281609631859"
                + "50244594553469083026425223082533446850352619311881"
                + "71010003137838752886587533208381420617177669147303"
                + "59825349042875546873115956286388235378759375195778"
                + "18577805321712268066130019278766111959092164201989";

        char temp;

        for (int i = 0; i < s.length(); i++)
        {
            temp = s.charAt(i);
            if (temp >= 48 && temp <= 57)
                pi.add(s.charAt(i) - '0');
        }

        W = 50;
        H = s.length() / W + 3;
        this.setPreferredSize(new Dimension(W * 10, H * 10));
    }

    @Override
    public void paintComponent(Graphics g)
    {
        if (image == null)
        {
            image = (BufferedImage) createImage(W, H);
            int i = 0;
            boolean end = false;

            for (int row = 0; row < H && !end; row++)
            {
                for (int col = 0; col < W && !end; col++)
                {
                    image.setRGB(col, row, clut[pi.get(i)]);
                    if (++i == pi.size())
                    {
                        i = 0;
                        end = true;
                    }
                }
            }
        }

        g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {

            @Override
            public void run()
            {
                JFrame frame = new JFrame("Pi raster");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new PiRaster());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Wilhelm
In this case, like your 1:1 aspect ratio better. You may be able to simplify your loop termination logic using a labelled break. http://java.sun.com/docs/books/tutorial/java/nutsandbolts/branch.html
trashgod