/* Programa    complex03.c  
	Assunto:  	Imagem de uma curva por um polinômnio complexo.
	Programa 	sem erros
	
	Condição: compile com
		gcc -Wall -oprog -lm complex03.c
		
		inclua a biblioteca ambiente.h no mesmo diretório e altere
			linha de inclusão desta biblioteca

   Descrição: Determina a imagem de segmentos de retas paralelas
   	aos eixos pela função exponencial.
   	Procure comentário "enfase"
         

   por Tarcisio Praciano Pereira - 10 lições para aprender C
   Sobral, Novembro de 2002 - na era Lula	- UVA

	Palavras-chave: imagem de curvas por polinômios complexos
	palavras chave: struct, estrutura
   por Tarcisio Praciano Pereira - 10 lições para aprender C
   Sobral,  de 2008	- UeVA    	      		
*/

# include <stdio.h>  	// (1) leitura da biblioteca padrão
# include <stdlib.h>
# include <math.h>
# include "/home/tarcisio/tex/c/ufg/ambiente.h"

			//	(2)	O tipo, número complexo
typedef	struct {
			float a; float b;
			} Complexo;

float		Re(Complexo z);
float		Im(Complexo z);
void		escreve(Complexo z);
Complexo	mais(Complexo z, Complexo w);
Complexo	vezes(Complexo z, Complexo w);
Complexo	P(Complexo z);
Complexo	Q(Complexo z);
Complexo Exp(Complexo z);
Complexo	recebe(Complexo z, Complexo w);
Complexo	faz_complexo(float a, float b);
int	curva_imagem(float inicio, float fim);
void		prepara_gnuplot();



int main(void)
{
	//Complexo	z=faz_complexo(2, 2);
	printf("	=====   Sistema algébrico dos números complexos \n");
	printf("		Imagem de uma curva por um polinômio   \n");	
	curva_imagem(-3, 3); 
	//escreve(z); printf("\n");
	//z = faz_complexo(3.14, 4.45);  // problema
	//escreve(faz_complexo(3.14, 4.45));
	//escreve(z);
	prepara_gnuplot();
	system("gnuplot transfere");
	return 0;
}

// percorre um retângulo com ênfase nas paralelas ao eixo OX (quer dizer
// o salto no eixo OY é grande)
int	curva_imagem(float inicio, float fim)
{
  float x,y;
  float delta = 0.01;
  float delta2 = 0.3;
  Complexo z;
  FILE	*dados;
  dados	= fopen("dados", "w");
  y = inicio;
  while(y <= fim)
  {
		  x = 0;
		  while(x <= fim )
		  {
			 z = faz_complexo(x, y);
			 z = Exp(z); // exp(x+iy)
			 fprintf(dados, "%f  %f\n", Re(z), Im(z));
			 x+=delta; //  y+= delta; ou delta2  // (10)  troque aqui para alterar a ênfase...
		  }
		  y+=delta2; //  ou delta ; //(10) troque aqui para alterar a ênfase...
  }
  fclose(dados);
  return(0);
}


void	prepara_gnuplot()
{
  FILE  *transfere;
  transfere =  fopen("transfere", "w");
  fprintf(transfere, "set title 'Imagem pela exponencial de segmentos de retas paralelas a OY \n");  
  fprintf(transfere, "set pointsize 0.1 \n");
  fprintf(transfere, "set grid  \n");  
  fprintf(transfere, "plot \"dados\" with points, 0 \n");
  fprintf(transfere, "pause -2\n");
  fclose(transfere);
}



Complexo	recebe(Complexo z, Complexo w)
{
	z.a = w.a;
	z.b = w.b;
	return(z);
}

float		Re(Complexo z)
	{
		return z.a;
	}

float		Im(Complexo z)
	{
		return z.b;
	}

Complexo	mais(Complexo z, Complexo w)
{
	Complexo temp;
	temp.a = z.a + w.a;
	temp.b = z.b + w.b;
	return(temp);
}

Complexo vezes(Complexo z, Complexo w)
{
	Complexo temp;
	temp.a = z.a*w.a - z.b*w.b;
	temp.b = z.b*w.a + z.a*w.b;
	return(temp);
}

Complexo	faz_complexo(float a, float b)
{
	Complexo temp;
	temp.a= a; temp.b = b;
	return(temp);
}

void	escreve(Complexo z)
{
	printf(" %2.2f + %2.2f i\n", Re(z),Im(z));
}

//      a0 + z*(a1 + z*( a2 + z*a3))) 
//     mais(a0, vezes(z, mais(a1, vezes(z, mais(a2, vezes(a3,z))))))
Complexo	P(Complexo z)
{
	Complexo a0, a1, a2, a3;
	Complexo temp;
	
	recebe(temp, mais(a0, vezes(z, mais(a1, vezes(z, mais(a2, vezes(a3,z)))))));
	return(temp);
}

Complexo	Q(Complexo z)
{
	Complexo v={1,0};
	recebe(v, faz_complexo(1,0));
	Complexo temp = vezes(z,z);
	temp = vezes(v,temp);
	return(temp);
}

//  exp(z) = exp(x+iy) = exp(x)*exp(iy) = exp(x)( cos(y) + i sin(y) )
Complexo	Exp(Complexo z)
{
	Complexo temp;
	temp.a = exp(z.a)*cos(z.b); // exp(x)cos(y)
	temp.b = exp(z.a)*sin(z.b); // exp(x)sin(y)
	return(temp);
}

/* Comentários:  A numeração dos comentários não
		  é continuada, pode dar saltos...para
		  facilitar a reutilização de programas.

	(2)	O tipo, número complexo. Com "typedef" podemos criar novos tipos 
	de dados. Aqui foi criado o tipo "Complexo" com auxílio de "struct".
	Um número complexo tem dois campos indicados por "a" e por "b".

(10) na função curva_imagem()  a escolha de uma malha mais fina em
    um dos eixos determina a ênfase - quer dizer, se quero a imagem
    de segmentos de reta paralelo ao eixo OX  ou  ao eixo OY 
*/


