/*
CLASS FOR MY FACETED OBJECTS
*/
class facetedObjects {
// Arrays for Type, Size and Color of the objects
String[] Type = new String[1];
float[] Size = new float[1];
color[] Color = new color[1];
// Arrays for the position
// Pos[][] ... last/current position of the Object
// nPos[][] ... future position
float[][] Pos;
float[][] nPos;
// modes ... 1-4
int[] Mode = new int[1];
// other stuff
int index;
boolean started;
/*
CONSTRUCTOR
just initiating some important things
*/
facetedObjects () {
index = 0;
started = false;
Type[index] = "";
Size[index] = 0;
Color[index] = color (0);
Mode[index] = 1;
}
/*
ADDING DATA
expanding the arrays for the information of the objects
*/
void addData ( String nType, float nSize, color nColor ) {
if ( started ) {
Type = append ( Type, nType );
Size = append ( Size, nSize );
Color = append ( Color, nColor );
Mode = append ( Mode, 1 );
index++;
}
else {
Type[index] = nType;
Size[index] = nSize;
Color[index] = nColor;
started = true;
}
}
/*
ANALYSE
mode 1-4
4 ... get it ... activated
3 ... throw it away ... deactivated
2 ... active
1 ... inactive
*/
void analyse ( int i ) {
// some intern variables for temp-storage
int mode = 1;
boolean mode_color = false;
boolean mode_type = false;
boolean mode_size = false;
/*
three question-types: color, type, size
- checking which buttons are selected
- setting facet-mode to true if something is done here
*/
if( key_color == "none"
|| ( key_color == "rot" && red(this.Color[i]) > 150
|| key_color == "gruen" && green(this.Color[i]) > 150
|| key_color == "blau" && blue(this.Color[i]) > 150 ) )
mode_color = true;
if( key_type == "none"
|| ( key_type == "eckig" && this.Type[i] == "square"
|| key_type == "rund" && this.Type[i] == "circle" ) )
mode_type = true;
if( key_size == "none"
|| ( key_size == "klein" && this.Size[i] < 10
|| key_size == "gross" && this.Size[i] > 10 ) )
mode_size = true;
// if everything is set to "all" ... set temp-mode to active (2)
// else if this object is interesting considering all three facets ... set it temp. to active (2)
if( key_color == "none" && key_type == "none" && key_size == "none" )
mode = 2;
else if( mode_color && mode_type && mode_size
&& ( key_color != "none" || key_type != "none" || key_size != "none" ) )
mode = 2;
// if object was inactive (1) and temp-mode says it is active (2) => activate (4)
// else if .. the other way round ... => deactivate (3)
if( this.Mode[i] == 1 && mode == 2 ) { // get it / activated
mode = 4;
}
else if( this.Mode[i] == 2 && mode == 1 ) { // throw it away / deactivated
mode = 3;
}
// saves mode
this.Mode[i] = mode;
}
/*
CALCULATES POSITION
- old/current position = new position
... because the animation is done
... the old one is unused
... the current nPos is now used and so it its the real current Position
- getting the real new position considering the mode of the object
modes 1-4
1 index from the outside position array
2 lowest unused index from the inside position array
3 index from the outside position array
4 lowest unused index from the inside position array
*/
void calcPos ( int i ) {
// setting new position to current
Objects.Pos[i][0] = Objects.nPos[i][0];
Objects.Pos[i][1] = Objects.nPos[i][1];
// general temp-saving
int mode = Objects.Mode[i];
float x = 0;
float y = 0;
// considering the modes ... setting the new position
switch ( mode ) {
case ( 1 ): // mode 1 ... inactive
x = oPos[i][0];
y = oPos[i][1];
break;
case ( 2 ): // mode 2 ... active
// lowest unused inside position
x = iPos[activeIndex][0];
y = iPos[activeIndex][1];
activeIndex++;
break;
case ( 3 ): // mode 3 ... deactivated
x = oPos[i][0];
y = oPos[i][1];
break;
case ( 4 ): // mode 4 ... activated
// lowest unused inside position
x = iPos[activeIndex][0];
y = iPos[activeIndex][1];
activeIndex++;
break;
}
// saving the new position
Objects.nPos[i][0] = x;
Objects.nPos[i][1] = y;
}
}
/*
CONFIGURATES THE INTERFACE // nothing very important here
*/
void configInterface() {
GUIc = new GUIController( this );
RColor = new IFRadioController( "Farbe" );
RType = new IFRadioController( "Typ" );
RSize = new IFRadioController( "Größe" );
ColorNone = new IFRadioButton( "alle", 20, 20, RColor );
ColorRed = new IFRadioButton( "rot", 20, 40, RColor );
ColorGreen = new IFRadioButton( "grün", 20, 60, RColor );
ColorBlue = new IFRadioButton( "blau", 20, 80, RColor );
TypeNone = new IFRadioButton( "alle", 90, 20, RType );
TypeSquare = new IFRadioButton( "eckig", 90, 40, RType );
TypeCircle = new IFRadioButton( "rund", 90, 60, RType );
SizeNone = new IFRadioButton( "alle", 160, 20, RSize );
SizeLarge = new IFRadioButton( "groß", 160, 40, RSize );
SizeSmall = new IFRadioButton( "klein", 160, 60, RSize );
ColorNone.addActionListener( this );
ColorRed.addActionListener( this );
ColorGreen.addActionListener( this );
ColorBlue.addActionListener( this );
TypeNone.addActionListener( this );
TypeSquare.addActionListener( this );
TypeCircle.addActionListener( this );
SizeNone.addActionListener( this );
SizeLarge.addActionListener( this );
SizeSmall.addActionListener( this );
GUIc.add( ColorNone );
GUIc.add( ColorRed );
GUIc.add( ColorGreen );
GUIc.add( ColorBlue );
GUIc.add( TypeNone );
GUIc.add( TypeSquare );
GUIc.add( TypeCircle );
GUIc.add( SizeNone );
GUIc.add( SizeLarge );
GUIc.add( SizeSmall );
}
/*
CONFIGURATES THE OBJECTS // nothing really important, replaces the missing database of objects
*/
void configObjects() {
color rot = color( 200, 0, 20 );
color gruen = color( 45, 200, 110 );
color blau = color( 50, 115, 180 );
Objects = new facetedObjects ();
for ( int i=0; i<76; i++ ) {
if ( i%4 == 0 ) {
Objects.addData ( "circle", 8, rot );
Objects.addData ( "square", 12, rot );
Objects.addData ( "square", 8, rot );
Objects.addData ( "square", 8, gruen );
}
else if ( i%6 == 0 ) {
Objects.addData ( "circle", 12, blau );
Objects.addData ( "circle", 12, gruen );
Objects.addData ( "square", 8, blau );
Objects.addData ( "circle", 8, blau );
Objects.addData ( "square", 12, gruen );
}
else {
Objects.addData ( "square", 8, rot );
Objects.addData ( "circle", 8, gruen );
Objects.addData ( "square", 12, blau );
}
}
}
/*
CONFIGURATES THE ARRAYS FOR POSITIONING // just maths
*/
void configPositions() {
Objects.Pos = new float[numberObjects][2];
Objects.nPos = new float[numberObjects][2];
oPos = new float[numberObjects][2];
iPos = new float[numberObjects][2];
float x = -7.5;
int y = -1;
float startX = width/2;
float startY = 0.25*height;
int counting = 1;
float minY = 0.92*height;
// alle objekte durchlaufen
for( int i=0; i<numberObjects; i++ ) {
// zeilen
if( i%15 == 0 ) {
x = -7.5;
y++;
}
// start parameter, ränder
float oX = random ( 0, width );
float oY = random ( minY, height );
oPos[i][0] = oX;
oPos[i][1] = oY;
Objects.Pos[i][0] = oX;
Objects.Pos[i][1] = oY;
Objects.nPos[i][0] = oX;
Objects.nPos[i][1] = oY;
// raster positionen für auswahl
iPos[i][0] = startX + 20*x;
iPos[i][1] = startY + 20*y;
x++;
}
}
/*
GENERATES THE FADER FOR ANIMATING WITH THE LERP-FUNCTION
only if sth should be animated
*/
void generateAnimationFader() {
if(animate) {
fader += (1-fader)*0.2; // easing: adding 20% of the rest till 1
fader = constrain( fader, 0, 1 ); // minimal, maximal
if( fader > 0.999 ) { // solving the problem of percentages of very small rests till 1
animate = false;
fader = 1;
}
}
}
/*
RESETTING PARAMETERS FOR ANIMATION
just resetting...
changing objects modes from 4 to 2 and from 3 to 1
*/
void resetParametersForAnimation() {
fader = 0;
animate = false;
activeIndex = 0;
// setting mode 4 & 3 to 2 & 1
// deactivates some wrong animations ...
for( int i=0; i<numberObjects; i++ ) {
if( Objects.Mode[i] == 4 )
Objects.Mode[i] = 2;
else if ( Objects.Mode[i] == 3 )
Objects.Mode[i] = 1;
}
}
/*
DRAWING OBJECTS
- getting positions
*/
void drawObjects() {
for (int i=0; i<numberObjects; i++) {
// start and end positions of the animation
float startX = Objects.Pos[i][0];
float startY = Objects.Pos[i][1];
float endX = Objects.nPos[i][0];
float endY = Objects.nPos[i][1];
// generating 2 faders
// Fader ... for animation of the position
// aFader ... for alpha- and resizing animation
float Fader = 0;
float aFader = 0;
if ( Objects.Mode[i] == 4 ) { // activate: "get it in the middle, it's important for me"
Fader = fader;
aFader = Fader;
}
else if ( Objects.Mode[i] == 3 ) { // deactivate: "throw it to the border, it's useless"
Fader = fader;
aFader = 1-Fader;
}
else if ( Objects.Mode[i] == 2 ) { // active: "just stay there"
Fader = fader;
aFader = 1;
}
else if ( Objects.Mode[i] == 1 ) { // inactive: "just stay far far away from me"
Fader = 1;
aFader = 0;
}
// animation of position, size and alpha-value
float x = lerp( startX, endX, Fader );
float y = lerp( startY, endY, Fader );
float px = lerp( Objects.Size[i]*0.5, Objects.Size[i], aFader );
float a = lerp( 50, 255, aFader );
// circle or square ?? draw it !!
fill( Objects.Color[i], a );
if( Objects.Type[i] == "circle" )
ellipse( x, y, px, px );
else
rect( x, y, px, px );
}
}
// importing an defining interface library
import interfascia.*;
GUIController GUIc;
IFRadioController RColor, RType, RSize;
IFRadioButton ColorNone, ColorRed, ColorGreen, ColorBlue, TypeNone, TypeSquare, TypeCircle, SizeNone, SizeLarge, SizeSmall;
// special class for the objects
facetedObjects Objects;
// some intern global variables
int numberObjects;
boolean animate = false;
float fader = 0;
float[][] oPos;
float[][] iPos;
int activeIndex = 0;
String key_type = "none";
String key_color = "none";
String key_size = "none";
/*
SETUP
- some general configuration
- more interface configuration
- configuration of objects: in this case it is just done manually (in future this should be replaced by a database or sth)
- configuration of the two arrays for positioning the objects
*/
void setup() {
size ( 800, 600 );
smooth ();
frameRate ( 25 );
noStroke ();
rectMode ( CENTER );
ellipseMode ( CENTER );
configInterface();
configObjects();
numberObjects = Objects.index+1;
configPositions();
}
/*
DRAW
- just cleaning the sketch
- generating the fader for the lerp function ... but only if something should be animated
- draws objects ... considering the modes at this moment
*/
void draw() {
background( 255 );
fill( 0 );
generateAnimationFader();
drawObjects();
}
/*
MOUSE RELEASED
- checks if sth is changed in the interface
- if yes: analyses the situation and defines the positions for animation
if yes: resets animation parameters
if yes: starts animation
*/
void mouseReleased() {
analyseSelection();
}
/*
ANALYSE SELECTION
1. checks which radiobuttons are selected and saves some keywords for later
none = all, rot = red, gruen = green, blau = blue, eckig = square, rund = circle, gross = large, klein = small
2. saves the label-keywords in global variables
3. if anything is selected:
reset animation parameters
analyse all object-modes
calculate all object-positions
start animation
*/
void analyseSelection ( ) {
if (!animate) {
// 1.
String label_color = "";
String label_type = "";
String label_size = "";
if ( ColorNone.isSelected() )
label_color = "none";
else if ( ColorRed.isSelected() )
label_color = "rot";
else if ( ColorGreen.isSelected() )
label_color = "gruen";
else if ( ColorBlue.isSelected() )
label_color = "blau";
if ( TypeNone.isSelected() )
label_type = "none";
else if ( TypeSquare.isSelected() )
label_type = "eckig";
else if ( TypeCircle.isSelected() )
label_type = "rund";
if ( SizeNone.isSelected() )
label_size = "none";
else if ( SizeLarge.isSelected() )
label_size = "gross";
else if ( SizeSmall.isSelected() )
label_size = "klein";
boolean action = false;
// 2.
if( ColorNone.isSelected() || ColorRed.isSelected() || ColorGreen.isSelected() || ColorBlue.isSelected() ) { // aktivieren
key_color = label_color;
}
if( TypeNone.isSelected() || TypeSquare.isSelected() || TypeCircle.isSelected() ) { // aktivieren
key_type = label_type;
}
if( SizeNone.isSelected() || SizeLarge.isSelected() || SizeSmall.isSelected() ) { // aktivieren
key_size = label_size;
}
// 3.
if ( label_color != "" || label_type != "" || label_size != "" ) {
resetParametersForAnimation();
for( int i=0; i<numberObjects; i++ ) {
Objects.analyse( i );
Objects.calcPos( i );
}
animate = true;
}
}
}
Objekte haben mehrere Eigenschaften und können über ein Interface nach festgelegten Facetten ausgewählt/angezeigt/sortiert werden.
Objects have several facets: color, type, size
Using the interface you can choose objects by defining the chosen color (red, green, blue), type (square, circle) or size (large, small). or all of them.
Animation works via lerp-function. Positions are defined with two arrays 4 different modes that an object can have:
1 = inactiv
2 = activ
3 = deactivate
4 = activate