Создание случайных прямоугольников при обработке - PullRequest
0 голосов
/ 12 марта 2020

Я хочу сделать случайные прямоугольники при обработке. До сих пор я использовал циклы для создания прямоугольника размера окна, но я не могу понять, как сделать случайным образом только 10 прямоугольников. Вот мой пример кода для вас:

void setup()
{
  size(400, 400);
}

void draw()
{
  background(0); // Black Background

  stroke(255); // White lines

  for (int j = 0; j <= height; j += 40)
  {
    for (int i = 0; i < width; i += 40)
    {
      fill(0); 
      rect(i, j, 40, 40);
    }
  }
}

Он показывает 100 черных прямоугольников, но я хочу видеть только 10 черных прямоугольников. Например: первая строка получит случайный 1 прямоугольник, вторая строка получит 2, третья строка получит 1 и будет идти до 10.

1 Ответ

0 голосов
/ 15 апреля 2020

Есть несколько способов решить эту забавную домашнюю работу / упражнения.

Во-первых, нужно нарисовать правильное количество блоков в столбце:

void setup()
{
  size(400, 400);

  background(0); // Black Background
  fill(0);
  stroke(255); // White lines

  int boxSize = 40;
  int maxBoxes = 1;

  for (int j = 0; j <= height; j += boxSize)
  {
    // box count per row
    int boxCount = 0;

    for (int i = 0; i < width; i += boxSize)
    {
      // only draw the max number of boxes
      if(boxCount < maxBoxes){

        rect(i, j, 40, 40);
        // increment per row box count
        boxCount++;
      }
    }
    // increment max boxes per box
    maxBoxes++;
  }
}

Во-вторых, позиции для нарисованных блоков в столбец должен быть рандомизированным, но в идеале не перекрываться. Однажды можно разделить все пространство решения на разделы: каждый раздел имеет собственный диапазон позиций, чтобы он не перекрывал следующий.

void setup()
{
  size(400, 400);

  background(0); // Black Background
  fill(0);
  stroke(255); // White lines

  int boxSize = 40;
  int maxBoxes = 1;
  int totalBoxes = width / boxSize;

  for (int j = 0; j <= height; j += boxSize)
  {
    // box count per row
    int boxCount = 0;
    // a list of box indices of where to draw a box (as opposed
    int[] randomXIndices = new int[maxBoxes];
    // how many index ranges to span per row
    int indexRangePerBox = totalBoxes / maxBoxes;
    // for each random index 
    for(int k = 0 ; k < maxBoxes; k++)
    {
      // pre-calculate which random index to select
      // using separate ranges per box to avoid overlaps
      randomXIndices[k] = (int)random(indexRangePerBox * k, indexRangePerBox * (k + 1));
    }

    for (int i = 0; i < width; i += boxSize)
    {
      // only draw the max number of boxes
      if(boxCount < maxBoxes)
      {

        int randomX = randomXIndices[boxCount] * boxSize;

        rect(randomX, j, 40, 40);
        // increment per row box count
        boxCount++;
      }

    }
    // increment max boxes per box
    maxBoxes++;
  }
}

void draw(){
}

void mousePressed(){
  setup();
}

Нажмите, чтобы сбросить. Обратите внимание, что нижние строки почти всегда выглядят одинаково:

  1. меньше места для маневра, чтобы выбрать случайную позицию
  2. random() - грубый генератор псевдослучайных чисел, но есть Есть лучшие стратегии, такие как randomGaussian(), noise() и т. д. c.
  3. В целом существуют другие стратегии для изучения выбора случайных позиций и избежания перекрытий

Демонстрационная версия ниже:

function setup()
{
  createCanvas(400, 400);
  reset();
  // reset once per second
  setInterval(reset, 1000);
}

function reset(){
  background(0); // Black Background
  fill(0);
  stroke(255); // White lines
  
  var boxSize = 40;
  var maxBoxes = 1;
  var totalBoxes = width / boxSize;
  
  for (var j = 0; j <= height; j += boxSize)
  {
    // box count per row
    var boxCount = 0;
    // a list of box indices of where to draw a box (as opposed
    var randomXIndices = new Array(maxBoxes);
    // how many index ranges to span per row
    var indexRangePerBox = totalBoxes / maxBoxes;
    // for each random index 
    for(var k = 0 ; k < maxBoxes; k++)
    {
      // pre-calculate which random index to select
      // using separate ranges per box to avoid overlaps
      randomXIndices[k] = floor(random(indexRangePerBox * k, indexRangePerBox * (k + 1)));
    }
    
    for (var i = 0; i < width; i += boxSize)
    {
      // only draw the max number of boxes
      if(boxCount < maxBoxes)
      {
        
        var randomX = randomXIndices[boxCount] * boxSize;
        
        rect(randomX, j, 40, 40);
        // increment per row box count
        boxCount++;
      }
      
    }
    // increment max boxes per box
    maxBoxes++;
  }
}

function draw(){
}

function mousePressed(){
  reset();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

grid with less and less random positioned boxes

...