Looped State: Not Perfect
This animated gif is a part of a partially generative animation I created to show a reason behind why a large amount of food is wasted. I titled this animation “Not Perfect” as it’s meant to show that a lot of food is thrown out before it even reaches the shelves of stores because that food is “not perfect.”
A decent percentage of food is wasted in production and distribution due to not meeting “appearance quality standards”. One study shows that 25-30% of carrots handled by M.H. Poskitt Carrots where rejected, about half of those due to purely cosmetic defects (Gustavsson, 2011).
This is an easily preventable waste of food, as surveys show that consumers would be okay with buying products with cosmetic defects, as long as the taste is not affected (which in most cases, it is not).
For more details on the process behind this animation, see this blog post.
To download the full animation, click here.
/* "Not Perfect" by Melody Elwood
** Made in Processing 3.5.4
** V2 published 30/09/2020
** Some sound effects from salamisound.com
*/
//Imports
import java.util.*; //For Arraylist
import processing.sound.*; //For Sounds
//CONSTANTS ********************************
//About the conveyor
float CONVEYOR_SPEED = 10;
//About the food
float BAD_CHANCE = 33.333; //Out of 100 (33)
float COLOUR_MIN = 150;
float COLOUR_MAX = 255; //how far the tint can go
float START_X = 1090;
float START_Y = 234;
int FRAMES_BETWEEN_NEW_FOOD = 20;
int FOOD_SIZE = 50;
int SHRINK_SPEED = 2;
//About the pusher
float PUSHER_X = 215;
float PUSHER_Y = 553;
float PUSHER_END_X = 280;
float PUSHER_TARGET_X = 400;
int PUSHER_SPEED = 50;
//volume
float PUSHER_VOLUME = 0.5 ; //0.0 to 1.0
float SCANNER_VOLUME = 0; //0.0 to 1.0
//CONSTANTS END ***************************
//Global variables
PImage conveyor;
PImage machine;
PImage pusherSprite;
String[] foodSprites;
SoundFile pusherSound;
SoundFile scannerSound;
List<Food> foodList = new ArrayList<Food>();
int lastCreated = 0;
Pusher pusher = new Pusher();
void setup()
{
//Basic setup
size(1080,1080);
background(255);
frameRate(60);
//create the machinery "background" and pusher
conveyor = loadImage("conveyor.png");
pusherSprite = loadImage("pusher.png");
machine = loadImage("machine.png");
//Create a list of all possible food sprites
File file = new File(sketchPath() + "\\Data\\good");
String[] files = file.list();
foodSprites = new String[files.length];
for(int i = 0; i < files.length; i++)
{
foodSprites[i] = sketchPath() + "\\Data\\good\\" + files[i];
}
//Load sounds
pusherSound = new SoundFile(this, "Mic-Hit.mp3"); // Previously used: "salamisound-8106538-open-stainless-steel-pedal.mp3"
pusherSound.cue(0.1);
pusherSound.amp(PUSHER_VOLUME);
scannerSound = new SoundFile(this, "salamisound-5709353-mechanical-arm-move-elec.mp3");
scannerSound.amp(SCANNER_VOLUME);
//A little more Attribution
println("Some sound from salamisound.com");
}
void draw()
{
createBackground();
if(frameCount-lastCreated > FRAMES_BETWEEN_NEW_FOOD || frameCount == 1)
{
lastCreated = frameCount;
createNewFood();
}
moveFood();
drawFood();
updatePusher();
drawMachine();
//For making a gif
saveFrame("frame-######.png");
}
void createBackground()
{
background(255);
imageMode(CENTER);
image(conveyor, width/2, height/2+100,1080,1080);
}
void createNewFood()
{
foodList.add(new Food());
//println(foodList);
}
void moveFood()
{
for(int i = 0; i < foodList.size(); i++)
{
foodList.get(i).move();
}
}
void drawFood()
{
for(int i = 0; i < foodList.size(); i++)
{
foodList.get(i).draw();
}
}
void updatePusher()
{
pusher.draw();
pusher.push();
}
void drawMachine()
{
//draw the machine on top
machine.resize(600,0);
image(machine, width/2+150, height/2-150);
}