0
\$\begingroup\$

I am trying to generate a map based on the Golden Ratio:

a+b is to a as a is to b.

I was looking at a JavaScript math library that had a built-in phi, but I wasn't sure how to apply it.

I also tried using hard-coded values as can be seen in this example:

<!DOCTYPE html>
<html>

  <head>
    <script src="https://unpkg.com/konva@7.1.0/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Drag and Drop Demo</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      }

    </style>
  </head>

  <body>
    <div id="container"></div>
    <script>
      function getRandomColor() {
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) {
          color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
      }

      var multiplier = 10;
      var width = 65;
      var height = 50;
      var color = getRandomColor();
      var x = 0;
      var y = 0;

      var stage = new Konva.Stage({
        container: 'container',
        width: width * multiplier,
        height: height * multiplier,
      });

      var layer = new Konva.Layer();

      function square(s) {
        var box = new Konva.Rect({
          x: x,
          y: y,
          width: s * multiplier,
          height: s * multiplier,
          fill: color,
          strokeWidth: 0,
          draggable: true,
        });

        // add cursor styling
        box.on('mouseover', function() {
          document.body.style.cursor = 'pointer';
        });
        box.on('mouseout', function() {
          document.body.style.cursor = 'default';
        });

        x += s * multiplier;
        color = getRandomColor();

        return box;
      }

      var level_map = [];

      level_map = [1, 2, 3, 5, 8, 13, 21, 34]; // golden ratio

      level_map.forEach(function(size, index) {
        level_map[index] = square(size);
      });

      x = level_map[0].x();
      y = level_map[0].height();

      console.log("x: ", x);
      console.log("y: ", y);

      level_map.forEach(function(square, index) {
        layer.add(square);
      });

      stage.add(layer);

    </script>
  </body>

</html>

Which creates the following pattern:

Actual Result

What I am looking for is more like this:

Desired Result

Note: this grid was roughly hand drawn and is not to scale.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Start with an area of dimensions fib(i) by fib(i-1) units, then...

  • Pick a starting "end" of the shape.

  • Create a "room" square of size fib(i-1)

  • Set the new working area to the original area minus the room.

  • Decrease i and repeat.

Golden ratio

You can obviously reverse the process and start from the inside.

\$\endgroup\$
2
  • \$\begingroup\$ Can I make it bigger? So there are a ton of little tiny squares mixed with big ones? What about repeating the pattern? \$\endgroup\$
    – oxr463
    Nov 6, 2020 at 0:09
  • \$\begingroup\$ First question... Yes, you can start with i=100 if you like, . And remember that you can always scale/move rooms, so a room that's 1,000 units with the formula above, you might scale to take only 10 units in world space. Your smallest roomes would be tiny. As to repeating the pattern... You're moving into a different class of problem The google term you want is "Packing algorithm"... How to pack shapoes in an area efficiently. Eg ijcai.org/Proceedings/09/Papers/092.pdf or stackoverflow.com/q/1213394/156755 \$\endgroup\$
    – Basic
    Nov 6, 2020 at 8:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .