Preview only show first 10 pages with watermark. For full document please download

Relatório Ep Cad Cam

Relatório do Exercício Programa (EP) de CAD/CAM de 2005. PMR2520

   EMBED


Share

Transcript

1. Introdução O objetivo deste trabalho é a utilização do programa USPDesigner para o desenvolvimento de três funções em linguagem C++ para o cálculo da área, volume e centro de gravidade de um determinado sólido. Também é desenvolvido uma função para construção de um sólido primitivo T, dadas as suas dimensões. O desenvolvimento dos comandos é mostrado abaixo. 1.1 Cálculo da Área Na realidade, todas as funções usadas para o cálculo da área foram dadas para servir como exemplo para o desenvolvimento das outras funções. A idéia para calcular a área dos sólidos é calcular a área dos triângulos formados pelas meias-arestas e seus vértices. Cada shell tem um conjunto de faces que por sua vez possui um conjunto de laços que é formado por uma seqüência de meias-arestas que liga os vértices do sólido. Com base nesta organização, o cálculo da área de cada triângulo formado pelas meias-arestas do sólido, resulta a área total. A fórmula usada segue a baixo: Área  1 r1 ^ r2 , 2 (1) onde o triângulo tem vértices v  [v0 , v1 , v2 ]T , tal que r1  [v0 , v1 ]T e r2  [v1 , v2 ]T . 1.2 Cálculo do Volume Analogamente à área, o cálculo do volume do sólido é baseado no volume de um tetraedro. A organização das propriedades utilizadas no calculo é a mesma descrita para o cálculo da área. A idéia é transformar, através da matriz de transformação T , um tetraedro qualquer em um tetraedro unitário ortogonal, através dos vértices do sólido original para o novo sistema de coordenadas, desta forma defini-se:  x1 T   y1  z1 x2 y2 z2 x3  y3  . z3  (2) Desta forma o volume é dado por: V T , 6 (3) onde T é o valor absoluto do determinante da matriz T . 1.3 Cálculo do centro de gravidade Utilizando a idéia do cálculo do volume do tetraedro, o centro de gravidade do sólido é a somatória do centro de gravidade de cada tetraedro unitário ortogonal multiplicado pelo seu volume divido pelo volume total do sólido, sendo, portanto uma média ponderada. Define-se as coordenadas do centro de gravidade de cada tetraedro como:  x0  1  x1  x2  x3  4  1 y   y  y 2  y3  ,  0 4 1   z0  1 4  z1  z 2  z3  (4) onde x1, 2,3 , y1, 2,3 e z1, 2,3 são os termos da matriz de transformação T . 1.4 Gerando o T primitivo Dadas as dimensões d1, d2, d3, d4 e d5 do T, utilizam-se os operadores de Euler MVSF (Make Vertex Solid Face), MEV (Make Edge Vertex) e MEF (Make Edge Face) para gerar o sólido desejado. A idéia é fazer a face de cima primeiro. Em seguida, geram-se as arestas que estendem os vértices da primeira face e ao final geram-se todas as faces laterais. Por último, a face inferior. A seqüência da criação de vértices é mostrada na figura 1. Figura 1 – Seqüência da geração de vértices e arrestas do T. 2. Código fonte #include #include #define __VIRTUAL_MEM #define __ROV__ #include "mensagem.h" #include "memvirtu.h" #include "lowparam.h" #include "lowmacro.h" #include "lowsolid.h" #include "eulerops.h" #include "vectorop.h" #include "genfunc_.h" #include "analise_.h" #include "prop.h" #include "mancommd.h" // AREA float MSD_highNamePropriedadeArea(char *name); float MSD_highPropriedadeArea(Id sn); double MSD_lowPropriedadeArea(SPTYPE s); double MSD_lowPropriedadeAreaFace(FPTYPE f); double MSD_lowPropriedadeAreaLaco(LPTYPE l); // VOLUME float MSD_highNamePropriedadeVolume(char *name); float MSD_highPropriedadeVolume(Id sn); double MSD_lowPropriedadeVolume(SPTYPE s); double MSD_lowPropriedadeVolumeFace(FPTYPE f); double MSD_lowPropriedadeVolumeLaco(LPTYPE l); // CENTRO DE GRAVIDADE void MSD_highNamePropriedadeCGravidade(char *name, float *cx, float *cy,float *cz); void MSD_highPropriedadeCGravidade(Id sn, float *cx, float *cy, float *cz); void MSD_lowPropriedadeCGravidade(SPTYPE s, float *cx, float *cy, float *cz); void MSD_lowPropriedadeCGravidadeFace(FPTYPE f, float *cx, float *cy, float *cz); void MSD_lowPropriedadeCGravidadeLaco(LPTYPE l, float *cx, float *cy, float *cz); // PRIMITIVO T void MSD_highCreatePrimitivoT(char *name, float *d1, float *d2, float *d3, float *d4, float *d5); /***************************************************** MAIN *****************************************************/ void MSD_execManipulatePropriedade(void) { int ip; char onam[30]; matrix mat ; float area, volume, cx, cy, cz ; // definição das variáveis locais float d1, d2, d3, d4, d5; for (ip = 0 ; ip == 0 ; ) { switch(optin()) { // recupera as oções do comando // - Comando calcula a area - recupera o nome do solido case 'a': if (1 == sscanf(restbuf, "%s", onam)) { area = MSD_highNamePropriedadeArea(onam) ; ip = 1 ; printf("area = %f\n", - area); } break ; // - Comando calcula o volume case 'v': if (1 == sscanf(restbuf, "%s", onam)) { volume = abs(MSD_highNamePropriedadeVolume(onam)) ; ip = 1 ; printf("volume = %f\n", volume); } break ; // - Comando calcula o centro de gravidade case 'c': if (1 == sscanf(restbuf, "%s", onam)) { MSD_highNamePropriedadeCGravidade(onam, &cx, &cy, &cz) ; ip = 1 ; printf("centro de gravidade = [%f,%f,%f]\n", cx, cy, cz); } break ; // - Comando para criar o primitivo barra T case 't': if(6 == sscanf(restbuf,"%s %f %f %f %f %f",onam,&d1,&d2,&d3,&d4, &d5)) { MSD_highCreatePrimitivoT(onam, &d1, &d2, &d3, &d4, &d5); ip = 1 ; } break ; } if (ip == 0) { printf("-avct nome do sólido\n") ; if (!lineins("? ")) return ; } } } /***************************************************** Cálculo da Área *****************************************************/ float MSD_highNamePropriedadeArea(char *name) { int sn ; // identificador do sólido if ((sn = MSD_getSolidIdFromName(name)) == -1) { fprintf(stderr, "area: nao encontrou o sólido %s!\n", name) ; return(0.0) ; } return(MSD_highPropriedadeArea(sn)) ; } float MSD_highPropriedadeArea(Id sn) { SPTYPE s ; // ponteiro para o sólido if ((s = MSD_getSolid(sn)) == SNIL) { fprintf(stderr, "area: nao encontrou o sólido %d!\n", sn) ; return(0.0) ; } return(MSD_lowPropriedadeArea(s)) ; } double MSD_lowPropriedadeArea(SPTYPE s) { DPTYPE d; FPTYPE f; double area = 0; for (d = SolSShells(s) ; d != DNIL ; d = SheNextD(d)) for (f = SheSFaces(d) ; f != FNIL ; f = FacNextF(f)) area += MSD_lowPropriedadeAreaFace(f); return(area); } double MSD_lowPropriedadeAreaFace(FPTYPE f) { LPTYPE l; double area = 0; area = MSD_lowPropriedadeAreaLaco(FacFLOut(f)); for (l = FacFLoops(f) ; l != LNIL ; l = LooNextL(l)) if (l != FacFLOut(f)) area -= MSD_lowPropriedadeAreaLaco(l); return(area); } double MSD_lowPropriedadeAreaLaco(LPTYPE l) { HPTYPE he ; VPTYPE v1 ; vector aa, bb, cc, dd, vv1 ; veczer(dd) ; he = LooLEdg(l) ; v1 = HalVtx(he) ; he = HalNxt(he) ; do { veccopy(vv1, VerVCoord(v1)) ; vecminus(aa, VerVCoord(HalVtx(he)), vv1) ; vecminus(bb, VerVCoord(HalVtx(HalNxt(he))), vv1) ; cross(cc, aa, bb) ; vecplus(dd, dd, cc) ; } while ((he = HalNxt(he)) != LooLEdg(l)) ; return(-0.5 * dot(FacFeq(LooLFace(l)), dd)) ; } /***************************************************** Cálculo do Volume *****************************************************/ float MSD_highNamePropriedadeVolume(char *name) { int sn ; // identificador do sólido if ((sn = MSD_getSolidIdFromName(name)) == -1) { fprintf(stderr, "Volume: nao encontrou o sólido %s!\n", name) ; return(0.0) ; } return(MSD_highPropriedadeVolume(sn)) ; } float MSD_highPropriedadeVolume(Id sn) { SPTYPE s ; // ponteiro para o sólido if ((s = MSD_getSolid(sn)) == SNIL) { fprintf(stderr, "Volume: nao encontrou o sólido %d!\n", sn) ; return(0.0) ; } return(MSD_lowPropriedadeVolume(s)) ; } double MSD_lowPropriedadeVolume(SPTYPE s) { DPTYPE d; // shell FPTYPE f; // face VPTYPE v; // vertice double Volume = 0; for (d = SolSShells(s) ; d != DNIL ; d = SheNextD(d)) for (f = SheSFaces(d) ; f != FNIL ; f = FacNextF(f)) Volume += MSD_lowPropriedadeVolumeFace(f); return(Volume); } double MSD_lowPropriedadeVolumeFace(FPTYPE f) { LPTYPE l; double Volume = 0; Volume = MSD_lowPropriedadeVolumeLaco(FacFLOut(f)); // passa laco externo da face f for (l = FacFLoops(f) ; l != LNIL ; l = LooNextL(l)) if (l != FacFLOut(f)) Volume -= MSD_lowPropriedadeVolumeLaco(l); return(Volume); } double MSD_lowPropriedadeVolumeLaco(LPTYPE l) { HPTYPE he ; VPTYPE v1 ; vector aa, bb, cc, dd, vv1, vv2, vv3; double volume; volume = 0; he = LooLEdg(l) ; v1 = HalVtx(he) ; he = HalNxt(he) ; do { veccopy(vv1, VerVCoord(v1)); veccopy(aa, VerVCoord(HalVtx(he))); veccopy(bb, VerVCoord(HalVtx(HalNxt(he)))); cross(cc, vv1, bb); volume += dot(cc, aa); } while ((he = HalNxt(he)) != LooLEdg(l)) ; return(-volume/6); } /***************************************************** Cálculo do centro de gravidade *****************************************************/ void MSD_highNamePropriedadeCGravidade(char *name, float *cx, float *cy, float *cz) { int sn ; // identificador do sólido float volume; // volume do sólido if ((sn = MSD_getSolidIdFromName(name)) == -1) { fprintf(stderr, "CGravidade: nao encontrou o sólido %s!\n", name) ; return ; } MSD_highPropriedadeCGravidade(sn, cx, cy, cz); volume = MSD_highNamePropriedadeVolume(name); *cx = *cx/volume; *cy = *cy/volume; *cz = *cz/volume; } void MSD_highPropriedadeCGravidade(Id sn, float *cx, float *cy, float *cz) { SPTYPE s ; // ponteiro para o sólido if ((s = MSD_getSolid(sn)) == SNIL) { fprintf(stderr, "CGravidade: nao encontrou o sólido %d!\n", sn) ; return ; } MSD_lowPropriedadeCGravidade(s,cx,cy,cz); } void MSD_lowPropriedadeCGravidade(SPTYPE s,float *cx, float *cy, float *cz) { DPTYPE d; // shell FPTYPE f; // face VPTYPE v; // vertice for (d = SolSShells(s) ; d != DNIL ; d = SheNextD(d)) for (f = SheSFaces(d) ; f != FNIL ; f = FacNextF(f)) MSD_lowPropriedadeCGravidadeFace(f,cx,cy,cz); } void MSD_lowPropriedadeCGravidadeFace(FPTYPE f,float *cx, float *cy, float *cz) { LPTYPE l; MSD_lowPropriedadeCGravidadeLaco(FacFLOut(f),cx,cy,cz); for (l = FacFLoops(f) ; l != LNIL ; l = LooNextL(l)) if (l != FacFLOut(f)) MSD_lowPropriedadeCGravidadeLaco(l,cx,cy,cz); } void MSD_lowPropriedadeCGravidadeLaco(LPTYPE l, float *cx, float *cy, float *cz) { HPTYPE he ; VPTYPE v1 ; vector aa, bb, cc, dd, vv1, vv2, vv3; double somax, somay, somaz, vtr; he = LooLEdg(l) ; v1 = HalVtx(he) ; he = HalNxt(he) ; do { veccopy(vv1, VerVCoord(v1)); veccopy(aa, VerVCoord(HalVtx(he))); veccopy(bb, VerVCoord(HalVtx(HalNxt(he)))); cross(cc, vv1, bb); vtr = -dot(cc,aa)/6; somax = (VerVCoord(v1)[0]+VerVCoord(HalVtx(he))[0]+VerVCoord(HalVtx(HalNxt(he)))[0])*vtr/4; somay = (VerVCoord(v1)[1]+VerVCoord(HalVtx(he))[1]+VerVCoord(HalVtx(HalNxt(he)))[1])*vtr/4; somaz = (VerVCoord(v1)[2]+VerVCoord(HalVtx(he))[2]+VerVCoord(HalVtx(HalNxt(he)))[2])*vtr/4; *cx = *cx + somax; *cy = *cy + somay; *cz = *cz + somaz; } while ((he = HalNxt(he)) != LooLEdg(l)) ; } /***************************************************** Cria o solido primitivo T *****************************************************/ void MSD_highCreatePrimitivoT(char *name, float *d1, float *d2, float *d3,float *d4, float *d5) { float d6, d7, d8; char sol; d6=(*d1-*d4)/2; d7=d6+*d4; d8=*d2+*d3; MSD_lowMVSF(sol, 1, 1, 1, 0, 0, 0); MSD_highSVME3(sol, 1, 1, 1, 2, 1, 1, 1, 1, *d1, 0, 0); MSD_highSVME3(sol, 2, 1, 1, 3, 1, 1, 1, 1, *d1, -*d2, 0); MSD_highSVME3(sol, 3, 2, 2, 4, 1, 1, 1, 1, d7, -*d2, 0); MSD_highSVME3(sol, 4, 3, 3, 5, 1, 1, 1, 1, d7, -d8, 0); MSD_highSVME3(sol, 5, 4, 4, 6, 1, 1, 1, 1, d6, -d8, 0); MSD_highSVME3(sol, 6, 5, 5, 7, 1, 1, 1, 1, d6, -*d2, 0); MSD_highSVME3(sol, 7, 6, 6, 8, 1, 1, 1, 1, 0, -*d2, 0); MSD_highMEF2(sol, 1, 8, 2, 7, 1, 1, 1, 2); MSD_highSVME3(sol, 1, 2, 2, 9, 2, 2, 1, 1, 0, 0, -*d5); MSD_highSVME3(sol, 2, 3, 3, 10, 2, 2, 1, 1, *d1, 0, -*d5); MSD_highSVME3(sol, 3, 4, 4, 11, 2, 2, 1, 1, *d1, -*d2, -*d5); MSD_highSVME3(sol, 4, 5, 5, 12, 2, 2, 1, 1, d7, -*d2, -*d5); MSD_highSVME3(sol, 5, 6, 6, 13, 2, 2, 1, 1, d7, -d8, -*d5); MSD_highSVME3(sol, 6, 7, 7, 14, 2, 2, 1, 1, d6, -d8, -*d5); MSD_highSVME3(sol, 7, 8, 8, 15, 2, 2, 1, 1, d6, -*d2, -*d5); MSD_highSVME3(sol, 8, 1, 1, 16, 2, 2, 1, 1, 0, -*d2, -*d5); MSD_highMEF2(sol, 9, 10, 1, 2, 2, 2, 2, 3); MSD_highMEF2(sol, 10, 11, 2, 3, 2, 3, 2, 4); MSD_highMEF2(sol, 11, 12, 3, 4, 2, 4, 2, 5); MSD_highMEF2(sol, 12, 13, 4, 5, 2, 5, 2, 6); MSD_highMEF2(sol, 13, 14, 5, 6, 2, 6, 2, 7); MSD_highMEF2(sol, 14, 15, 6, 7, 2, 7, 2, 8); MSD_highMEF2(sol, 15, 16, 7, 8, 2, 8, 2, 9); MSD_highMEF2(sol, 16, 9, 8, 10, 2, 9, 3, 10); MSD_lowSetNormal(MSD_getSolid(sol), sol); MSD_lowSetEdgeAngle(MSD_getSolid(sol)); strcpy(SolName(MSD_getSolid(sol)), name); } 3. Resultados Inicialmente, quatro sólidos primitivos são testados no programa. O primeiro resultado mostra o valor teórico calculado pelas fórmulas clássicas e o segundo resultado mostra o valor retornado pelo programa desenvolvido pelo grupo. Seguem a baixo os resultados: Tabela 1 – Resultado nos programas dos sólidos primitivos. Primitivo Cone, n=20, R=5, Cube, A=10, B=20, Cylinder, n=20, R=5, Sphere, n=20, R=5 H=10 C=30 H=10 área teórica 254,160186 2.200,000000 471,238898 314,1592654 prop –a 251,724762 2.200,000000 467,377441 312,547180 volume teórico 261,7993878 6.000,000000 785,398163 523,598776 prop –v 257,000000 6.000,000000 772,000000 518,000000 centro teórico x = 0,0 y = 0,0 z = 2,5 x = 5,0 y = 10,0 z = 15,0 x = 0,0 y = 0,0 z = 5,0 x = 0,0 y = 0,0 z = 0,0 prop –c x = 0,0 y = 0,0 z = 2,5 x = 5,0 y = 10,0 z = 15,0 x = 0,0 y = 0,0 z = 5,0 x = 0,0 y = 0,000001 z = 0,0 Testando a geração do sólido primitivo T, temos: Tabela 2 – Testes com o T primitivo T Primitivo T, d1=10, d2=2, d3=5, T, d1=2, d2=1, d3=5, d4=2, d5=2 d4=1, d5=1 área teórica 30,000000 30,000000 prop –a 30,000000 30,000000 volume teórico 60,000000 7,000000 prop –v 60,000000 7,000000 centro teórico x = 5,0 y = -2,166667 z = -1,0 x = 1,0 y = -2,642857 z = -0,5 prop –c x = 5,0 y = -2,166667 z = -1,0 x = 1,0 y = -2,642857 z = -0,5 4. Conclusões Embora os cálculos dos elementos primitivos teóricos e computacionais apresentem uma pequena discrepância, os resultados são satisfatórios em todos os testes realizados, demonstrando que as funções desenvolvidas para os cálculos da área, volume e centro de gravidade estão corretas. Sentiu-se a necessidade de mostrar os sólidos construídos, porém como não é possível a utilização da tecla print screen, não foi possível colocar as imagens no trabalho. Departamento de Engenharia Mecatrônica Escola Politécnica da Universidade de São Paulo PMR 2520 – Introdução Ao CAD/CAM Prof. Dr. Marcos Tsuzuki Relatório do Exercício - Programa USPDesigner Leandro Nigro Malavazi 3632797 Mário Morishita 3727830 19/04/2006