Random () происходит только один раз - PullRequest
0 голосов
/ 03 августа 2020

У меня есть это для () l oop, где я произвольно выбираю фрагменты изображения, чтобы отображать 16 фрагментов изображения в случайном порядке.

Я выбираю эти фрагменты из массив, и у меня есть переменная, которая определяет, какой фрагмент будет выбран в массиве.

Проблема в том, что я бы подумал, что случайная функция будет запускаться для каждого кадра, но запускается только один раз.

Вот код:

void setup() {

    size(720,720);

    slices = new PImage[16];

        slices[0] = loadImage("1.png");
        slices[1] = loadImage("2.png");
        slices[2] = loadImage("3.png");
        slices[3] = loadImage("4.png");
        slices[4] = loadImage("5.png");
        slices[5] = loadImage("6.png");
        slices[6] = loadImage("7.png");
        slices[7] = loadImage("8.png");
        slices[8] = loadImage("9.png");
        slices[9] = loadImage("10.png");
        slices[10] = loadImage("11.png");
        slices[11] = loadImage("12.png");
        slices[12] = loadImage("13.png");
        slices[13] = loadImage("14.png");
        slices[14] = loadImage("15.png");
        slices[15] = loadImage("16.png");
        
        frameRate(1);


    
}

void draw() {

        

        for (int a = 0; a < 16; a++){

        int rand = int(random(slices.length));
        
        image(slices[rand],x,y,size,size);
         x += size;

         if (a % 4 == 3){
            y += size;
            x = 0;
            }
            
        }

Он отображает рандомизированные фрагменты только один раз, а затем я получаю исправленное изображение. Я бы хотел, чтобы в каждом кадре появлялись случайные фрагменты.

Спасибо за вашу помощь!

Ответы [ 2 ]

1 голос
/ 04 августа 2020

У вас 2 проблемы в вашем коде. Во-первых, вы можете не захотеть выбирать случайный индекс.

Это потому, что одно и то же изображение может быть выбрано дважды. Вместо этого вы можете перетасовать массив перед рисованием изображений, например:

for (int i = slices.length; i > 1; i--) {
  //choose a random index for the i-th element to be swapped with
  int j = (int)random(i);

  //swap them
  PImage temp = slices[j];
  slices[j] = slices[i-1];
  slices[i-1] = temp;
}

Во-вторых, индекс выбирается для каждого кадра, и изображения тоже рисуются, но вы не можете их видеть, потому что ваш код никогда не сбрасывает y обратно в 0, что означает, что они находятся под экраном.

Вы можете исправить это, добавив

y = 0;

в верхнюю или нижнюю часть вашего draw ().

1 голос
/ 04 августа 2020

Может быть, вы забыли очистить экран (например, позвонили по номеру background()) (это означает, что после того, как вы нарисовали изображение, оно останется визуализированным)?

Вы также можете использовать для l oop в настройке, чтобы избежать повторения самого себя :

int numSlices = 16;
PImage[] slices = new PImage[numSlices];
float x, y;
float size = 180;

void setup() {

  size(720, 720);

  
  for(int i = 0 ; i < numSlices; i++){
    slices[i] = loadImage((i+1) + ".png");
  }
  
  frameRate(1);
}

void draw() {
  background(255);
  
  for (int a = 0; a < numSlices; a++) {

    int rand = int(random(numSlices));

    image(slices[rand], x, y, size, size);
    x += size;

    if (a % 4 == 3) {
      y += size;
      x = 0;
    }
  }
  y = 0;
}

Кроме того, вы можете легко отформатировать свой код (через CMD+T в OSX или Ctrl+T в Windows / Linux)

Обновление Камакура (+1) правильно указывает, что y не сбрасывается до 0.

В качестве отвлечения я не указываю вам на * Метод 1018 * shuffle():

int numSlices = 16;
PImage[] slices = new PImage[numSlices];
float x, y;
float size = 180;

IntList indices = new IntList();

void setup() {

  size(720, 720);


  for(int i = 0 ; i < numSlices; i++){
    slices[i] = loadImage((i+1) + ".png");
    indices.append(i);
  }

  frameRate(1);
}

void draw() {
  background(255);
  // shuffle list
  indices.shuffle();
  // reset y
  y = 0;
  
  for (int a = 0; a < numSlices; a++) {

    int rand = indices.get(a);

    image(slices[rand], x, y, size, size);
    x += size;

    if (a % 4 == 3) {
      y += size;
      x = 0;
    }
  }
  
}

Дополнительная причина поиграть с ним, кроме опыта обучения, состоит в том, что вряд ли повторение того же случайного индекса будет. 1024 *

Что касается стыковки / перемешивания, вот модифицированная версия примера Загрузка и отображение :

/**
 * Load and Display 
 * 
 * Images can be loaded and displayed to the screen at their actual size
 * or any other size. 
 */

PImage img;  // Declare variable "a" of type PImage
// shuffled image
PImage imgShuffled;
// list of indices to shuffle
IntList shuffleIndices = new IntList();
// configure image slicing rows/columns
int rows = 4;
int cols = 4;
// total sections
int numSections = rows * cols;
// image section dimensions
int sectionWidth;
int sectionHeight;

void setup() {
  size(640, 360);
  frameRate(1);
  // The image file must be in the data folder of the current sketch 
  // to load successfully
  img = loadImage("https://processing.org/examples/moonwalk.jpg");  // Load the image into the program
  // calculate section dimensions
  sectionWidth  = img.width / cols;
  sectionHeight = img.height / rows;
  // allocate a separate image to copy shuffled pixels into
  imgShuffled = createImage(img.width, img.height, RGB);
  // populate image section indices
  for(int i = 0 ; i < numSections; i++){
    shuffleIndices.append(i);
  }
}

void shuffleImage(){
  // shuffle the list
  shuffleIndices.shuffle();
  // Ta-da!
  println(shuffleIndices);
  // loop through each section
  for(int i = 0 ; i < numSections; i++){
    // index to row, col conversion
    int srcCol = i % cols;
    int srcRow = i / cols;
    // convert to pixel coordinates to copy from
    int srcX = srcCol * sectionWidth;
    int srcY = srcRow * sectionHeight;
    // get random / shuffled index
    int index = shuffleIndices.get(i);
    // same row, col, to pixel conversion to copy to
    int dstCol = index % cols;
    int dstRow = index / cols;
    int dstX = dstCol * sectionWidth;
    int dstY = dstRow * sectionHeight;
    // copy from original image to shuffled pixel coordinates
    imgShuffled.copy(img,srcX,srcY,sectionWidth,sectionHeight,dstX,dstY,sectionWidth,sectionHeight);
  }
}

void draw() {
  shuffleImage();
  // Displays the image at its actual size at point (0,0)
  image(imgShuffled, 0, 0);
}

Изображение Moonwalk перетасовано в виде сетки 4x4

...