user3474126
user3474126

Reputation: 63

Rounding up to the nearest 4 (simple math)

I am REALLY bad at math and have been trying to figure this out for quite a while but its all guesswork really.

I have a grid that is filled with X boxes. 4 boxes can fit horizontally along the grid. For every multiple of 4 boxes +1, the grid needs to expand vertically to fit a new row of boxes in.

Each box is 300 units deep/in height.

So say I have 4 boxes, the grid needs to be 300 units deep.

If I have 5 boxes it needs to be 600 units deep.

If I have 8 boxes it needs to be 600 units deep.

If I have 9 boxes it needs to be 900 units deep.

If I have 14 boxes it needs to be 1200 units deep.

Here is my mostly commented code trying to figure this out by Googling for people's solutions to rounding up.

The closest I am at the moment is:

height of grid = numberofentries rounded up to the nearest 4, divided by 4, times 300px

Thankyou for reading. I am shit at math. Below is my random commented stuff and someones function that may or may not be needed (there are plenty of math functions on Google but I just don't know what I'm doing)

//Integer totalHeight= 300*((Math.round(imageURLs.size()/6)));

//Integer totalHeight = imageURLs.size()*300/4;

Integer totalHeight = (roundUp(imageURLs.size(), 4)) / 4 * 300;

// height = numberofentries / 4 rounded up to the nearest multiple of 4

// height = numberofentries rounded up to the nearest 4, divided by 4, times 300px

//Double heightMath= 300*(4*(Math.ceil(Math.abs(imageURLs.size()/4))));

//Long heightMath= 300*(long)Math.floor(imageURLs.size() + 1d);

//Integer totalHeight = (int) (double) heightMath;

int roundUp (int numToRound, int multiple) {
    if (multiple == 0) {
        return numToRound;
    }

    int remainder = numToRound % multiple;
    if (remainder == 0) {
        return numToRound;
    }
    return numToRound + multiple - remainder;
}

I don't even know if I'm supposed to be "rounding". It could be some other math term... PS this is not homework, its for functionality in my project that composites images to a single image ...just they need formatting

Here is the full code and the output image from the https://i.sstatic.net/dKP1f.jpg (warning 2mb image)

public class testImage {

//int roundUp(int numToRound, int multiple) 
//{ 
// if(multiple == 0) 
// { 
//  return numToRound; 
// } 
//
// int remainder = numToRound % multiple;
// if (remainder == 0)
//  return numToRound;
// return numToRound + multiple - remainder;
//}

    int roundUp(int numToRound, int multiple) {
    return (numToRound+multiple-1) / multiple;
}

public testImage() throws IOException

  {



      ArrayList <String> imageURLs = new ArrayList<>();

imageURLs.add("C:\\Users\\J\\Desktop\\test1.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test2.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test3.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test4.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test5.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test6.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test7.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test1.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test2.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test3.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test4.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test5.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test6.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test7.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test7.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test6.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test7.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test1.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test2.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test3.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test4.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test5.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test6.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test7.jpg");


//Integer totalHeight= 300*((Math.round(imageURLs.size()/6)));

//Integer totalHeight = imageURLs.size()*300/4;


//Integer totalHeight = 300*(roundUp(imageURLs.size(), 4));

//Integer totalHeight = (roundUp(imageURLs.size(),4))/4*300;

// height = numberofentries / 4 rounded up to the nearest multiple of 4

// height = numberofentries rounded up to the nearest 4, divided by 4, times 300px

Double heightMath= 300*(4*(Math.ceil(Math.abs(imageURLs.size()/4.0))));

//Long heightMath= 300*(long)Math.floor(imageURLs.size() + 1d);

Integer totalHeight = (int) (double) heightMath;

if (totalHeight < 300){ 
      totalHeight = 300; 
  }

BufferedImage result = new BufferedImage(
                               864, totalHeight, //work these out
                               BufferedImage.TYPE_INT_RGB);

Graphics g = result.getGraphics();

Integer x = 0;
Integer y = 0;




for(String imageURL : imageURLs){

        BufferedImage bi = ImageIO.read(new File(imageURL));
        g.drawImage(bi, x, y, null);
        x += 216;
        if(x > result.getWidth()){
            x = 0;
            y += bi.getHeight();
        }

          ImageIO.write(result,"png",new File("C:\\Users\\J\\Desktop\\resultimage.jpg"));
    }

Upvotes: 1

Views: 232

Answers (2)

user3474126
user3474126

Reputation: 63

Sorry to put you through all this. I discovered that the dimensions of the test images I was using is actually 200 instead of the 300 that I had stretched them to on my html pages. This caused the big gap in the image composite and made me think the formulas weren't working.

I also found that I had to change values in the rest of the code to compensate for this, as images were missing off the screen.

Thanks for your help everyone.

A screenshot shows it working: https://i.sstatic.net/SXLlc.jpg

The working code is:

public class testImage {

int roundUp(int numToRound, int multiple) {
    return (numToRound+multiple-1) / multiple;
}

public testImage() throws IOException

  {

ArrayList <String> imageURLs = new ArrayList<>();

imageURLs.add("C:\\Users\\J\\Desktop\\test5.jpg");
imageURLs.add("C:\\Users\\J\\Desktop\\test5.jpg");

Integer totalHeight = (roundUp(imageURLs.size(),4))*200;

System.out.println(imageURLs.size());
System.out.println(totalHeight);

BufferedImage result = new BufferedImage(
                               736, totalHeight, //work these out
                               BufferedImage.TYPE_INT_RGB);

Graphics g = result.getGraphics();

Integer x = 0;
Integer y = 0;

for(String imageURL : imageURLs){

        BufferedImage bi = ImageIO.read(new File(imageURL));
        g.drawImage(bi, x, y, null);
        x += 184;
        if(x >= result.getWidth()){
            x = 0;
            y += bi.getHeight();
        }

          ImageIO.write(result,"png",new File("C:\\Users\\J\\Desktop\\resultimage.jpg"));
    }
}
}

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726839

The common trick to round the division by N is to add N-1, and divide in integers:

int roundUp(int numToRound, int multiple) {
    return (numToRound+multiple-1) / multiple;
}

This assumes that multiple is not zero.

Upvotes: 1

Related Questions