Abaixo segue o vídeo do Trabalho 2:
terça-feira, 23 de junho de 2015
Exercício 24: Histograma Dos Canais RGB
O código a seguir apresenta os histogramas dos canais rgb de uma imagem, o sódigo é uma adaptação de um código desenvolvido em aula e as adaptações foram armazenar os dados de todos os canais, calcular o tom de maxima aparição em todos os canais, e claro mostrar efetivamente o histograma de cada canal.
Código-Fonte:
int[] tonsr = new int[256];
int[] tonsg = new int[256];
int[] tonsb = new int[256];
PImage img;
int max=1,maxg=1,maxb=1;
void setup(){
size(1000,600);
background(0);
//float t=0, mediaT,somaT=0;
int pos,t,g,b;
img = loadImage("akito.jpg");
image(img,0,0);
for(int x=0;x<250;x++){
for(int y=0;y<231;y++){
pos=y*250+x;
t=(int)red(img.pixels[pos]);
g=(int)green(img.pixels[pos]);
b=(int)blue(img.pixels[pos]);
tonsr[t] +=1;
tonsg[g] +=1;
tonsb[b] +=1;
}
}
for(int i=0;i<tonsr.length;i++){
println("tom "+i+" = "+tonsr[i]);
}
//mediaT = somaT/(640*480);
max = maxPos(1);
maxg = maxPos(2);
maxb = maxPos(3);
println("Tom "+max+" valor "+tonsr[max]);
criaHist();
/*
float v,SomaV=0;
for(int x=0;x<640;x++){
for(int y=0;y<480;y++){
pos=y*640+x;
t=red(img.pixels[pos]);
v= pow(t-mediaT,2);
SomaV+=v;
}
}
float media = SomaV/(640*480);
println("Média de Tons é ",media);
*/
}
int maxPos(int cor){
int n=0;
int pos2=0;
if(cor == 1){
for(int b=0;b<tonsr.length;b++){
if(tonsr[b]>=n){
n=tonsr[b];
pos2=b;
}
}
}else if(cor == 2){
for(int b=0;b<tonsg.length;b++){
if(tonsg[b]>=n){
n=tonsg[b];
pos2=b;
}
}
}else if(cor == 3){
for(int b=0;b<tonsb.length;b++){
if(tonsb[b]>=n){
n=tonsb[b];
pos2=b;
}
}}
return pos2;
}
void criaHist(){
float x=5;
max = maxPos(1);
for(int i=0;i<tonsr.length;i++){
println("maximor "+tonsr[max]);
fill(220,0,0);
noStroke();
rect(x,height-((tonsr[i]*100)/tonsr[max]),1,height);
x+=1;
}
x+=50;
maxg = maxPos(2);
for(int i=0;i<tonsg.length;i++){
println("maximog "+tonsg[maxg]);
fill(0,220,0);
noStroke();
rect(x,height-((tonsg[i]*100)/tonsg[maxg]),1,height);
x+=1;
}
x+=50;
maxb = maxPos(3);
for(int i=0;i<tonsb.length;i++){
println("tonb"+tonsb[i]+"maximob "+tonsb[maxb]);
fill(0,0,220);
noStroke();
rect(x,height-((tonsb[i]*100)/tonsb[maxb]),1,height);
x+=1;
}
}
void draw(){
//println("X: "+x);
//background(0);
//criaHist();
//image(img,0,0);
}
Código-Fonte:
int[] tonsr = new int[256];
int[] tonsg = new int[256];
int[] tonsb = new int[256];
PImage img;
int max=1,maxg=1,maxb=1;
void setup(){
size(1000,600);
background(0);
//float t=0, mediaT,somaT=0;
int pos,t,g,b;
img = loadImage("akito.jpg");
image(img,0,0);
for(int x=0;x<250;x++){
for(int y=0;y<231;y++){
pos=y*250+x;
t=(int)red(img.pixels[pos]);
g=(int)green(img.pixels[pos]);
b=(int)blue(img.pixels[pos]);
tonsr[t] +=1;
tonsg[g] +=1;
tonsb[b] +=1;
}
}
for(int i=0;i<tonsr.length;i++){
println("tom "+i+" = "+tonsr[i]);
}
//mediaT = somaT/(640*480);
max = maxPos(1);
maxg = maxPos(2);
maxb = maxPos(3);
println("Tom "+max+" valor "+tonsr[max]);
criaHist();
/*
float v,SomaV=0;
for(int x=0;x<640;x++){
for(int y=0;y<480;y++){
pos=y*640+x;
t=red(img.pixels[pos]);
v= pow(t-mediaT,2);
SomaV+=v;
}
}
float media = SomaV/(640*480);
println("Média de Tons é ",media);
*/
}
int maxPos(int cor){
int n=0;
int pos2=0;
if(cor == 1){
for(int b=0;b<tonsr.length;b++){
if(tonsr[b]>=n){
n=tonsr[b];
pos2=b;
}
}
}else if(cor == 2){
for(int b=0;b<tonsg.length;b++){
if(tonsg[b]>=n){
n=tonsg[b];
pos2=b;
}
}
}else if(cor == 3){
for(int b=0;b<tonsb.length;b++){
if(tonsb[b]>=n){
n=tonsb[b];
pos2=b;
}
}}
return pos2;
}
void criaHist(){
float x=5;
max = maxPos(1);
for(int i=0;i<tonsr.length;i++){
println("maximor "+tonsr[max]);
fill(220,0,0);
noStroke();
rect(x,height-((tonsr[i]*100)/tonsr[max]),1,height);
x+=1;
}
x+=50;
maxg = maxPos(2);
for(int i=0;i<tonsg.length;i++){
println("maximog "+tonsg[maxg]);
fill(0,220,0);
noStroke();
rect(x,height-((tonsg[i]*100)/tonsg[maxg]),1,height);
x+=1;
}
x+=50;
maxb = maxPos(3);
for(int i=0;i<tonsb.length;i++){
println("tonb"+tonsb[i]+"maximob "+tonsb[maxb]);
fill(0,0,220);
noStroke();
rect(x,height-((tonsb[i]*100)/tonsb[maxb]),1,height);
x+=1;
}
}
void draw(){
//println("X: "+x);
//background(0);
//criaHist();
//image(img,0,0);
}
Exercício 23: Jogo da vida - Parte III
O código a seguir é mais uma modificação do jogo da vida, aqui adicionamos um código que calcula a média de células vivas em todas as gerações, e calcula o desvio padrão.
O desvio padrão é calculado seguindo a formula sqrt((pow(x[0]-media,2) + pow(x[1]-media,2) + ...)/x.length-1);
Código-Fonte:
float vendaAn;
int NumeroGeracao=1;
int[] escheme = {};
int[] Mundoatual = {0,1,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,0,1,0,1};
int[] MundoNovo = new int[32];
void setup(){
size(1280,720);
frameRate(1);
background(0);
//Mostramundo();
}
int CruzaCelulas(int Posicao){
int NumeroCelulas = Mundoatual[Posicao-1] + Mundoatual[Posicao] + Mundoatual[Posicao+1];
return NumeroCelulas;
}
void Mostramundo(){
for(int i=0;i<Mundoatual.length;i++){
if(Mundoatual[i]==1){
ellipse(i*20,NumeroGeracao *30,20,20);
}
}
}
void estatisticas(){
int aux=0;
println(escheme.length);
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<Mundoatual.length;cont++){
aux += Mundoatual[cont];
}
escheme = append(escheme,aux);
}else{
float media=0;
float desvio=0;
float max=0;
for(int cont=0;cont<escheme.length;cont++){
stroke(255);
//point((cont+1)*150-6,(height - escheme[cont]*50-6));
if(cont<escheme.length-1){
if(escheme[cont]>=max){max=escheme[cont];}
media += float(escheme[cont]);
}else{
media = media/escheme.length;
for(int i=0;i<escheme.length;i++){
desvio += pow((escheme[i]-media),2);
}
desvio = sqrt(desvio/escheme.length-1);
println("media de células vivas: "+media);
println("desvio padrão de células vivas: "+desvio);
}
}
}
/*
for(int cont=0;cont<escheme.length;cont++){
println((cont+1)+"ª Geração: "+escheme[cont]);
if(escheme[cont]==0){
noLoop();
}
}
*/
}
void draw(){
int NumeroCelulas = 0;
// Mostramundo();
// if(escheme.length>0 && escheme[escheme.length-1]>0){
estatisticas();
//}
//println("Tamanho atual: "+Mundoatual.length);
for(int o=1;o<Mundoatual.length-1;o++){
NumeroCelulas = CruzaCelulas(o);
if(NumeroCelulas==2){
MundoNovo[o]=1;
}else{
MundoNovo[o]=0;
}
}
arrayCopy(MundoNovo,Mundoatual,32);
NumeroGeracao++;
}
O desvio padrão é calculado seguindo a formula sqrt((pow(x[0]-media,2) + pow(x[1]-media,2) + ...)/x.length-1);
Código-Fonte:
float vendaAn;
int NumeroGeracao=1;
int[] escheme = {};
int[] Mundoatual = {0,1,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,0,1,0,1};
int[] MundoNovo = new int[32];
void setup(){
size(1280,720);
frameRate(1);
background(0);
//Mostramundo();
}
int CruzaCelulas(int Posicao){
int NumeroCelulas = Mundoatual[Posicao-1] + Mundoatual[Posicao] + Mundoatual[Posicao+1];
return NumeroCelulas;
}
void Mostramundo(){
for(int i=0;i<Mundoatual.length;i++){
if(Mundoatual[i]==1){
ellipse(i*20,NumeroGeracao *30,20,20);
}
}
}
void estatisticas(){
int aux=0;
println(escheme.length);
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<Mundoatual.length;cont++){
aux += Mundoatual[cont];
}
escheme = append(escheme,aux);
}else{
float media=0;
float desvio=0;
float max=0;
for(int cont=0;cont<escheme.length;cont++){
stroke(255);
//point((cont+1)*150-6,(height - escheme[cont]*50-6));
if(cont<escheme.length-1){
if(escheme[cont]>=max){max=escheme[cont];}
media += float(escheme[cont]);
}else{
media = media/escheme.length;
for(int i=0;i<escheme.length;i++){
desvio += pow((escheme[i]-media),2);
}
desvio = sqrt(desvio/escheme.length-1);
println("media de células vivas: "+media);
println("desvio padrão de células vivas: "+desvio);
}
}
}
/*
for(int cont=0;cont<escheme.length;cont++){
println((cont+1)+"ª Geração: "+escheme[cont]);
if(escheme[cont]==0){
noLoop();
}
}
*/
}
void draw(){
int NumeroCelulas = 0;
// Mostramundo();
// if(escheme.length>0 && escheme[escheme.length-1]>0){
estatisticas();
//}
//println("Tamanho atual: "+Mundoatual.length);
for(int o=1;o<Mundoatual.length-1;o++){
NumeroCelulas = CruzaCelulas(o);
if(NumeroCelulas==2){
MundoNovo[o]=1;
}else{
MundoNovo[o]=0;
}
}
arrayCopy(MundoNovo,Mundoatual,32);
NumeroGeracao++;
}
segunda-feira, 15 de junho de 2015
Exercício 21: Jogo da Vida - Parte II
Esse exercício é um aprimoramento do exercício anterior, mostrando outros gráficos representando agora o numero de nascimentos e mortes das gerações.
O gráfico em pizza mostra a porcentagem de mortes e nascimentos da geração corrente, usando apenas uma pequena relação que resulta em um ângulo que e usado para desenhar a "fatia" correspondente.
O gráfico de barras é apenas uma adaptação do gráfico de linhas, a adaptação feita no código anterior foi salvar as motes de cada geração.
Código-Fonte:
float vendaAn;
int NumeroGeracao=1;
int[] escheme = {
};
int[] escheme2 = {
};
int[] Mundoatual = {
0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1
};
int[] MundoNovo = new int[32];
void setup() {
size(1280, 720);
frameRate(1);
background(0);
//Mostramundo();
}
int CruzaCelulas(int Posicao) {
int NumeroCelulas = Mundoatual[Posicao-1] + Mundoatual[Posicao] + Mundoatual[Posicao+1];
return NumeroCelulas;
}
void Mostramundo() {
for (int i=0; i<Mundoatual.length; i++) {
if (Mundoatual[i]==1) {
ellipse(i*20, NumeroGeracao *30, 20, 20);
}
}
}
void estatisticas() {
int aux=0;
int aux2=0;
println(escheme.length);
// if(escheme.length==0 || escheme[escheme.length-1]!=0){
for (int cont=0; cont<Mundoatual.length; cont++) {
aux += Mundoatual[cont];
if (Mundoatual[cont]==0) {
aux2++;
//} else {
// aux++;
}
}
//escheme = append(escheme,aux);
//escheme2 = append(escheme2,aux2);
// }else{
//ellipse(width/2, height/2, 40, 40);
println((aux2*360)/32);
//fill(0,0,255);
//arc(width/2,height/2,80,80, radians((aux2*360)/32), radians((aux*360)/32));
background(0);
fill(50,50,220);
rect(50,50,10,10); text("Nascimentos",65,60);
text("Nascimentos: "+(aux*100)/32+"%",50,95);
arc(width/2,height/2,160,160, radians((aux2*360)/32), radians(360));
fill(220,50,50);
rect(50,65,10,10); text("Mortes",65,75);
text("Mortes: "+(aux2*100)/32+"%",50,110);
arc(width/2,height/2,160,160, 0, radians((aux2*360)/32));
// }
//Grafico em barras
/*
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<Mundoatual.length;cont++){
aux += Mundoatual[cont];
if(Mundoatual[cont]==0){
aux2++;
}
}
escheme = append(escheme,aux);
escheme2 = append(escheme2,aux2);
}else{
text("Nascimentos:",50,50);
for(int cont=0;cont<escheme.length;cont++){
stroke(255);
if(cont<escheme.length-1){
text(escheme[cont],(cont+1)*50-6,(height - escheme[cont]*10-6));
rect((cont+1)*50-6,(height - escheme[cont]*10-6),20,height-(height - escheme[cont]*10-6));
//line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
}else{
text(escheme[cont],(cont+1)*50-6,(height - escheme[cont]*10-6));
}
}
line(width/2,0,width/2,height);
text("Mortes:",width/2+50,50);
for(int cont=0;cont<escheme2.length;cont++){
stroke(255);
// if(cont<escheme2.length-1){
text(escheme2[cont],width/2+(cont+1)*50-6,(height - escheme2[cont]*10-6));
rect(width/2+(cont+1)*50-6,(height - escheme2[cont]*10-6),20,height-(height - escheme2[cont]*10-6));
//line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
// }else{
// text(escheme2[cont],width/2+(cont+1)*50-6,(height - escheme2[cont]*10-6));
// }
}
}
*/
//Grafico em linhas
/*
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<escheme.length;cont++){
stroke(255)
point((cont+1)*150-6,(height - escheme[cont]*50-6));
if(cont<escheme.length-1){
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
}else{
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
}
}
*/
/*
for(int cont=0;cont<escheme.length;cont++){
println((cont+1)+"ª Geração: "+escheme[cont]);
if(escheme[cont]==0){
noLoop();
}
}
*/
}
void draw() {
int NumeroCelulas = 0;
// Mostramundo();
estatisticas();
//println("Tamanho atual: "+Mundoatual.length);
for (int o=1; o<Mundoatual.length-1; o++) {
NumeroCelulas = CruzaCelulas(o);
if (NumeroCelulas==2) {
MundoNovo[o]=1;
} else {
MundoNovo[o]=0;
}
}
arrayCopy(MundoNovo, Mundoatual, 32);
NumeroGeracao++;
}
O gráfico em pizza mostra a porcentagem de mortes e nascimentos da geração corrente, usando apenas uma pequena relação que resulta em um ângulo que e usado para desenhar a "fatia" correspondente.
O gráfico de barras é apenas uma adaptação do gráfico de linhas, a adaptação feita no código anterior foi salvar as motes de cada geração.
Código-Fonte:
float vendaAn;
int NumeroGeracao=1;
int[] escheme = {
};
int[] escheme2 = {
};
int[] Mundoatual = {
0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1
};
int[] MundoNovo = new int[32];
void setup() {
size(1280, 720);
frameRate(1);
background(0);
//Mostramundo();
}
int CruzaCelulas(int Posicao) {
int NumeroCelulas = Mundoatual[Posicao-1] + Mundoatual[Posicao] + Mundoatual[Posicao+1];
return NumeroCelulas;
}
void Mostramundo() {
for (int i=0; i<Mundoatual.length; i++) {
if (Mundoatual[i]==1) {
ellipse(i*20, NumeroGeracao *30, 20, 20);
}
}
}
void estatisticas() {
int aux=0;
int aux2=0;
println(escheme.length);
// if(escheme.length==0 || escheme[escheme.length-1]!=0){
for (int cont=0; cont<Mundoatual.length; cont++) {
aux += Mundoatual[cont];
if (Mundoatual[cont]==0) {
aux2++;
//} else {
// aux++;
}
}
//escheme = append(escheme,aux);
//escheme2 = append(escheme2,aux2);
// }else{
//ellipse(width/2, height/2, 40, 40);
println((aux2*360)/32);
//fill(0,0,255);
//arc(width/2,height/2,80,80, radians((aux2*360)/32), radians((aux*360)/32));
background(0);
fill(50,50,220);
rect(50,50,10,10); text("Nascimentos",65,60);
text("Nascimentos: "+(aux*100)/32+"%",50,95);
arc(width/2,height/2,160,160, radians((aux2*360)/32), radians(360));
fill(220,50,50);
rect(50,65,10,10); text("Mortes",65,75);
text("Mortes: "+(aux2*100)/32+"%",50,110);
arc(width/2,height/2,160,160, 0, radians((aux2*360)/32));
// }
//Grafico em barras
/*
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<Mundoatual.length;cont++){
aux += Mundoatual[cont];
if(Mundoatual[cont]==0){
aux2++;
}
}
escheme = append(escheme,aux);
escheme2 = append(escheme2,aux2);
}else{
text("Nascimentos:",50,50);
for(int cont=0;cont<escheme.length;cont++){
stroke(255);
if(cont<escheme.length-1){
text(escheme[cont],(cont+1)*50-6,(height - escheme[cont]*10-6));
rect((cont+1)*50-6,(height - escheme[cont]*10-6),20,height-(height - escheme[cont]*10-6));
//line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
}else{
text(escheme[cont],(cont+1)*50-6,(height - escheme[cont]*10-6));
}
}
line(width/2,0,width/2,height);
text("Mortes:",width/2+50,50);
for(int cont=0;cont<escheme2.length;cont++){
stroke(255);
// if(cont<escheme2.length-1){
text(escheme2[cont],width/2+(cont+1)*50-6,(height - escheme2[cont]*10-6));
rect(width/2+(cont+1)*50-6,(height - escheme2[cont]*10-6),20,height-(height - escheme2[cont]*10-6));
//line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
// }else{
// text(escheme2[cont],width/2+(cont+1)*50-6,(height - escheme2[cont]*10-6));
// }
}
}
*/
//Grafico em linhas
/*
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<escheme.length;cont++){
stroke(255)
point((cont+1)*150-6,(height - escheme[cont]*50-6));
if(cont<escheme.length-1){
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
}else{
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
}
}
*/
/*
for(int cont=0;cont<escheme.length;cont++){
println((cont+1)+"ª Geração: "+escheme[cont]);
if(escheme[cont]==0){
noLoop();
}
}
*/
}
void draw() {
int NumeroCelulas = 0;
// Mostramundo();
estatisticas();
//println("Tamanho atual: "+Mundoatual.length);
for (int o=1; o<Mundoatual.length-1; o++) {
NumeroCelulas = CruzaCelulas(o);
if (NumeroCelulas==2) {
MundoNovo[o]=1;
} else {
MundoNovo[o]=0;
}
}
arrayCopy(MundoNovo, Mundoatual, 32);
NumeroGeracao++;
}
domingo, 14 de junho de 2015
Exercício 20: Jogo da Vida
O código a seguir, implementa uma versão simplificada do algoritmo Jogo da Vida, a implementação original requeria matrizes e uma varredura na área ao redor de cada célula. Essa implementação mostra um vetor de células ao invés de uma matriz, em condições normal essa "linha" de células só iria ser atualizada, mas nesse caso, cada geração é mostrada, para que a diferença seja notada com mais facilidade.
O código do jogo da vida fora desenvolvido em sala, e foi somente adaptado para processar 32 valores, ao invés dos originais 8 valores; como pedido na atividade, se faz necessário guardar o numero de células em cada geração e gerar um gráfico de linhas baseado em tais valores (o código do gráfico de linhas foi reutilizado de uma aula anterior), a função Mostramundo (responsável por mostra a representação gráfica de cada geração) deixa de ser chamada, um novo vetor de inteiros vazio é criado para armazenar o numero de células das gerações, a função responsável por fazer isso acontecer será explanada abaixo.
A função estatisticas é criada para atribuir o numero de células vivas, um pequeno teste é feito para evitar redundâncias, quando o número de células vivas for igual a zero esse valor é atribuído ao próximo índice do vetor, no entanto o laço de repetição que atribui esses valores não é mais executado, pois dali em diante todos os valores serão zero, sendo o fim. Se a condição para executar o laço não for satisfeita significa que todos os valores já foram salvos, então o gráfico é desenhado na tela, junto com os valores que cada vértice representa.
Código-Fonte:
float vendaAn;
int NumeroGeracao=1;
int[] escheme = {};
int[] Mundoatual = {0,1,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,0,1,0,1};
int[] MundoNovo = new int[32];
void setup(){
size(1280,720);
frameRate(60);
background(0);
}
int CruzaCelulas(int Posicao){
int NumeroCelulas = Mundoatual[Posicao-1] + Mundoatual[Posicao] + Mundoatual[Posicao+1];
return NumeroCelulas;
}
void Mostramundo(){
for(int i=0;i<Mundoatual.length;i++){
if(Mundoatual[i]==1){
ellipse(i*20,NumeroGeracao *30,20,20);
}
}
}
void estatisticas(){
int aux=0;
println(escheme.length);
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<Mundoatual.length;cont++){
aux += Mundoatual[cont];
}
escheme = append(escheme,aux);
}else{
for(int cont=0;cont<escheme.length;cont++){
stroke(255);
point((cont+1)*150-6,(height - escheme[cont]*50-6));
if(cont<escheme.length-1){
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
}else{
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
}
}
}
}
void draw(){
int NumeroCelulas = 0;
// Mostramundo();
estatisticas();
//println("Tamanho atual: "+Mundoatual.length);
for(int o=1;o<Mundoatual.length-1;o++){
NumeroCelulas = CruzaCelulas(o);
if(NumeroCelulas==2){
MundoNovo[o]=1;
}else{
MundoNovo[o]=0;
}
}
arrayCopy(MundoNovo,Mundoatual,32);
NumeroGeracao++;
}
O código do jogo da vida fora desenvolvido em sala, e foi somente adaptado para processar 32 valores, ao invés dos originais 8 valores; como pedido na atividade, se faz necessário guardar o numero de células em cada geração e gerar um gráfico de linhas baseado em tais valores (o código do gráfico de linhas foi reutilizado de uma aula anterior), a função Mostramundo (responsável por mostra a representação gráfica de cada geração) deixa de ser chamada, um novo vetor de inteiros vazio é criado para armazenar o numero de células das gerações, a função responsável por fazer isso acontecer será explanada abaixo.
A função estatisticas é criada para atribuir o numero de células vivas, um pequeno teste é feito para evitar redundâncias, quando o número de células vivas for igual a zero esse valor é atribuído ao próximo índice do vetor, no entanto o laço de repetição que atribui esses valores não é mais executado, pois dali em diante todos os valores serão zero, sendo o fim. Se a condição para executar o laço não for satisfeita significa que todos os valores já foram salvos, então o gráfico é desenhado na tela, junto com os valores que cada vértice representa.
Código-Fonte:
float vendaAn;
int NumeroGeracao=1;
int[] escheme = {};
int[] Mundoatual = {0,1,1,0,1,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,0,1,0,1};
int[] MundoNovo = new int[32];
void setup(){
size(1280,720);
frameRate(60);
background(0);
}
int CruzaCelulas(int Posicao){
int NumeroCelulas = Mundoatual[Posicao-1] + Mundoatual[Posicao] + Mundoatual[Posicao+1];
return NumeroCelulas;
}
void Mostramundo(){
for(int i=0;i<Mundoatual.length;i++){
if(Mundoatual[i]==1){
ellipse(i*20,NumeroGeracao *30,20,20);
}
}
}
void estatisticas(){
int aux=0;
println(escheme.length);
if(escheme.length==0 || escheme[escheme.length-1]!=0){
for(int cont=0;cont<Mundoatual.length;cont++){
aux += Mundoatual[cont];
}
escheme = append(escheme,aux);
}else{
for(int cont=0;cont<escheme.length;cont++){
stroke(255);
point((cont+1)*150-6,(height - escheme[cont]*50-6));
if(cont<escheme.length-1){
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
line((cont+1)*150-6,(height - escheme[cont]*50-6),(cont+2)*150-6,(height - escheme[cont+1]*50-6));
}else{
text(escheme[cont],(cont+1)*150-6,(height - escheme[cont]*50-6));
}
}
}
}
void draw(){
int NumeroCelulas = 0;
// Mostramundo();
estatisticas();
//println("Tamanho atual: "+Mundoatual.length);
for(int o=1;o<Mundoatual.length-1;o++){
NumeroCelulas = CruzaCelulas(o);
if(NumeroCelulas==2){
MundoNovo[o]=1;
}else{
MundoNovo[o]=0;
}
}
arrayCopy(MundoNovo,Mundoatual,32);
NumeroGeracao++;
}
Exercício 19: Chroma Key e Teoria dos Conjuntos
Nesse post, será explanado a relação entre o efeito Chroma Key e a teoria matemática dos Conjuntos.
Considerando que cada uma das imagens formem o seu conjunto, podemos considerar a parte azul ou verde (como na imagem abaixo), como equivalente ao conjunto vazio (ø), e o a pessoa como os valores de posições onde há valor, então o processo de chroma key é análogo à adição de conjuntos, os valores presentes em um não são repetidos, sendo assim nas posições onde esta a pessoa existe valor, então este não é sobreposto pelo valor da mesma posição do outro "conjunto", e nas posições vazias, os valores do segundo conjunto os preenchem, tendo como resultado a terceira imagem abaixo(Resultado).
Considerando que cada uma das imagens formem o seu conjunto, podemos considerar a parte azul ou verde (como na imagem abaixo), como equivalente ao conjunto vazio (ø), e o a pessoa como os valores de posições onde há valor, então o processo de chroma key é análogo à adição de conjuntos, os valores presentes em um não são repetidos, sendo assim nas posições onde esta a pessoa existe valor, então este não é sobreposto pelo valor da mesma posição do outro "conjunto", e nas posições vazias, os valores do segundo conjunto os preenchem, tendo como resultado a terceira imagem abaixo(Resultado).
Imagem com fundo verde.
Imagem de fundo.
Resultado
terça-feira, 2 de junho de 2015
Exercício 18: CrossFade Entre 3 Imagens
O código a seguir realiza o crossfade entre 3 imagens, o código de crossfade desenvolvida em aula é reutilizado, uma adaptação é feita para que a variável que controla o crossfade é controlada pelo movimento do mouse, enquanto o mouse esta na primeira metade da tela vertical da tela, o programa realiza o crossfade entre a imagem 1 e 2, na segunda metade este faz o crossfade entre as imagens 2 e 3, e vice e versa.
Código-Fonte:
PImage imgOriginal;
PImage img2;
PImage img3;
float a,a2,r,g,b;
int pos;
void setup(){
a=1;
a2=1;
mouseY=1;
size(320,240);
imgOriginal = loadImage("opa.jpg");
img2 = loadImage("trololo.jpg");
img3 = loadImage("yopa.JPG");
}
void draw(){
loadPixels();
//a = a - 0.001;
if(mouseY<height/2){
a=float(mouseY)/float(height/2);
println(float(mouseY)/float(height/2));
}else{
a2=float(mouseY-height/2)/float(height/2);
println(float(mouseY-height/2)/float(height/2));
}
for(int x=0;x<320;x++){
for(int y=0;y<240;y++){
if(a>=0 && mouseY<width/2){
pos=y*320+x;
r = (1-a) * red(imgOriginal.pixels[pos]) + a * red(img2.pixels[pos]);
g = (1-a) * green(imgOriginal.pixels[pos]) + a * green(img2.pixels[pos]);
b = (1-a) * blue(imgOriginal.pixels[pos]) + a * blue(img2.pixels[pos]);
pixels[pos] = color(r,g,b);
}else if(a2>=0 && mouseY>height/2){
pos=y*320+x;
r = (1-a2) * red(img2.pixels[pos]) + a2 * red(img3.pixels[pos]);
g = (1-a2) * green(img2.pixels[pos]) + a2 * green(img3.pixels[pos]);
b = (1-a2) * blue(img2.pixels[pos]) + a2 * blue(img3.pixels[pos]);
pixels[pos] = color(r,g,b);
}
}
}
updatePixels();
}
Código-Fonte:
PImage imgOriginal;
PImage img2;
PImage img3;
float a,a2,r,g,b;
int pos;
void setup(){
a=1;
a2=1;
mouseY=1;
size(320,240);
imgOriginal = loadImage("opa.jpg");
img2 = loadImage("trololo.jpg");
img3 = loadImage("yopa.JPG");
}
void draw(){
loadPixels();
//a = a - 0.001;
if(mouseY<height/2){
a=float(mouseY)/float(height/2);
println(float(mouseY)/float(height/2));
}else{
a2=float(mouseY-height/2)/float(height/2);
println(float(mouseY-height/2)/float(height/2));
}
for(int x=0;x<320;x++){
for(int y=0;y<240;y++){
if(a>=0 && mouseY<width/2){
pos=y*320+x;
r = (1-a) * red(imgOriginal.pixels[pos]) + a * red(img2.pixels[pos]);
g = (1-a) * green(imgOriginal.pixels[pos]) + a * green(img2.pixels[pos]);
b = (1-a) * blue(imgOriginal.pixels[pos]) + a * blue(img2.pixels[pos]);
pixels[pos] = color(r,g,b);
}else if(a2>=0 && mouseY>height/2){
pos=y*320+x;
r = (1-a2) * red(img2.pixels[pos]) + a2 * red(img3.pixels[pos]);
g = (1-a2) * green(img2.pixels[pos]) + a2 * green(img3.pixels[pos]);
b = (1-a2) * blue(img2.pixels[pos]) + a2 * blue(img3.pixels[pos]);
pixels[pos] = color(r,g,b);
}
}
}
updatePixels();
}
segunda-feira, 1 de junho de 2015
Exercício 17: Photocheap Filtros
O código a seguir, cria filtros para uma imagem para dar um ar de imagem envelhecida, o primeiro cria ruídos na imagem, o segundo deixa a imagem em tons de cinza, o terceiro deixa a imagem avermelhada, e o ultimo deixa a imagem amarelada, a seguir sera explicado como cada filtro atua.
Ruido: A variável pos guarda o numero de pixels da imagem original que foi copiada, um numero randômico de inteiro de 0 até pos-1 é gerado para indicar um pixel da imagem, e nesse pixel é adicionado 16 a cada canal, esse numero pode ser ajustado. o numero de passos para o laços pode ser controlado, aumentando ou diminuído o numero de pixel a serem alterados, no exemplo o numero de passos é 100000.
Cinza: Baseado na percepção das cores pelo ser humano cada cor da image, é multiplicado por um valor que representa a porcentagem de percepção que o ser humano tem daquela cor, depois uma variável media soma todos os canais já multiplicados, tendo assim a média ponderada das cores, e em todos os canais da imagem resultante a variável media é setada, resultando na imagem em tons de cinza.
Vermelho: O filtro a seguir copia as cores G e B para a imagem resultante, e adiciona 64 ao canal R e copia para imagem resultante.,
Amarelo: Esse filtro é bem parecido com o ultimo, só que para adicionar amarelo, é necessário adicionar valor nos canais vermelho e verde.
Código-Fonte:
PImage img;
PImage imgRuido;
PImage imgCinza;
PImage imgRed;
PImage imgYellow;
float media,r,b,g;
int pos;
void setup(){
size(800,600);
img = loadImage("opa.jpg");
imgRuido = createImage(640,447,RGB);
imgCinza = createImage(640,447,RGB);
imgRed = createImage(640,447,RGB);
imgYellow = createImage(640,447,RGB);
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
imgRuido.pixels[pos] = img.pixels[pos];
imgRed.pixels[pos] = img.pixels[pos];
}
}
//Ruido
int p =0;
for (int i=0; i<100000; i++) {
p = (int)random(0,pos-1);
r=red(imgRuido.pixels[p])+16;
g=green(imgRuido.pixels[p])+16;
b=blue(imgRuido.pixels[p])+16;
imgRuido.pixels[p] = color(r,g,b);
imgCinza.pixels[p] = color(r,g,b);
}
//Cinza
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
r=red(imgRuido.pixels[pos])*0.3;
g=green(imgRuido.pixels[pos])*0.59;
b=blue(imgRuido.pixels[pos])*0.11;
media = r+g+b;
imgCinza.pixels[pos] = color(media,media,media);
}
}
//Vermelho
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
r=red(imgCinza.pixels[pos])+64;
g=green(imgCinza.pixels[pos]);
b=blue(imgCinza.pixels[pos]);
imgRed.pixels[pos] = color(r,g,b);
}
}
//Amarelo
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
r=red(imgRed.pixels[pos])+64;
g=green(imgRed.pixels[pos])+64;
b=blue(imgRed.pixels[pos]);
imgYellow.pixels[pos] = color(r,g,b);
}
}
}
void draw() {
//image(img,0,0);
//image(imgRuido,0,0);
//image(imgCinza,0,0);
//image(imgRed, 0, 0);
image(imgYellow,0,0);
}
Ruido: A variável pos guarda o numero de pixels da imagem original que foi copiada, um numero randômico de inteiro de 0 até pos-1 é gerado para indicar um pixel da imagem, e nesse pixel é adicionado 16 a cada canal, esse numero pode ser ajustado. o numero de passos para o laços pode ser controlado, aumentando ou diminuído o numero de pixel a serem alterados, no exemplo o numero de passos é 100000.
Cinza: Baseado na percepção das cores pelo ser humano cada cor da image, é multiplicado por um valor que representa a porcentagem de percepção que o ser humano tem daquela cor, depois uma variável media soma todos os canais já multiplicados, tendo assim a média ponderada das cores, e em todos os canais da imagem resultante a variável media é setada, resultando na imagem em tons de cinza.
Vermelho: O filtro a seguir copia as cores G e B para a imagem resultante, e adiciona 64 ao canal R e copia para imagem resultante.,
Amarelo: Esse filtro é bem parecido com o ultimo, só que para adicionar amarelo, é necessário adicionar valor nos canais vermelho e verde.
Código-Fonte:
PImage img;
PImage imgRuido;
PImage imgCinza;
PImage imgRed;
PImage imgYellow;
float media,r,b,g;
int pos;
void setup(){
size(800,600);
img = loadImage("opa.jpg");
imgRuido = createImage(640,447,RGB);
imgCinza = createImage(640,447,RGB);
imgRed = createImage(640,447,RGB);
imgYellow = createImage(640,447,RGB);
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
imgRuido.pixels[pos] = img.pixels[pos];
imgRed.pixels[pos] = img.pixels[pos];
}
}
//Ruido
int p =0;
for (int i=0; i<100000; i++) {
p = (int)random(0,pos-1);
r=red(imgRuido.pixels[p])+16;
g=green(imgRuido.pixels[p])+16;
b=blue(imgRuido.pixels[p])+16;
imgRuido.pixels[p] = color(r,g,b);
imgCinza.pixels[p] = color(r,g,b);
}
//Cinza
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
r=red(imgRuido.pixels[pos])*0.3;
g=green(imgRuido.pixels[pos])*0.59;
b=blue(imgRuido.pixels[pos])*0.11;
media = r+g+b;
imgCinza.pixels[pos] = color(media,media,media);
}
}
//Vermelho
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
r=red(imgCinza.pixels[pos])+64;
g=green(imgCinza.pixels[pos]);
b=blue(imgCinza.pixels[pos]);
imgRed.pixels[pos] = color(r,g,b);
}
}
//Amarelo
for (int x=0; x<640; x++) {
for (int y=0; y<447; y++) {
pos=y*640+x;
r=red(imgRed.pixels[pos])+64;
g=green(imgRed.pixels[pos])+64;
b=blue(imgRed.pixels[pos]);
imgYellow.pixels[pos] = color(r,g,b);
}
}
}
void draw() {
//image(img,0,0);
//image(imgRuido,0,0);
//image(imgCinza,0,0);
//image(imgRed, 0, 0);
image(imgYellow,0,0);
}
Assinar:
Postagens (Atom)