sábado, 28 de novembro de 2015

Trabalho: Parte I

Artista escolhido: Luiz Sacliotto

Obra escolhida: Concreção 9768

Análise geométrica


A obra que escolhi para analisar geometricamente e basear meu trabalho foi a concreção 9768 do artista abstracionista Luiz Sacliotto.



Pela análise geométrica da obra do artista, pode perceber o padrão do distanciamento entre cada um dos quadrados, o qual ocorria sempre a uma distância fixa. Se considerarmos cada cor de preenchimento como pertencente a um quadrado de tamanho diferente, é possível construir um programa que se faça valer destas propriedades. 

Programação

Primeiramente, dividi a obra em quatro partes, para melhor programar seu preenchimento.


Utilizando a função rect do Processing, fiz uma função chamada luizSacliotto que recebe 3 inputs: o tamanho que terão os quadrados menores e as coordenadas "x" e "y" na qual será iniciada a construção da obra. Como o quadrado maior de uma parte tem 4 vezes o tamanho do lado do quadrado menor, uma variável chamada "c" é criada para guardar este valor.

Em seguida, coloquei esta função dentro de um laço que decrementa a cada repetição o valor de "c" em "h", construindo assim quadrados menores. Além disso, a coordenada y tinha seu valor somado em "h" para que o próximo quadrado fosse construído a uma distância que fosse igual ao lado do menor quadrado.


Para o preenchimento de cada quadrado, antes do laço iniciar uso a função fill do Processing para preencher o quadrado maior. Depois disso, faço uma condicional para que a cada repetição par, o quadrado seja preenchido por uma coloração vermelha.


Feito isso, está completa a primeira parte da obra.


 Feito isto, para a segunda parte, precisamos que a coordenada inicial "x" tenha o valor do quadrado maior para que a próxima parte tenha sua formação iniciada ao lado da parte anterior sem sobrepô-la. Além disso, a cada repetição do laço, tanto a coordenada x quanto a y na função rect terão seus valores respectivamente somados e diminuídos por "h", para que os quadrados seguintes sejam feitos na mesma proporção que a parte anterior.

Para o preenchimento, é invertida a ordem que foi feita os preenchimentos da parte anterior.

Tomando este cuidado com todas as partes, temos finalmente a reprodução da obra:


Apropriação

Feita a replicação da obra, resolvi colocar a função dentro de um laço e a cada repetição do laço a totalidade da obra feita anteriormente se tornaria a primeira parte de uma obra ainda maior.


Segue abaixo todo o meu código completo para executar esta última etapa.

void setup(){
  background(255);
  size(1920, 1080);
}

void luizSacliotto(int h, int posX, int posY){
 
 
  int c = h * 4;
 
  fill(0);
  //primeira parte
  for(int i = 0; i<=3 ; i++){
   
     rect(posX, posY, c, c);
     posY += h;
     c = c - h;
     if(i%2==0){
     
       fill(125,0 , 0);
     }else{
       fill(0);
     }
   
  }
 //segunda parte
 c= 4*h;
 posX = c;
 posY = 0;
 fill(125,0,0);
 for(int j = 0; j<=3; j++){
 
    rect(posX, posY, c, c);
    posY +=h;
    posX += h;
    c = c - h;
    if(j%2==0){
      fill(0);
    }else{
      fill(125,0,0);
    }
 }

 //terceira parte
 c = 4*h;
 posX = 0;
 posY = c;

 fill(125,0,0);
 for(int k = 0; k<=3; k++){
    rect(posX, posY, c, c);
   
    c -=h;
    if(k%2==0){
      fill(0);
    }else{
      fill(125, 0, 0);
    }
 }

 //quarta parte
 c= 4*h;
 posX = c;
 posY = c;

 fill(0);
 for(int m = 0; m<=3; m++){
    rect(posX, posY, c, c);
    posX +=h;
    posY +=h;
    c -=h;
    if(m%2==0){
      fill(125,0,0);
    }else{
      fill(0);
    }
 
 }

}

void draw(){
  int localX = 0;
  int localY = 0;
  int tamanho = 40;
 
   
    for(int j=0; j<=4; j++){
     
 
  luizSacliotto(tamanho, localX, localY);
 
  localX += 8*tamanho;
  tamanho+= tamanho;
    }
}



segunda-feira, 23 de novembro de 2015

As facilidades das funções

Na nossa aula do dia 19/11/2015, foi passado para nós a seguinte atividade em sala de aula: fazer uma barra de slider no Processing.

Uma barra de slider é algo que vemos comumente em interfaces que querem dar várias opções em um menu. Por exemplo, para deixarmos o nível do volume de um som num nível agradável, normalmente representamos a intensidade do som reproduzido através de uma barra de slider.

Para este exercício, produzi o código abaixo. Para dar um efeito visual mais interessante, fiz com que o quadrado deste slider se desloque continuamente entre as extremidades:

float x;
float d = 0.01;

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

//função do quadrado menor
void slideBar(float p){ //pega um valor que vai mexer o quadrado
   fill(255);
  rect(25, 20, 550, 100);
  float whatever; //este será o valor que vai ser a coordenada X
  whatever = 25+450*p; //25(distancia da borda da janela) + 450(tamanho do retângulo maior - lado do quadrado) * p(a proporção que vai ser o input da função
  fill(125);
  rect(whatever, 20, 100,100);

}



void draw(){
  background(0);
 

 
  x = x + d;
  if(x >= 1 || x <=0){
    d = -d;
  }
 
  slideBar(x);
 
 
 
}



Como podemos ver no código para facilitar meu trabalho eu resolvi compartimentar grande parte dele dentro de uma função.

Funções são ferramentas importantes na programação, permitindo que certas partes do código sejam compartimentadas em diferentes porções, sendo chamadas apenas quando necessário. Além disso, posso utilizá-los várias vezes dentro do mesmo bloco de código, o que o torna até mesmo mais legível.

Além disso, o código quando é reservado para uma função torna sua alteração mais rápida e fácil. Se eu preciso modificar alguma coisa, basta modificar dentro da função que essa alteração será aplicada em todas as instâncias que ela for chamada.

Em resumo, a utilização de funções dinamiza e facilita a compreensão não apenas do código, mas da lógica da programação empregada na construção do mesmo.





Bolas que se colorem com a seta do mouse

Dentre as atividades que foram passadas para serem feitas em casa e postadas aqui neste blog, foi pedido que fizéssemos um programa no Processing que produzisse em locais aleatórios duas circunferências, também com raios aleatórios.

Quando a seta do mouse passasse sobre elas, estas circunferências devem mudar de cor e quando a seta do mouse sair de cima delas, elas devem deixar de ter essa cor.

Para facilitar meu trabalho, reaproveitei o código de uma outra atividade feita em sala que calcula a distância entre dois pontos, apenas adicionando novas variáveis que tem seu valor gerado randomicamente a cada vez que o programa é aberto e chamando as funções apenas para mudar a cor das circunferências dentro da condição estabelecida (mouse dentro da circunferência). Segue o código explicado através de comentários abaixo.

 float xBola1;
float yBola1;
float xBola2;
float yBola2;
float raio1;
float raio2;

//cálculo da distância entre dois pontos na mesma linha
float distancia1D(float X1, float X2){
  float resposta;
  resposta = X2 - X1;
  return sqrt(pow(resposta, 2));
 
}

//cálculo da distância entre dois pontos em qualquer lugar na tela
float distancia2D(float x1, float y1, float x2, float y2){
 
  float coordenadaX;
  coordenadaX = distancia1D(x2, x1);
  float coordenadaY;
  coordenadaY = distancia1D(y2, y1);
 
  float distancia = round(sqrt(pow(coordenadaX, 2) + pow(coordenadaY, 2)));
  return distancia;
   
 
}

void setup(){
 size(600, 600);
 //determinar de forma aleatória a localização e o raio das circunferências
 xBola1 = round(random(width));
 yBola1 = round(random(height));
 xBola2 = round(random(width));
 yBola2 = round(random(height));

 raio1 = round(random(20, 80));
 raio2 = round(random(20, 80));


}

void draw(){
  background(0);
  //colocamos a condicional para colorir a bola caso o mouse entre nela

 if(distancia2D(mouseX, mouseY, xBola1, yBola1) <= raio1){
     fill(125);
 }
 //fazemos a primeira ellipse dando como parâmetros sua localização e o raio gerado

 ellipse(xBola1, yBola1, raio1*2, raio1*2);
 //ao afastar a seta do mouse, volta a ficar branca
 fill(255);
 //faz o mesmo com a outra circunferencia
  if(distancia2D(mouseX, mouseY, xBola2, yBola2) <=raio2){
    fill(0, 123, 200);
  }
    ellipse(xBola2, yBola2, raio2*2, raio2*2);
    fill(255);
 
 
}


domingo, 22 de novembro de 2015

Exemplo do Processing

Na nossa segunda aula, foi pedido que fosse pegue um dos exemplos presentes no site https://processing.org/examples , analisássemos algum que nos chamasse a atenção e o modificasse para ter algum tipo de efeito diferenciado.

Dentre os exemplos, um dos que mais me chamaram a atenção foi este simples código em que eram criados algumas elipses que seguiam a seta do mouse.


Segue o código desse exemplo abaixo: 

float x = 100;
float y = 100;
float angle1 = 0.0;
float segLength = 50;

void setup() {
  size(640, 360);
  strokeWeight(20.0);
  stroke(255, 100);
}

void draw() {
  background(0);
  
  float dx = mouseX - x;
  float dy = mouseY - y;
  angle1 = atan2(dy, dx);  
  x = mouseX - (cos(angle1) * segLength);
  y = mouseY - (sin(angle1) * segLength);
 
  segment(x, y, angle1); 
  ellipse(x, y, 20, 20);
}

void segment(float x, float y, float a) {
  pushMatrix();
  translate(x, y);
  rotate(a);
  line(0, 0, segLength, 0);
  popMatrix();
}
Para efeitos de exemplo, resolvi fazer com que no lugar das elipses tivessem retângulos e a cor deste objeto fosse mudando dependendo do local que se encontrava o mouse na tela. Para ter o efeito desejado, precisei retirar a função stroke de dentro da função setup e deixá-la na função draw, para que a cor do objeto fosse mudando a cada novo frame.

Segue o código editado abaixo:
float x = 100;
float y = 100;
float angle1 = 0.0;
float segLength = 50;

void setup() {
  size(640, 360);
  strokeWeight(20.0);
  
}

void draw() {
  background(0);
  stroke(mouseX, 100, mouseY);
  float dx = mouseX - x;
  float dy = mouseY - y;
  angle1 = atan2(dy, dx);  
  x = mouseX - (cos(angle1) * segLength);
  y = mouseY - (sin(angle1) * segLength);
 
  segment(x, y, angle1); 
  rect(x, y, 20, 20);
}

void segment(float x, float y, float a) {
  pushMatrix();
  translate(x, y);
  rotate(a);
  line(0, 0, segLength, 0);
  popMatrix();
}

quinta-feira, 19 de novembro de 2015

Bolinha acelerando e se batendo

Dentre as atividades que foram passadas, foi determinado que fosse produzida uma circunferência que se deslocaria tanto horizontalmente quanto verticalmente pela tela e, quando ela encostasse nos cantos da janela, sua velocidade fosse aumentada em 1%.

Segue abaixo o código com os comentários explicando como ele foi produzido.

//determinação dos valores das variáveis

float bolaX = 10;
float bolaY = 15;
float dX = 15;
float dY = 15;
float acelerador = 0.01;
//tamanho da tela
void setup(){
  size(800, 600);
}

void draw(){
  background(0);
  //bola tem sua posição determinada
 ellipse(bolaX, bolaY, 40, 40); 
  //deslocamento da bola
  bolaX = bolaX + dX;
  bolaY = bolaY + dY;
  
  /*a cada vez que a bola encostar numa parede, ela terá uma mudança na sua tranjetória
  e sua velocidade vai ser aumentada em 1% */
  if(bolaX>=790){
    dX =  -(dX +dX*acelerador);
    
  }
  else if(bolaX <10){
     dX = -(dX +dX*acelerador);
       
  }
  else if(bolaY>=590){
    dY = -(dY+dY*acelerador);
  }
  else if(bolaY<10){
    dY = -(dY+dY*acelerador);
  }
  
  
}


Pong!

Na atividade para casa da aula 10, foi pedido que fizéssemos no Processing um jogo parecido com o clássico jogo Pong, o qual foi um dos primeiros a serem desenvolvidos e foi um dos maiores responsáveis tanto da popularização dos arcades e que tornaram possível o nascimento dos videogames.

Segue abaixo o código com comentários explicando cada parte principal dele. Em seguida, um gif demonstrando o jogo funcionando.

Para este jogo, eu reaproveitei o código de uma outra atividade que foi feita anteriormente em sala de aula que consistia em fazer uma bolinha se mover livremente pela tela e quando se chocasse com os limites da janela ela mudaria de direção.

Tive alguns problemas na determinação da colisão com os paddles, mas ainda assim gostei bastante do resultado.

//coordenadas iniciais da bola
int bolaX = 100;
int bolaY = 150;
//modificadores da trajetória da bola
int dX = 5;
int dY = 5;
//coordenadas iniciais do primeiro paddle
int xP1 = 20;
int yP1 = 120;
//coordenadas iniciais do segundo paddle
int xP2 = 280;
int yP2 = 120;
//raio da bolinha
int raio = 20;

void setup(){
  size(320, 240);
}

void draw(){
 background(0);
 mover();
 //aqui é feita a bolinha
 ellipse(bolaX, bolaY, raio*2, raio*2);
 //aqui são feitos os paddles
 rect(xP1, yP1, 20, 80);
 rect(xP2, yP2, 20, 80);


  //nesta parte, temos a determinação do deslocamento da bola de forma costante, sendo um MRU
 
  bolaX = bolaX + dX;
  bolaY = bolaY + dY;
  //mudança da direção da bola ao tocar nas bordas
  if(bolaX>=300){
    dX = -dX;
   
  }
  else if(bolaX <10){
     dX = -dX;
     
  }
  else if(bolaY>=220){
    dY = -dY;
  }
  else if(bolaY<10){
    dY = -dY;
 
  }
  //mudança na direção da bola ao tocar um dos paddles
  if(Colisao(xP1, yP2) || Colisao(xP2, yP2)){
   dX = -dX;
   dY = -dY;
  }
  //finalização do jogo quando a bola toca uma das bordas da janela do jogo
  if(bolaX > (width-raio)){
    gameOver(true);
  }
  else if(bolaX< raio){
    gameOver(false);
  }
 
}
/*função que determina o comportamento da bola quando colidir
com um dos paddles*/
boolean Colisao(int xP, int yP){
  if(bolaY >= yP - raio && bolaY <= yP+ 80+raio){
    if(bolaX >= xP - raio && bolaX <= xP + 20 + raio){
      return true;
    }
    else
      return false;
  }
    else
      return false;
   
 
}

//função que movimenta os paddles
void mover(){
  if(keyPressed){
    if (keyCode == DOWN) {
      yP1+=5;
    }else if(keyCode == UP){
      yP1-=5;
    }else if(keyCode == LEFT){
      yP2+=5;
    }else if(keyCode == RIGHT){
      yP2-=5;
    }
  }
}
//função que termina o jogo, posicionando um texto dizendo qual lado venceu
void gameOver(boolean fimdejogo){
  if (fimdejogo){
    clear();
    text("Esquerda ganhou!", 160, 120);
    noLoop();
  }
  if (!fimdejogo){
    clear();
    text("Direita ganhou",160,120);
    noLoop();
  }
}


A da BRAUN

Foi pedido como atividade da aula 7 que fizéssemos uma reprodução de parte do logo da empresa BRAUN, uma empresa que teve grande influência na história de design de produtos. Para esta atividade, foi pedido apenas que fosse reproduzido a letra "A" do seu logo, além de que ele ficasse aumentando e diminuindo continuamente.

Abaixo, segue o código com a explicação dele como comentários.

//valores bases dados para as variáveis que sofrerão alterações na execução do código
float aDaBraun = 10;
float aumentador = 5;


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

  
}


void draw(){
 background(255);

 //chamada da função com a variável estabelecida anteriormente
 Braun(aDaBraun);
 //adição feita a variável que controla o módulo
 aDaBraun= aDaBraun + aumentador;
 /*aqui, estabeleço que a variável que modifica a variável 
 de módulo tenha seu valor invertido a partir do momento 
 que o módulo passa a ter o tamanho de 50 unidades*/
 if(aDaBraun >=50){
   aumentador = -aumentador;
 }/*aqui, quando o valor passar a ser menor que 10 unidades, o modificador 
 tem seu valor novamente invertido para que o logo volte a aumentar*/
 else if(aDaBraun <=10){
   aumentador = -aumentador;
 }


}
//função que produz o logo
void Braun(float modulo){
 fill(0);
  //estabelecimento da posição inicial
  float posicaoX = 300+modulo; 
  float posicaoY = 150+modulo;
  noStroke();
  //as duas "pernas" do "A"
  rect(posicaoX, posicaoY-modulo, modulo, modulo/2);
  rect(posicaoX-modulo, posicaoY, modulo, modulo*8);
  rect(posicaoX+modulo, posicaoY, modulo, modulo*8);
  //curvatura do "A", feita com duas circunferências
  ellipse(posicaoX, posicaoY, modulo*2, modulo*2);
  ellipse(posicaoX+modulo, posicaoY, modulo*2, modulo*2);
  
  
  fill(255);
  //preenchimento do "A"
  rect(posicaoX, posicaoY, modulo, modulo+modulo/2, PI);
  
  fill(0);
  //parte de baixo do "A"
  rect(posicaoX-modulo, posicaoY+(2.5*modulo), modulo*3, modulo);
  
}