Pretende-se desenvolver um programa que, dado um número variável de circunferências, calcula o número total de intersecções entre estas.

1. Desenvolva um módulo ponto, constituído pelos ficheiros de código ponto.c e de declarações ponto.h, que implementem as seguintes funções:

a) Define um tipo de dados Ponto, constituído por uma estrutura com duas coordenadas reais, x e y;


b) Escreva funções com os seguintes protótipos:

i) Ponto criaPonto(float x, float y); -  recebe duas coordenadas reais e devolve um Ponto com as coordenadas preenchidasii) 

ii) Ponto lePonto(void); - Pede ao utilizador, através de msg no écran e leitura do teclado, duas coordenadas x e y, e devolve um  Ponto com essas coordenadas.

iii) float distancia(Ponto p1, Ponto P2); - Calcula a distância entre dois pontos.

Desenvolva, num ficheiro separado,  um programa principal que, usando as funções anteriores, leia dois pontos e escreva a distância entre eles. Verifique que todas as funções estão a funcionar como pretendido.

2. Ainda usando o módulo ponto anterior, escreva, num ficheiro separado, um programa principal que:

a) Declare um vector listaPontos, em que cada posição armazena um Ponto, que suporte MAX_PONTOS Pontos. Faça MAX_PONTOS >=1000.b) Peça ao utilizador um número de pontos nEfect ( 0 < nEfect <= MAX_PONTOS) e leia as coordenadas de cada um dos nEfect pontos e os armazene nas primeiras nEfect posições do vector listaPontos.

c) Escreva uma função com protótipo 

float determinaMinEntrePontos(Ponto listaPontos[], int nEfect, Ponto *p1, Ponto ªp2);

que:

i) Retorna a distância mínima possível entre todos os pares de pontos possíveis do vector listaPontos[]. Pontos que eventualmente sejam coincidentes (ou seja, cuja distância entre eles sejam zero) devem ser ignorados. Por outras palavras, só deverão ser considerados pares de pontos com distâncias entre si superiores a 0.

ii) Preencha os endereços especificados por p1 e p2  com as coordenadas dos dois pontos mais próximos entre si.

Nota: se houver vários pares de pontos com distâncias entre si idênticas e iguais à distância mínima, p1 e p2 podem ser quaisquer par de pontos que verifiquem esta medida. 3. Desenvolva um módulo circunferência, constituído pelos ficheiros de código circunferencia.c e de declarações circunferencia.h, que implementem as seguintes funções:

a) Define um tipo de dados Circunferencia, constituído por umPonto e um real que é o raio.
Escreva funções com os seguintes protótipos:

i) Circunferencia criaCircunferencia(Ponto c, float raio); -  recebe um Ponto c que representa o centro e um real que representa o raio e devolve uma variável de tipo Circunferencia com estes valores.

ii) Circunferencia leCircunferencia(void); - Pede ao utilizador, através de msg no écran e leitura do teclado, duas coordenadas do centro e um raio, e devolve uma variável de tipo Circunferencia com estes valores preenchidos. Use tanto quanto possível funções já desenvolvidas anteriormente.

iii) int nInterseccoes(Circunferencia c1, Circunferencia c2) - Função que recebe duas circunferências como argumento, c1 e c2, e devolve o número de pontos de intersecção entre elas. O número de pontos de intersecção devem ser 0, 1 ou 2, consoante as circunferências sejam disjuntas, tangenciais ou se intersectem. Caso as circunferências c1 e c2 sejam coincidentes no raio e centros, situação em que o número de pontos de intersecção é infinito, deverá ser considerado que o número de intersecções é zero.

Desenvolva, num ficheiro separado,  um programa principal que, usando as funções anteriores, leia duas circunferências  e indique o número de intersecções entre elas. Verifique que todas as funções estão a funcionar como pretendido.

4.  Usando tanto quanto possível as funções desenvolvidas anteriormente, escreva, num ficheiro separado, um programa principal que:

a) Declare um vector listaCirc, em que cada posição armazena uma circunferência, que suporte MAX_CIRC circunferências. Faça MAX_CIRC >=1000.

b) Peça ao utilizador um número de circunferências nEfect ( 0 < nEfect <= MAX_CIRC) e leia as coordenadas do centro e raio de cada um dos nEfect circunferências e os armazene nas primeiras nEfect posições do vector listaCirc.

c) Escreva uma função com protótipo 

int determinaTotalInterseccoes(Circunferencia listaCirc[], int nEfect);

que recebe como argumento o vector de Circunferências e o número efectivo de circunferências preenchidas e devolva o número total de intersecções somando as intersecções entre todos os pares possíveis de circunferências 

5. Modifique ligeiramente o programa desenvolvido no ponto 4 de modo a que o vector listaCirc seja criado após o utilizador indicar o número de circunferências pretendidas, sendo o vector listaCirc criado dinâmico com o número efectivo de circunferências necessárias (e não MAX_CIRC, como anteriormente), de forma a optimizar a utilização da memória e evitar a utilização excessiva desta última (sugestão: utilize as funções de sistema malloc ou calloc).