Universidade do Estado do Rio de Janeiro Centro de Tecnologia e Ciências
Instituto de Física Armando Dias Tavares
Departamento de Física Aplicada e Termodinâmica
Trabalho 2 de Física Computacional – 2015/2
Atividade 1. Funções e sub-rotinas
A função é um recurso de programação que encapsula um bloco de instruções, capaz de processar dados passados como argumentos e que tem, por objetivo, retornar um dado. A função é invocada a partir de seu identificador (nome).
A sub-rotina é semelhante à função diferindo apenas pelo fato de sub-rotina não retornar dados da mesma forma que função. A entrada e saída de dados da sub-rotina se dá via passagem de argumentos. A sub-rotina é invocada também a partir de seu identificador (nome).
Dados são passados para funções e sub-rotinas como argumentos através de dois mecanismos: por cópia e por referência de dados. A passagem de um dado como argumento via mecanismo de cópia permite que o valor do dado copiado seja alterado no escopo (âmbito) da função (ou sub-rotina) sem que isso afete o valor do dado ori-ginal (que foi copiado). Já a passagem do dado como argumento via mecanismo de referência vincula o conteúdo do argumento ao dado original, isto é, se o conteúdo do argumento for modificado, o dado original, que está fora do escopo da função (ou sub-rotina), será afetado da mesma forma.
A execução de uma função ou sub-rotina é encerrada quando a lógica simplesmente termina ou executa uma instrução de retorno.
Lembrando das sintaxes:
• Funçãoidentificador(lista_de_argumentos)
identificador sequência literal que identifica o bloco de instruções
lista_de_argumentos sequência de rótulos dos dados declarados como argumentos com passagem de dados via cópia ou referência
• Subrotinaidentificador(lista_de_argumentos)
identificador sequência literal que identifica o bloco de instruções
lista_de_argumentos sequência de rótulos dos dados declarados como argumentos com passagem de dados via cópia ou referência
Exemplo 1. Calcular o vetor unitário de vetor 2D lido do arquivo “vetor.data”. A saída deve ser as ordenadas do vetor de entrada e do vetor unitário correspondente.
Arquivo “vetor.data”:
✸✱✽✸ ✲✼✱✷✶
Pseudocódigo
definir registrovet2d | declararx,ynuméricos fim registro
FunçãoNorma (pt o)
declararpt ovet2d porcópia
declarardnumérico
1. d←ppt o.x∗ ∗2+pt o.y∗ ∗2
2. retornard {retorna o escalar}
Fim Função
FunçãoUnitario (pt o)
declarardnumérico
1. d←Norma(pt o) {calcula comprimento dept o}
2. uni t←vet2d(pt o.x/d,pt o.y/d) {formata os dados como estrutura vet2d}
3. retornaruni t {retorna o registro}
Fim Subrotina Algoritmo Exemplo1
declararent r ad aarquivo {identificador do arquivo de entrada}
declararp,uvet2d {vetor de entrada e unitário}
1. abrir“vetor.data”comoent r ad aparaleitura
2. ler ement r ad a p.x,p.y
3. fecharent r ad a
4. u←Unitario(p)
5. escrever“p=(”,p.x, “,” ,p.y, “)”
6. escrever“u=(”,u.x, “,” ,u.y, “)” Fim Algoritmo
Fim Pseudocódigo
Exemplo 2. Calcular os vetores unitários dos vetores 2D lidos do arquivo “coordenadas.data”. A saída deve ser as ordenadas dos vetores de entrada e dos vetores unitários correspondentes.
Arquivo “coordenadas.data”: primeira linha tem o total de coordenadas para serem lidas; depois, as coordenadas em si.
✼
✸✱✽✸ ✲✼✱✷✶ ✲✶✱✻✹✻ ✸✱✸✽ ✾✱✻✾ ✸✱✷✶✸ ✹✱✽✷ ✲✻✱✹✾ ✲✾✱✸✵✺ ✶✱✼✽✹ ✲✹✱✾✽✶ ✲✾✱✽✹✺ ✸✱✷✶✶ ✲✻✱✾✼✶
Pseudocódigo
definir registrovet2d | declararx,ynuméricos fim registro
FunçãoNorma (pt o)
declararpt ovet2d porcópia
declarardnumérico
1. d←ppt o.x∗ ∗2+pt o.y∗ ∗2 2. retornard
Fim Função
FunçãoUnitario (pt o)
declararpt ovet2d porcópia
declararuni tvet2d declarardnumérico
1. d←Norma(pt o)
2. uni t←vet3d(pt o.x/d,pt o.y/d)
3. retornaruni t Fim Subrotina Algoritmo Exemplo2
declararent r ad aarquivo {identificador de arquivo}
declararp[∗],u[∗]vet2d {listas sem comprimento inicial}
declararnnumérico {total de coordenadas}
declararinumérico {contador}
1. abrir“coordenadas.data”comoent r ad aparaleitura
2. ler ement r ad a n {ler total de coordenadas no arquivo de entrada}
3. alocar(p[n],u[n]) {atribuir comprimentos as listaspeu}
4. paraide1atén,fazer
5. | ler ement r ad a p[i].x,p[i].y {ler cada coordenada}
6. fim para
7. fecharent r ad a
8. paraide1atén,fazer
9. | u[i]←Unitario(p[i]) {usar função para calcular vetor unitário}
10. | escrever“p[”,i,“]=(”,p[i].x, “,” ,p[i].y, “)”
11. | escrever“u[”,i,“]=(”,u[i].x, “,” ,u[i].y, “)”
12. fim para
13. desalocar(p,u) {liberar comprimento das listas}
Fim Algoritmo Fim Pseudocódigo Exercícios:
Um sólido é um objeto 3D cujo envoltório (casca, bordo) não apresenta buracos. Existem diversas formas de se representar um sólido, sendo a representação por bordos uma das mais simples. Esta representação consiste na segmentação do envoltório formando faces com geometrias simples, ou seja, polígonos convexos planos. As fa-ces, por sua vez, são representadas por vértices ligados por arestas, segmentos lineares limitados por dois vértices.
Na representação de sólidos por bordos, as arestas devem ser compartilhadas sempre por duas faces. As faces possuem orientação segundo a “regra da mão direita”, que implica em uma circulação por arestas no sentido anti-horário. Como as arestas são limitadas por vértices, a circulação pelas arestas implica em uma sequência específica de vértices.
Assim, cada face pode ser identificada por um indexador e deve ter um lista de vértices que a constrói, sendo que esta lista de vértices deve estar ordenada segundo a circulação anti-horária das arestas.
Um exemplo: um cubo cujos vértices sejam
• v0=(−1,−1,−1)
• v1=(−1,−1,+1)
• v2=(−1,+1,+1)
• v3=(−1,+1,−1)
• v4=(+1,+1,+1)
• v5=(+1,−1,+1)
• v6=(+1,−1,−1)
• v7=(+1,+1,−1)
tem sua seis faces definidas da seguinte forma
• f0=[v0,v1,v2,v3] • f1=[v4,v5,v6,v7]
• f2=[v0,v3,v7,v6]
• f3=[v1,v5,v4,v2]
• f4=[v0,v6,v5,v1]
• f5=[v2,v4,v7,v3]
Como as faces são planas, é possível determinar a equação do plano de cada face a partir dos seus vértices. Com a equação do plano, tem-se a normal da face, informação muito valiosa. Na verdade, se se tem uma, se tem a outra: se temos a equação do plano, temos a normal; se temos a normal, temos a equação do plano.
(a) Assim, propõe-se como exercício a elaboração de um algoritmo que leia um arquivo com a lista de vértices e faces e calcule as normais de cada face. Depois, para cada vértice, calcular-se-á a média das normais das faces que compartilham-na. Por fim, cada face deve ter sua equação correspondente. Para isso, realize as seguintes tarefas:
i. criar uma estrutura que seja capaz de representar um ponto no espaço tridimensional;
ii. criar uma estrutura para armazenar a equação do plano da face; esta estrutura deve ter as coordenadas da normal da face mais a distância do plano à origem do sistema de coordenadas.
iii. criar uma estrutura que seja capaz de representar um vértice; o vértice deve conter sua coordenada espacial e a normal associada;
iv. criar uma estrutura que represente uma face; a face deve conter a lista de índices dos vértices que a compõe e a equação do plano da face;
v. criar uma função que calcule o produto vetorial; o argumento deve ser a sequência de três coordenadas espaciais,p1,p2ep3; a saída deve ser o vetor perpendicular aos vetores−−−→p2p1e−−−→p2p3;
vi. criar uma função que retorna o produto escalar; o argumento deve ser a sequência de dois vetores,v1e v2; a saída deve ser o escalar calculado entre os vetores eles;
vii. criar uma função que retorna o comprimento de um vetor; o argumento deve ser o vetor; a saída é o comprimento;
viii. criar uma subrotina que normaliza um vetor; o argumento deve ser o vetor que será normalizado; o mesmovetor que entra, com comprimento diferente da unidade, retorna modificado (normalizado); ix. criar uma subrotina que calcula a equação do plano de uma face; o argumento deve ser a face e a lista de
vértices do sólido;
x. criar uma subrotina que adiciona a normal da face às normais dos vértices que a compõe; os argumentos devem ser a face e a lista de vértices do sólido;
(b) A continuação do trabalho implica no desenvolvimento de um algoritmo que leia um arquivo com as coor-denadas dos vértices e os índices dos vértices de cada face.
Um formato bastante conveniente é Object File Format (.off ). A estrutura do arquivo .off é simples:
❖❋❋
★ ♥✈✿ ♥✉♠❡r♦ ❞❡ ✈❡rt✐❝❡s ★ ♥❢✿ ♥✉♠❡r♦ ❞❡ ❢❛❝❡s ★ ♥❛✿ ♥✉♠❡r♦ ❞❡ ❛r❡st❛s ♥✈ ♥❢ ♥❛
★ ❧✐st❛ ❞❡ ❝♦♦r❞❡♥❛❞❛s
★ ❛ ♣r✐♠❡✐r❛ ❝♦♦r❞❡♥❛❞❛ ❡❤ ♦ ✈❡rt✐❝❡s ✵ ①❬✵❪ ②❬✵❪ ③❬✵❪
①❬✶❪ ②❬✶❪ ③❬✶❪ ✳✳✳
①❬♥✈✲✶❪ ②❬♥✈✲✶❪ ③❬♥✈✲✶❪ ★ ❧✐st❛ ❞❡ ❢❛❝❡s
★ ♥✿ ♥✉♠❡r♦ ❞❡ ✈❡rt✐❝❡s ❞❛ ❢❛❝❡
★ ✐❞❬✵❪ ✐❞❬✶❪ ✳✳✳ ✐❞❬♥✲✶❪✿ ❧✐st❛ ❞♦s ✐♥❞✐❝❡s ❞♦s ✈❡rt✐❝❡s ❞❛ ❢❛❝❡ ♥ ✐❞❬✵❪ ✐❞❬✶❪ ✳✳✳ ✐❞❬♥✲✶❪
Exemplo do cubo: ❖❋❋ ✽ ✻ ✵ ✲✶ ✲✶ ✲✶ ✲✶ ✲✶ ✰✶ ✲✶ ✰✶ ✰✶ ✲✶ ✰✶ ✲✶ ✰✶ ✰✶ ✰✶ ✰✶ ✲✶ ✰✶ ✰✶ ✲✶ ✲✶ ✰✶ ✰✶ ✲✶ ✹ ✵ ✶ ✷ ✸ ✹ ✹ ✺ ✻ ✼ ✹ ✵ ✸ ✼ ✻ ✹ ✶ ✺ ✹ ✷ ✹ ✵ ✻ ✺ ✶
✹ ✷ ✹ ✼ ✸
A primeira linha do arquivo é astringcom o nome do formato: OFF. A segunda linha indica que o modelo tem 8 vértices, 6 faces e 0 arestas. O número de arestas não é importante neste caso. Então permanece 0. Depois, vem a lista de coordenadas, desde o vértice de índice 0 até o oitavo vértice, cujo índice é 7. Os índices não são explícitos.
Assim que se encerra a lista de vértices, segue a lista de faces. Cada linha é descrição de uma face. O primeiro número é o total de vértices da face correspondente. Depois, os índices dos vértices que compõem a face, seguindo a circulação anti-horária. No exemplo, a primeira face tem 4 vértices e os vértices são:v0,v1,v2, v3. A última face tem 4 vértices e os vértices são:v2,v4,v7,v3.
i. Então, a tarefa será criar um algoritmo para ler este arquivo.offe armazenar esta estrutura de dados no programa usando as estruturas do item anterior. Os vértices devem ser armazenados em uma lista do tipo vértice e as faces numa lista do tipo face;
ii. calcule, para cada face, seu vetor normal;
iii. aproveite para adicionar o vetor normal às normais de cada vértice que compõe a face; lembre-se que o valores iniciais das normais de cada vértice devem ser: (0,0,0);
iv. por fim, salve em um arquivo um relatório informando: 1. número de vértices;
2. índice do vértice, ordenadas do vértice, ordenadas da normal do vértice;