/// <summary> /// constroi e rotaciona uma lista de vetores 3D a partir de uma imagem e vetor3 eixos determinados pelo aplicativo, e alguns parâmetros. /// </summary> /// <param name="eixoX">eixo X 3D calculado com ferramentas como o gzimo eixos.</param> /// <param name="eixoY">eixo Y 3D calculado com ferramentas como o gzimo eixos.</param> /// <param name="eixoZ">eixo Z 3D calculado com ferramentas como o gzimo eixos.</param> /// <param name="cena">imagem a ser processada.</param> /// <param name="profundidadeObjeto">profundidade imaginada pelo usuário para a imagem 3D a ser rotacionada.</param> /// <param name="anguloXYEmGraus">ângulo de rotação do plano XY.</param> /// <param name="anguloYZEmGraus">ângulo de rotação do plano YZ.</param> /// <param name="anguloXZEmGraus">ângulo de rotação do plano XZ.</param> /// <param name="msgErro">mensagens de erro durante o processamento da imagem para matriz rotacionada.</param> /// <param name="isAnguloAbsoluto">se [true], os ângulos não são incrementos, mas marcam posições absolutas.</param> /// <param name="isUsaEixoZCalculado">se [true], o eixo Z é calculado pelo produto vetorial entre os /// eixos X e Y, e o ângulo entre esses eixos.</param> /// <param name="funcPerspecitva">função de transformação para o efeito de perspectiva (transformação de dados 3D para geometria 2D.</param> /// <param name="fatorPerspectiva">utiliza o fator de perspectiva para incrementar o método de transformação de perspectiva.</param> ///<returns>retorna a imagem rotacionada.</returns> public Bitmap rotacionaMatriz3D( vetor3 eixoX, vetor3 eixoY, vetor3 eixoZ, Bitmap cena, double profundidadeObjeto, double anguloXYEmGraus, double anguloYZEmGraus, double anguloXZEmGraus, ref string msgErro, bool isAnguloAbsoluto, bool isUsaEixoZCalculado, transformacaoPerspectiva funcPerspectiva, double fatorPerspectiva) { vetor3 eixo_i = new vetor3(eixoX); vetor3 eixo_j = new vetor3(eixoY); vetor3 eixo_k = new vetor3(eixoZ); msgErro = ""; if (msgErro != "") { return(null); } if (isUsaEixoZCalculado) { // calcula o eixo Z a partir do produto vetorial e do ângulo entre os eixos X e Y.É um grande avanço! double anguloXY = Math.Acos(1 / ((eixoX.modulo() * eixoY.modulo())) * (eixoX * eixoY)); // faz o produto vetorial e divide pelos modulos dos eixos X e Y. eixoZ = (Math.Sin(anguloXY) / (eixoX.modulo() * eixoY.modulo())) * (eixoX & eixoY); } // if isUsaEixoZCalculado // normaliza os três eixos. eixo_i.normaliza(); eixo_j.normaliza(); eixo_k.normaliza(); // inicia a imagem a ser rotacionada. Bitmap cenaRotacionada = new Bitmap(6 * cena.Width, 6 * cena.Height); if (isAnguloAbsoluto) { // calcula os ângulos iniciais, que são retirados para formar um ângulo absoluto com os ângulos parâmetros. double anguloXYEixoXinicial = angulos.toGraus(eixo_i.encontraAnguloOmega(vetor3.planoRotacao.XY)); double anguloXZEixoXinicial = angulos.toGraus(eixo_i.encontraAnguloOmega(vetor3.planoRotacao.XZ)); double anguloYZEixoXInicial = angulos.toGraus(eixo_i.encontraAnguloOmega(vetor3.planoRotacao.YZ)); double anguloXYEixoYinicial = angulos.toGraus(eixo_j.encontraAnguloOmega(vetor3.planoRotacao.XY)); double anguloXZEixoYinicial = angulos.toGraus(eixo_j.encontraAnguloOmega(vetor3.planoRotacao.XZ)); double anguloYZEixoYInicial = angulos.toGraus(eixo_j.encontraAnguloOmega(vetor3.planoRotacao.YZ)); double anguloXYEixoZinicial = angulos.toGraus(eixo_k.encontraAnguloOmega(vetor3.planoRotacao.XY)); double anguloXZEixoZinicial = angulos.toGraus(eixo_k.encontraAnguloOmega(vetor3.planoRotacao.XZ)); double anguloYZEixoZInicial = angulos.toGraus(eixo_k.encontraAnguloOmega(vetor3.planoRotacao.YZ)); // rotaciona os eixos cartesianos com acrescimos de ângulos, que também são ângulos absolutos. eixo_i.rotacionaVetorAnguloAbsoluto(anguloXYEmGraus + anguloXYEixoXinicial, -anguloYZEmGraus + anguloYZEixoXInicial, -anguloXZEmGraus + anguloXZEixoXinicial); eixo_j.rotacionaVetorAnguloAbsoluto(anguloXYEmGraus + anguloXYEixoYinicial, -anguloYZEmGraus + anguloYZEixoYInicial, -anguloXZEmGraus + anguloXZEixoYinicial); eixo_k.rotacionaVetorAnguloAbsoluto(anguloXYEmGraus + anguloXYEixoZinicial, -anguloYZEmGraus + anguloYZEixoZInicial, -anguloXZEmGraus + anguloXZEixoZinicial); // normaliza os três eixos. eixo_i.normaliza(); eixo_j.normaliza(); eixo_k.normaliza(); if (!this.isMatrizJaGerada) { this.iniciaMatriz3D( eixoX, eixoY, eixoZ, cena, profundidadeObjeto, fatorPerspectiva, funcPerspectiva, ref msgErro); } // if !isMatrizJaGerada } // if isAnguloAbsoluto else { // cálculo ângulo relativo. // rotaciona os eixos-base, portanto uma rotação com acréscimos de ângulos. eixo_i.rotacionaVetor(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); eixo_j.rotacionaVetor(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); eixo_k.rotacionaVetor(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); if (!this.isMatrizJaGerada) { this.iniciaMatriz3D( eixo_i, eixo_j, eixo_k, cena, profundidadeObjeto, fatorPerspectiva, funcPerspectiva, ref msgErro); } // if !isMatrizJaGerada if (msgErro != "") { return(null); } } // else return(this.calcImagemComMatrix3D( eixo_i, eixo_j, eixo_k, funcPerspectiva, fatorPerspectiva, cenaRotacionada, cena, profundidadeObjeto, ref msgErro)); } // rotacionaMatriz3D()
} // void entradaEixosAparente() /// <summary> /// rotaciona os eixos 3D, extraidos da imagem, com três angulos de rotação. /// </summary> /// <param name="anguloX">rotaciona o plano YZ, em radianos.</param> /// <param name="anguloY">rotaciona o plano XZ, em radianos.</param> /// <param name="anguloZ">rotaciona o plano XY, em radianos.</param> /// <param name="ex">eixo X a ser rotacionado.</param> /// <param name="ey">eixo Y a ser rotacionado.</param> /// <param name="ez">eixo Z a ser rotacionado.</param> public static vetor3[] rotacaoEuler(double anguloX, double anguloY, double anguloZ, vetor3 ex, vetor3 ey, vetor3 ez) { // guarda numa só matriz os eixos X,Y e Z retirados da Imagem Matriz mtzEixosEntrada = new Matriz(3, 3); mtzEixosEntrada.setElemento(0, 0, ex.X); mtzEixosEntrada.setElemento(1, 0, ex.Y); mtzEixosEntrada.setElemento(2, 0, ex.Z); mtzEixosEntrada.setElemento(0, 1, ey.X); mtzEixosEntrada.setElemento(1, 1, ey.Y); mtzEixosEntrada.setElemento(2, 1, ey.Z); mtzEixosEntrada.setElemento(0, 2, ez.X); mtzEixosEntrada.setElemento(1, 2, ez.Y); mtzEixosEntrada.setElemento(2, 2, ez.Z); // faz o calculo da matriz de transformação. Matriz mtzTransformacao = Matriz.MatrizInversa(mtzEixosEntrada); // inicializa os eixos Origem. vetor3 eixoXOrigem = new vetor3(1.0F, 0.0F, 0.0F); vetor3 eixoYOrigem = new vetor3(0.0F, 1.0F, 0.0F); vetor3 eixoZOrigem = new vetor3(0.0F, 0.0F, 1.0F); double anguloX_Z = Math.Acos(eixoXOrigem.Z / vetor3.raio(eixoXOrigem)); double anguloY_Z = Math.Acos(eixoYOrigem.Z / vetor3.raio(eixoYOrigem)); double anguloZ_Z = Math.Acos(eixoZOrigem.Z / vetor3.raio(eixoZOrigem)); // rotaciona o plano YZ, em cordenadas de ângulo absoluto. eixoYOrigem = angulos.rotacionaVetorComAnguloAbsoluto(anguloX, anguloY_Z, eixoYOrigem); eixoZOrigem = angulos.rotacionaVetorComAnguloAbsoluto(anguloX, anguloZ_Z, eixoZOrigem); // rotaciona o plano XZ. eixoXOrigem = angulos.rotacionaVetorComAnguloAbsoluto(anguloY, anguloX_Z, eixoXOrigem); // a próxima rotação é feita sobre a rotação anterior no [eixoZOrigem]. eixoZOrigem.rotacionaVetor(anguloY, anguloZ_Z); // rotaciona o plano XY. // a próxima rotação é feita sobre a rotação anterior no [eixoXOrigem]. eixoXOrigem.rotacionaVetor(anguloZ, anguloX_Z); // a próxima rotação é feita sobre a rotação anterior no [eixoYOrigem]. eixoYOrigem.rotacionaVetor(anguloZ, anguloY_Z); // guarda nesta matriz os angulos de Origem rotacionados. Matriz mtEixosOrigemRotacionados = new Matriz(3, 3); mtEixosOrigemRotacionados.setElemento(0, 0, eixoXOrigem.X); mtEixosOrigemRotacionados.setElemento(1, 0, eixoXOrigem.Y); mtEixosOrigemRotacionados.setElemento(2, 0, eixoXOrigem.Z); mtEixosOrigemRotacionados.setElemento(0, 1, eixoYOrigem.X); mtEixosOrigemRotacionados.setElemento(1, 1, eixoYOrigem.Y); mtEixosOrigemRotacionados.setElemento(2, 1, eixoYOrigem.Z); mtEixosOrigemRotacionados.setElemento(0, 2, eixoZOrigem.X); mtEixosOrigemRotacionados.setElemento(1, 2, eixoZOrigem.Y); mtEixosOrigemRotacionados.setElemento(2, 2, eixoZOrigem.Z); // calcula a matriz que guarda os eixos de Origem rotacionados. Matriz mtEixosSaida = mtEixosOrigemRotacionados * mtzTransformacao; // atribui para os eixos de entrada os eixos rotacionados com ângulos Euler. ex = new vetor3(mtEixosSaida.getElemento(0, 0), mtEixosSaida.getElemento(1, 0), mtEixosSaida.getElemento(2, 0)); ey = new vetor3(mtEixosSaida.getElemento(0, 1), mtEixosSaida.getElemento(1, 1), mtEixosSaida.getElemento(2, 1)); ez = new vetor3(mtEixosSaida.getElemento(0, 2), mtEixosSaida.getElemento(1, 2), mtEixosSaida.getElemento(2, 2)); return(new vetor3[] { ex, ey, ez }); } // rotacionaComAngulosEuler()