Skip to main content
3 of 3
Minor punctuation fix
DMGregory
  • 141k
  • 23
  • 258
  • 401

Web application for efficient placement of blocks

Task: to develop a function that efficiently places rectangular blocks in rectangular 2D container. The location of the blocks in the container should be as dense as possible in order to rationally use the space of the container.

I am almost done but I have some problems with my code: items overlap each other

Here is my code, but I don't want use some libraries:

<!DOCTYPE html>
<html>
<head>
  <title>Block Placement Algorithm</title>
  <style>
    .container {
      width: 500px;
      height: 500px;
      position: relative;
      border: 1px solid #ccc; 
    }
    .block {
      position: absolute;
      border: 1px solid #000;
    }
  </style>
</head>
<body>
  <div class="container" id="container"></div>

  <script>
 function checkOverlap(newBlock, existingBlocks) {
  for (const block of existingBlocks) {
    if (
      newBlock.right >= block.left - blockMargin &&
      newBlock.left <= block.right + blockMargin &&
      newBlock.bottom >= block.top - blockMargin &&
      newBlock.top <= block.bottom + blockMargin
    ) {
      return true; // Якщо є перекриття з існуючим блоком
    }
  }
  return false; // Якщо немає перекриття з існуючими блоками
}

    function calculateBlockArea(blockCoordinates) {
      let totalBlockArea = 0;

      for (const block of blockCoordinates) {
        totalBlockArea += block.width * block.height;
      }

      return totalBlockArea;
    }

    // Generate block coordinates
    const blockCoordinates = [];
    const containerWidth = 500;
    const containerHeight = 500;
    const maxAttempts = 100;
    const blockMargin = 0; 

    for (let i = 0; i < 10; i++) {
      const width = Math.floor(Math.random() * 100) + 50;
      const height = Math.floor(Math.random() * 100) + 50;

      let newBlock;
      let attempts = 0;
      do {
        newBlock = {
          top: Math.floor(Math.random() * (containerHeight - height)),
          left: Math.floor(Math.random() * (containerWidth - width)),
          right: 0,
          bottom: 0,
          initialOrder: i + 1,
          width: width,
          height: height
        };

        newBlock.right = newBlock.left + width;
        newBlock.bottom = newBlock.top + height;

        attempts++;
      } while (checkOverlap(newBlock, blockCoordinates) && attempts < maxAttempts);

      blockCoordinates.push(newBlock);
    }

    // Sort blocks by initialOrder
    blockCoordinates.sort((a, b) => a.initialOrder - b.initialOrder);

    // Render blocks on the page
    const container = document.getElementById('container');

    let currentTop = 0;
    let currentLeft = 0;

    blockCoordinates.forEach(block => {
      const div = document.createElement('div');
      div.className = 'block';
      div.style.width = block.width + 'px';
      div.style.height = block.height + 'px';

      // Set position based on the order with margin
      div.style.top = currentTop + 'px';
      div.style.left = currentLeft + 'px';
      div.textContent = block.initialOrder;

      const randomColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
      div.style.backgroundColor = randomColor;

      container.appendChild(div);

      currentLeft += block.width + blockMargin; 
      if (currentLeft + block.width > containerWidth) {
        currentTop += block.height + blockMargin; 
        currentLeft = 0; 
      }
    });
  </script>
</body>
</html>