/* Programa    complex02.c  
	Assunto:  	Imagem de uma curva por um polinômnio complexo.
	Programa 	sem erros

   Descrição: Determina a imagem de um círculo por um polinômio
   			complexo.
         

   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(0, 2*3.1415);
	//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;
}


int	curva_imagem(float inicio, float fim)
{
  float rho=2, teta;
  float delta = 0.01;
  Complexo z;
  FILE	*dados;
  dados	= fopen("dados", "w");
  while(rho > 0)
  {
  	teta = inicio;
  	while(teta <= fim)
  	{
    z = faz_complexo(rho*cos(teta), rho*sin(teta));
    z = Exp(z);
    fprintf(dados, "%f  %f\n", Re(z), Im(z));
    teta += delta; 
   }
   rho -= 10*delta;
  }
  fclose(dados);
  return(0);
}


void	prepara_gnuplot()
{
  FILE  *transfere;
  transfere =  fopen("transfere", "w");
  fprintf(transfere, "set pointsize 0.1 \n");
  fprintf(transfere, "plot \"dados\" with points \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".
*/


