Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate cell sizes and draw (with lines in between) them

Tags:

java

graphics

I want to draw a grid and draw stuff in the cells (to keep things easy just fill them). Overall I've got it pretty much working only in some panel sizes the cell is about 1 pixel off of where it should be placed (overlapping the line). TBH I haven't really done enough calculating to possibly find the answer myself, so my apologies for that, I'm really not too sure how to approach this "bug" either though.

Anyway, here's the code:

public class Gui extends JFrame {

public static void main(String[] args) {
    new Gui().setVisible(true);
}

public Gui() {
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    add(new JPanel() {
        public static final int SIZE = 3;
        /** Line thickness ratio to a block */
        public static final float LINE_THICKNESS = 0.1f;

        /** @return the width of a block. */
        protected final int getBlockWidth() {
            return getWidth() / SIZE;
        }

        /** @return the height of a block. */
        protected final int getBlockHeight() {
            return getHeight() / SIZE;
        }

        /**  @return the width of a cell. */
        protected final int getCellWidth() {
            return (int) Math.ceil(getBlockWidth()*(1-LINE_THICKNESS));
        }

        /** @return the height of a cell. */
        protected final int getCellHeight() {
            return (int) Math.ceil(getBlockHeight()*(1-LINE_THICKNESS));
        }

        @Override
        public void paintComponent(Graphics g) {
            g.setColor(new Color(0, 0, 255, 100));
            int lineWidth = (int) (LINE_THICKNESS * getBlockWidth());
            int lineHeight = (int) (LINE_THICKNESS * getBlockHeight());
            for(int i = 0; i <= SIZE; i++) {
                g.fillRect(i * getBlockWidth() - lineWidth / 2, 0, lineWidth, getHeight());
                g.fillRect(0, i * getBlockHeight() - lineHeight/2, getWidth(), lineHeight);
            }
            g.setColor(new Color(255, 0, 0, 100));
            for(int i = 0; i < SIZE; i++) {
                for(int j = 0; j < SIZE; j++) {
                    int x = j * getBlockWidth() + lineWidth/2;
                    int y = i * getBlockHeight() + lineHeight/2;
                    Graphics temp = g.create(x, y, getCellWidth(), getCellHeight());
                    drawCell(temp, i, j);
                }
            }
        }

        private void drawCell(Graphics g, int i, int j) {
            g.fillRect(0, 0, getCellWidth(), getCellHeight());
        }
    });
    setLocation(new Point(500, 200));
    setSize(new Dimension(600, 600));
}
}

If you run it you'll probably see what I mean. I can't think of a good explanation in words. At first I thought I had to add + 1 to x and y since I want to draw next to the line, but this (obviously) just shifts the problem to the other side.

Running this with a SIZE bigger (like 30) gives me another bug that it gives open space to the sides. I know (or assume) this is because I'm using integers and it isn't too big of a deal though. But hints for a better approach (in general) are always welcome.

like image 290
Alowaniak Avatar asked Oct 11 '13 00:10

Alowaniak


People also ask

What is the formula for calculating cell size?

*To figure the length of one cell, divide the number of cells that cross the diameter of the field of view into the diameter of the field of view. For example, if the diameter of the field is 5 mm and you estimate that 50 cells laid end to end would cross the diameter, then 5 mm/50 cells = 0.1mm/cell.

How do you determine the size of a cell under a microscope?

Divide the number of cells in view with the diameter of the field of view to figure the estimated length of the cell. If the number of cells is 50 and the diameter you are observing is 5 millimeters in length, then one cell is 0.1 millimeter long. Measured in microns, the cell would be 1,000 microns in length.


1 Answers

There are several ways you can fix this. I will not give you code, since I believe (based on how you asked your question) you are one of those who like to think and solve problems on their own.

First of all: first draw the background on the whole panel and then draw the lines. There'll be no while lines and the drawing will be slightly faster.

Second way: the order of drawing is important. You can safely draw the background first (even if it overlaps) and then overwrite it with borders.

Third way: do not use ints. Use floats or doubles. All your trouble will go away.

Fourth way: calculate the remainder. You can predict when the lines are drawn and when not, think about it. Predict it and draw appropriately.

like image 92
Dariusz Avatar answered Sep 29 '22 07:09

Dariusz