}// drawLegend() /// <summary> /// desenha no dispositivo gráfico do gzimo eixos, um plano quase /// transparente, útil para visualização qual plano é qual. /// </summary> /// <param name="g">dispositivo gráfico para desenho.</param> /// <param name="corQ1">cor do plano. Deve ser bem transparente.</param> /// <param name="numerosIndicesEixoeixos">índices do eixos gráfico, que determina o plano.</param> public void drawATransparentPlane(PointF location, Graphics g, Color corQ1, vetor2 locOffset, params int[] numeroIndicesEixoeixos) { if (numeroIndicesEixoeixos.Length != 0) { List <PointF> pontosPlano = new List <PointF>(); for (int x = 0; x < numeroIndicesEixoeixos.Length; x++) { vetor3 v = this.cordsGzimoEixos[numeroIndicesEixoeixos[x]].Clone(); v.multiplicaPorUmaBase(this.eixoXGzimo, this.eixoYGzimo, this.eixoZGzimo); pontosPlano.Add(vetor2ToPointF(this.perspectiva( v, this.fatorPerspectiva), new PointF((float)locOffset.X, (float)locOffset.Y))); } // for x GraphicsPath path = new GraphicsPath(pontosPlano.ToArray(), new byte[] { (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line }); Region rg = new Region(path); g.FillRegion(new SolidBrush(corQ1), rg); } // if numeroIndicesEixoeixos.Length!=0 } // drawATransparentPlane()
public new void Update() { if ((this.timeToUpdate.IsTimeToAct()) && (this.ponteiroDestino != null)) { double deltaAngulo = angulos.toRadianos(AnguloEntreVetores(this.ponteiroAtual - this.ponteiroCentral, this.ponteiroDestino - this.ponteiroCentral)); //se os ponteiros atual e destinho não estiverem pertos, //continua movimentando o ponteiro atual até chegar perto //vetorialmente do vetor destino. if ((ponteiroAnterior != null) && (!isSentidoHorarioDeRotacao)) { ponteiroAnterior = new vetor2(ponteiroAtual); ponteiroAtual = ponteiroAtual.RotacionaVetor(angulos.toRadianos(+deltaAngulo / 0.5)); } // if else { ponteiroAnterior = new vetor2(ponteiroAtual); ponteiroAtual = ponteiroAtual.RotacionaVetor(angulos.toRadianos(-deltaAngulo / 0.5)); } // else if (vetor2.Distancia(ponteiroAtual, ponteiroDestino) < 1.5) { this.PonteiroDirecao = new vetor2(this.ponteiroAtual - this.ponteiroCentral); // guarda a posição e direção na variável de consulta fora do componente. }//if }// if } // Update()
private void SetMatrixTranslation(vetor2 location) { RawMatrix3x2 m_Translation; // cria a matriz que servirá de translação. Translation((float)location.X, (float)location.Y, out m_Translation); // cria a matriz de translacao. MyDevice2D.render[this.idRender].Transform = m_Translation; // seta a matriz do RenderTarget para a matriz de translação. }
} // void DrawGzimo(). /// <summary> /// desenha uma legenda de orientação dos eixos cartesianos. /// desenha também retângulos coloridos de acordo com cada plano e letras indicando o nome do plano (XZ,YZ, ou XY). /// </summary> /// <param name="g">dispositivo gráfico para desenho da legenda.</param> /// <param name="locLegenda">posição da legenda, em relação ao Control pai.</param> /// <param name="vOrigemLegenda">origem dos eixos legenda.</param> private void drawLegend(Graphics g, vetor2 locLegenda, vetor3 vOrigemLegenda) { Pen pincel = new Pen(Color.Black, 2.5F); vetor2 v2ini = vetor3.transformacaoPerspectivaIsometrica(vOrigemLegenda, fatorPerspectiva); vetor2 v2fini = vetor3.transformacaoPerspectivaIsometrica(eixoXLegenda, fatorPerspectiva); pincel.Color = Color.Green; g.DrawLine(pincel, (float)locLegenda.X + (float)v2ini.X, (float)locLegenda.Y - (float)v2ini.Y, (float)locLegenda.X + (float)v2fini.X, (float)locLegenda.Y - (float)v2fini.Y); g.DrawString("X", this.fonteGzimo, new SolidBrush(Color.Green), new PointF((float)locLegenda.X + (float)v2fini.X + 5, (float)locLegenda.Y - (float)v2fini.Y)); v2fini = vetor3.transformacaoPerspectivaIsometrica(eixoYLegenda, fatorPerspectiva); pincel.Color = Color.Red; g.DrawLine(pincel, (float)locLegenda.X + (float)v2ini.X, (float)locLegenda.Y - (float)v2ini.Y, (float)locLegenda.X + (float)v2fini.X, (float)locLegenda.Y - (float)v2fini.Y); g.DrawString("Y", this.fonteGzimo, new SolidBrush(Color.Red), new PointF((float)locLegenda.X + (float)v2fini.X, (float)locLegenda.Y - (float)v2fini.Y - 5)); v2fini = vetor3.transformacaoPerspectivaIsometrica(eixoZLegenda, fatorPerspectiva); pincel.Color = Color.Blue; g.DrawLine(pincel, (float)locLegenda.X + (float)v2ini.X, (float)locLegenda.Y - (float)v2ini.Y, (float)locLegenda.X + (float)v2fini.X, (float)locLegenda.Y - (float)v2fini.Y); g.DrawString("Z", this.fonteGzimo, new SolidBrush(Color.Blue), new PointF((float)locLegenda.X + (float)v2fini.X + 6, (float)locLegenda.Y - (float)v2fini.Y - 6)); }// drawLegend()
// CÁLCULOS: // EixosEntrada*mt[3,3]=EixosOrigem. // mt[3,3]=MatrizInversa(EixosEntrada)*EixosOrigem. // como EixosOrigem=I3, mt[3,3]=MatrizInversa(EixosEntrada). // EixosOrigemRotacionados=rotaciona(EixosOrigem). // EixosSaida=EixosOrigemRotacionados*MatrizInversa(mt[3,3]. /// <summary> /// construtor. Constroi os eixos 3D e rotaciona estes eixos com os /// três angulo Euler de entrada. /// </summary> /// <param name="cena">imagem cujos eixos serão aplicados.</param> /// <param name="eixoXAparente">representa o eixo X aparente, retirado da imagem de entrada.</param> /// <param name="anguloX">ângulo X Euler.</param> /// <param name="anguloY">ângulo Y Euler.</param> /// <param name="anguloZ">ângulo Z Euler.</param> /// <param name="dimCells">dimensões da imagem final, já processada.</param> public Bitmap rotacionaComAngulosEuler(Bitmap cena, vetor2 eixoXAparente, double anguloX, double anguloY, double anguloZ, Size dimCells) { // inicializa o eixo X com o parâmetro de entrada [eixoXAparente]. vetor3 eixoX = new vetor3(eixoXAparente.X, eixoXAparente.Y, 0.0); // calcula o eixo Y como rotação de 90.0F graus do eixo X. vetor2 ey = angulos.rotacionaVetor(90.0F, eixoXAparente); // guarda o eixo Y num objeto [vetor3]. vetor3 eixoY = new vetor3(ey.X, ey.Y, 0.0); // inicializa o eixo Z, como produto vetorial do eixo X e eixo Y. vetor3 eixoZ = new vetor3(); // calcula o produto vetorial com o eixo X e o eixo Y. eixoZ.X = eixoX.Y * eixoY.Z - eixoX.Z * eixoY.Y; eixoZ.Y = eixoX.Z * eixoY.X - eixoX.X * eixoY.Z; eixoZ.Z = eixoX.X * eixoY.Y - eixoX.Y * eixoY.X; // faz a rotação nos três eixos. vetor3[] eixosTransformados = rotacaoEuler(anguloX, anguloY, anguloZ, eixoX, eixoY, eixoZ); // calcula o eixo X aparente através da perspectiva isométrica dos três eixos. vetor2 eixoX2D = new vetor2((eixosTransformados[0].X + eixosTransformados[1].X + eixosTransformados[2].X) + (eixosTransformados[0].Z + eixosTransformados[1].Z + eixosTransformados[2].Z) / this.szPerspectiva, (eixosTransformados[0].Y + eixosTransformados[1].Y + eixosTransformados[2].Y) + (eixosTransformados[0].Z + eixosTransformados[1].Z + eixosTransformados[2].Z) / this.szPerspectiva); // o angulo de rotação é zero porque a rotação foi feita no eixo X Aparente [eixoX2D]. return(rotaciona.rotacionaImagemComUmEixo2D(cena, 0.0F, eixoX2D, dimCells)); } // void entradaEixosAparente()
} // rotacionaImagemComDoisEixos2D() /// <summary> /// aplica a imagem [cena] um eixo X e Y dados, sendo o eixo X /// rotacionado por um ângulo [angle]; o eixo Y é calculado por este método. /// </summary> /// <param name="cena">imagem em processamento.</param> /// <param name="angle">ângulo em graus para o incremento no eixo X e no eixo Y.</param> /// <param name="eixoX_2D">eixo X calculado manualmente com marcação na imagem [cena].</param> /// <param name="dimCells">dimensões da imagem final, já processada.</param> /// <returns>retorna a imagem rotacionada.</returns> public static Bitmap rotacionaImagemComUmEixo2D(Bitmap cena, double angle, vetor2 eixoX_2D, Size dimCells) { if (cena == null) { throw new Exception("erro no metodo rotacionaImagemComUmEixo2D(), imagem currente e' nula"); } double anguloInc = angle; // prepara os eixos X e Y. // O eixo Y é conseguido rotacionando o eixo X por 90 graus. // O eixo X é conseguido rotacionando o eixo Y por -90 graus. // inicializa o eixo X, a partir do eixoX_2D, que é um eixo X aparente, conseguido com marcação na imagem. vetor2 ex = new vetor2(eixoX_2D.X, eixoX_2D.Y); // eixo Y, que foi calculado neste método como uma rotação de 90 graus sobre o eixo X [ex]. vetor2 ey = angulos.rotacionaVetor(90.0F, ex); // constrói o eixo X como uma matriz [1,2]. MATRIZES.Matriz mtEixoX = new MATRIZES.Matriz(1, 2); mtEixoX.setElemento(0, 0, ex.X); mtEixoX.setElemento(0, 1, ex.Y); // constroi a matriz de transformação (dos eixos construídos para os eixos (1,0) e (0,1). MATRIZES.Matriz mtrzTransf = new MATRIZES.Matriz(2, 2); mtrzTransf.setElemento(0, 0, ex.X); mtrzTransf.setElemento(0, 1, ex.Y); mtrzTransf.setElemento(1, 0, ey.X); mtrzTransf.setElemento(1, 1, ey.Y); // calcula a matriz inversa de transformação. MATRIZES.Matriz mtrzTransfInversa = MATRIZES.Matriz.MatrizInversa(mtrzTransf); // multiplica a matriz do eixo X pela matriz inversa de transformação. MATRIZES.Matriz mtEixoXTransformado = mtEixoX * mtrzTransfInversa; // rotaciona o eixo X mtEixoXTransformado = angulos.rotacionaVetor(anguloInc, mtEixoXTransformado); // constroi o eixo Y como sendo uma rotação de 90.0F graus no eixo X. MATRIZES.Matriz mtEixoYTransformado = angulos.rotacionaVetor(90.0F, mtEixoXTransformado); // mutliplica os eixos X e Y pela matriz de transformação, retornando para o universo 2D inicial. mtEixoXTransformado = mtEixoXTransformado * mtrzTransf; mtEixoYTransformado = mtEixoYTransformado * mtrzTransf; // converte a matriz do eixo X para um [vetor2]. vetor2 eixoXFinal = new vetor2((double)mtEixoXTransformado.getElemento(0, 0), (double)mtEixoXTransformado.getElemento(0, 1)); // converte a matriz do eixo Y para um [vetor2]. vetor2 eixoYFinal = new vetor2((double)mtEixoYTransformado.getElemento(0, 0), (double)mtEixoYTransformado.getElemento(0, 1)); // normaliza os eixos finais. eixoXFinal = vetor2.normaliza(eixoXFinal); eixoYFinal = vetor2.normaliza(eixoYFinal); // retorna uma Imagem construida com os eixos finais. return(new Bitmap(aplicaEixos(cena, eixoXFinal, eixoYFinal, dimCells))); } // rotacionaImagemComUmEixo2D
} // Draw() /// <summary> /// desenha um texto. Há que ter os métodos Begin() e End() para efetivar a renderização. /// </summary> public void Draw(vetor2 location, float opacity, RawRectangleF rectSource) { SetMatrixTranslation(location); // a coisa mais certa é setar a matriz transform do RenderTarget, e depois setar a transform para Identity. MyDevice2D.render[this.idRender].DrawBitmap(this.imageDirect2D, 1.0f, BitmapInterpolationMode.Linear, rectSource); SetMatrixIdentity();// restaura a matriz identidade , para a matriz transform do RenderTarget. } // Draw()
} // MyImage() /// <summary> /// desenha um texto. Há que ter os métodos Begin() e End() para efetivar a renderização. /// </summary> public void Draw(vetor2 location) { SetMatrixTranslation(location); // desenha o Direct2D1.Bitmap, com a matriz de translação setada na matriz de transformação do RenderTarget. MyDevice2D.render[this.idRender].DrawBitmap(this.imageDirect2D, 1, SharpDX.Direct2D1.BitmapInterpolationMode.NearestNeighbor); SetMatrixIdentity(); } // Draw()
} // rotacionaVetor() public static MATRIZES.Matriz rotacionaVetor(double anguloEmGraus, MATRIZES.Matriz mtv) { vetor2 vInicial = new vetor2((double)mtv.getElemento(0, 0), (double)mtv.getElemento(0, 1)); vetor2 vFinal = rotacionaVetor(anguloEmGraus, vInicial); MATRIZES.Matriz mtFinal = new MATRIZES.Matriz(1, 2); mtFinal.setElemento(0, 0, (double)vFinal.X); mtFinal.setElemento(0, 1, (double)vFinal.Y); return(mtFinal); }
public RenderScene(Control container, vetor2 locationScene, Size szScene) { this.sizeScene = szScene; this.container = container; this.locationScene = locationScene; this.imagesD2D = new List <MyImage>(); this.locations = new List <MATRIZES.vetor2>(); this.opacities = new List <float>(); this.sceneBitmapGDI = new System.Drawing.Bitmap(szScene.Width, szScene.Height); // cria uma imagem GDI da cena. } // MySceneImage()
/// <summary> /// rotaciona um vetor 2D em um angulo determinado de incremento. /// </summary> /// <param name="anguloEmGraus">angulo em graus de incremento, utilizado na rotacao.</param> /// <param name="v">vetor 2D a ser rotacionado.</param> /// <returns>retorna um vetor2 rotacionado em um angulo de [anguloEmGraus].</returns> public static vetor2 rotacionaVetor(double anguloEmGraus, vetor2 v) { vetor2 vf = new vetor2(0.0F, 0.0F); double angle = (double)vetor3.toRadianos(anguloEmGraus); double cosAngle = (double)Math.Cos(angle); double sinAngle = (double)Math.Sin(angle); vf.X = v.X * cosAngle - v.Y * sinAngle; vf.Y = v.Y * cosAngle + v.X * sinAngle; return(vf); } // rotacionaVetor()
/// <summary> /// muda a direção do vetor 2D para um determinado [anguloEmGraus]. /// </summary> /// <param name="anguloEmGraus">novo ângulo-direção do vetor 2D de entrada.</param> /// <param name="v">estrutura representando o vetor 2D.</param> /// <returns></returns> public static vetor2 rotacionaVetorComAnguloAbsoluto(double anguloEmGraus, vetor2 v) { vetor2 vf = new vetor2(0.0, 0.0); double angle = vetor3.toRadianos(anguloEmGraus); double raio = Math.Sqrt(v.X * v.X + v.Y * v.Y); vf.X = raio * Math.Cos(angle); vf.Y = raio * Math.Sin(angle); return(vf); } // rotacionaVetorComAnguloAbsoluto()
} // Draw() // calcula o ângulo em graus entre dois vetores. private double AnguloEntreVetores(vetor2 v1, vetor2 v2) { double n1 = v1.Modulo(); double n2 = v2.Modulo(); if ((n1 == 0.0) || (n2 == 0)) { return(100.0); } double produtoEscalar = vetor2.ProdutoEscalar(v1, v2); return(angulos.toGraus(Math.Acos(produtoEscalar / (n1 * n2)))); } // AnguloEntreVetores()
} // MySceneImage() public void AddImage(MyImage image, vetor2 location, float opacity) { if ((this.imagesD2D == null) || (this.imagesD2D.Count == 0)) { this.imagesD2D = new List <MyImage>(); } if ((this.locations == null) || (this.locations.Count == 0)) { this.locations = new List <vetor2>(); } this.imagesD2D.Add(image); this.locations.Add(location); this.opacities.Add(opacity); } // AddImage()
} // btnPlanoXY_Click() /// <summary> /// desenha uma linha reta, componente do gzimo eixos. /// </summary> /// <param name="g">dispositivo gráfico da imagem do gzimo eixos.</param> /// <param name="v1">vetor 3D inicial.</param> /// <param name="v2">vetor 3D final.</param> /// <param name="pincel">Caneta para o desenho da linha, determina a cor da linha.</param> private void drawLinePerspective(Graphics g, vetor3 v1, vetor3 v2, Pen pincel) { vetor2 v2_i = perspectiva(v1, fatorPerspectiva); vetor2 v2_f = perspectiva(v2, fatorPerspectiva); // desenha a linha currente do Gzimo eixos. g.DrawLine(pincel, (float)posicao.X + (float)v2_i.X, (float)posicao.Y + (float)v2_i.Y, (float)posicao.X + (float)v2_f.X, (float)posicao.Y + (float)v2_f.Y); } // drawLinePerspective()
} // iniciaMatriz3D() public Bitmap calcImagemComMatrix3D(vetor3 eixoX, vetor3 eixoY, vetor3 eixoZ, Matriz3DparaImagem2D.transformacaoPerspectiva funcPerspectiva, double fatorPerspectiva, Bitmap cenaRotacionada, Bitmap cena, double profundidadeObjeto, ref string msgErro) { try { Bitmap cenaSaida = null; int x, y, z; v2_0 = null; if (!this.isMatrizJaGerada) { this.iniciaMatriz3D(eixoX, eixoY, eixoZ, cena, profundidadeObjeto, fatorPerspectiva, funcPerspectiva, ref msgErro); } // malha principal, mapeia a matriz rotacionada e seta as cores das coordenadas calculadas. for (z = 0; z < this.matrix.GetLength(2); z++) { for (y = 0; y < this.matrix.GetLength(1); y++) { for (x = 0; x < this.matrix.GetLength(0); x++) { v3 = new vetor3(this.matrix[x, y, z]); v3.multiplicaPorUmaBase(eixoX, eixoY, eixoZ); v2_0 = funcPerspectiva(v3, fatorPerspectiva); if (((int)(v2_0.X - xmin) < cena.Width) && ((int)(v2_0.Y - ymin) < cena.Height) && ((v2_0.X - xmin) >= 0) && ((v2_0.Y - ymin) >= 0)) { // seta a cor na coordenada 2D perspectiva isométrica calculada a partir do ponto 3D matrix[x,y,z]. cenaRotacionada.SetPixel((int)(v2_0.X - this.xmin), (int)(v2_0.Y - this.ymin), this.matrix[x, y, z].cor); } } // for x } } msgErro = ""; cenaSaida = Utils.UtilsImage.recortaImagem(cenaRotacionada); return(cenaSaida); } // try catch (Exception ex) { msgErro = "Erro no processamento da imagem, em sua inicialização. Mensagem de Erro: " + ex.Message; return(null); } // catch } // calcImagemComMatrix3D()
} // IsClockWiseRotation() private double GetAngle(vetor2 ponteiroDirecao) { double anguloQuadrante = Math.Atan2(Math.Abs(ponteiroDirecao.Y), Math.Abs(ponteiroDirecao.X)); if ((ponteiroDirecao.X < 0) && (ponteiroDirecao.Y > 0)) { anguloQuadrante += Math.PI / 2.0; } if ((ponteiroDirecao.X < 0) && (ponteiroDirecao.Y < 0)) { anguloQuadrante += Math.PI; } if ((ponteiroDirecao.X > 0) && (ponteiroDirecao.Y < 0)) { anguloQuadrante += (3.0 / 2.0) * Math.PI; } return(angulos.toGraus(anguloQuadrante)); } // AnguloDirecao()
public GridImageViewUmaSoImagemEntrada(Control pai, PointF location, Size dimCellsGrade, Size dimGrade, vetor2 eixoXAparente, Bitmap cenainicial) { // guarda a imagem que vai ser rotacionada, formando a lista de imagens. this.cenaOriginal = cenainicial; // seta a localizacao deste control. this.Location = new Point((int)location.X, (int)location.Y); // carrega o eixo X aparente. this.eixoX = eixoXAparente; // dimensões de cada imagem na grade do tabuleiro. szCellGrade = dimCellsGrade; // calcula o incremento do angulo, o quanto varia para cada imagem na tela. this.incrementoAngulo = 360.0F / (gradeTela.Width * gradeTela.Height); // seta as dimensões da cela. this.gradeTela = dimGrade; // inicializa a imagem que guardará a lista de imagens; this.cenaTela = new Bitmap(gradeTela.Width * szCellGrade.Width, gradeTela.Height * szCellGrade.Height); // determina o tamanho deste control. this.Size = new Size(this.cenaTela.Width, this.cenaTela.Height); // autoscroll=true para garantir que a lista seja totalmente vista, // mesmo que a tela seja insuficiente para desenhar todas as imagens. this.AutoScroll = true; // control pai, para fins registro perante a hierarquia. this.controlPai = pai; // adiciona este control ao controi pai. pai.Controls.Add(this); // seta para [true] a visibilidade deste control. this.Visible = true; // calcula as imagens rotacionadas, e adiciona-as na lista de imagens. this.calcListaImagens(); } // listImageView
public JoystickVetorial(Point location, double radious, Control container) { this.ponteiroCentral = new vetor2(radious / 2.0, radious / 2.0); this.radious = radious; // dimensão da imagem da área ativa do joystick. this.Size = new Size((int)radious, (int)radious); this.Location = new Point(location.X, location.Y); this.BackColor = container.BackColor; this.timeToUpdate = new TimeReaction(1000.0 / 48.0); this.ctrlContainer = container; this.MouseMove += JoystickVetorial_MouseMove; this.MouseDown += JoystickVetorial_MouseDown; this.ponteiroAtual = new vetor2(radious, 0.0); // inicializa ó ponteiro de consulta de saída. this.ponteiroAtual = new vetor2(radious, 0.0); // inicializa o ponteiro de posição atual. this.ponteiroDestino = null; } // JoystickVetorial()
} // AnguloEntreVetores() //sentido anti-horário se omega>0 //sentido horário se omega<0 private bool IsSentidoHorario(vetor2 v1, vetor2 vdestino) { vetor2 vSentidoAntiHorario = new vetor2(v1); vetor2 vSentidoHorario = new vetor2(v1); vSentidoAntiHorario = vSentidoAntiHorario.RotacionaVetor(+1.0); // sentido anti-horário; vSentidoHorario = vSentidoHorario.RotacionaVetor(-1.0); // sentido horário, if (vetor2.Distancia(vSentidoAntiHorario, vdestino) < vetor2.Distancia(vSentidoHorario, vdestino)) { return(false); } if (vetor2.Distancia(vSentidoAntiHorario, vdestino) < vetor2.Distancia(vSentidoHorario, vdestino)) { return(true); } return(true); } // IsClockWiseRotation()
} // Draw() /// <summary> /// desenha um texto. Há que ter os métodos Begin() e End() para efetivar a renderização. /// </summary> public void Draw(vetor2 location, float opacity) { SetMatrixTranslation(location); MyDevice2D.render[this.idRender].DrawBitmap(this.imageDirect2D, opacity, SharpDX.Direct2D1.BitmapInterpolationMode.NearestNeighbor); SetMatrixIdentity(); } // Draw()
private void JoystickVetorial_MouseMove(object sender, MouseEventArgs e) { ponteiroDestino = new vetor2(e.Location.X, e.Location.Y); this.isSentidoHorarioDeRotacao = this.IsSentidoHorario(this.ponteiroAtual, this.ponteiroDestino); this.Draw(); }
} // rotacionaImagemComUmEixo2D /// <summary> /// retorna uma Imagem aplicando os eixos X e Y em cada ponto. /// </summary> /// <param name="cena">Imagem a ser processionada.</param> /// <param name="ex">coordenadas do eixo X.</param> /// <param name="ey">coordenadas do eixo Y.</param> /// <param name="dimCells">dimensões da imagem final, já processada.</param> /// <returns></returns> protected static Bitmap aplicaEixos(Bitmap cena, vetor2 ex, vetor2 ey, Size dimCells) { if (cena == null) { throw new Exception("erro no metodo [aplicaEixos()], imagem currente e' nula"); } double xf = 0.0F; double yf = 0.0F; Bitmap cenaFinal = new Bitmap(3 * cena.Width, 3 * cena.Height); double minX = +1000000000.0F; double minY = +1000000000.0F; double maxX = -1000000000.0F; double maxY = -1000000000.0F; int xx, yy; try { for (xx = 0; xx < cena.Width; xx++) { for (yy = 0; yy < cena.Height; yy++) { xf = (double)((xx) * ex.X + (yy) * ey.X); yf = (double)((xx) * ex.Y + (yy) * ey.Y); // calcula os pontos extremos da imagem, para fins de correção de // coordenadas fora das dimensões da imagem final. if (xf < minX) { minX = xf; } if (xf > maxX) { maxX = xf; } if (yf < minY) { minY = yf; } if (yf > maxY) { maxY = yf; } } // for yy } cenaFinal = new Bitmap((int)((maxX - minX) + cena.Width / 2), (int)((maxY - minY) + cena.Height / 2)); for (xx = 0; xx < cena.Width; xx++) { for (yy = 0; yy < cena.Height; yy++) { xf = (double)((xx) * ex.X + (yy) * ey.X) - minX; yf = (double)((xx) * ex.Y + (yy) * ey.Y) - minY; cenaFinal.SetPixel((int)xf, (int)yf, cena.GetPixel(xx, yy)); } } return(new Bitmap(cenaFinal, new Size(3 * dimCells.Width, 3 * dimCells.Height))); } catch (Exception ex1) { MessageBox.Show(ex1.Message + " valor(X,Y): " + (int)xf + " : " + (int)yf + " dimensoes: (" + cenaFinal.Width + " , " + cenaFinal.Height); return(null); } // catch } // aplicaEixos()
/// <summary> /// constroi este tipo de Gzimo (eixos). /// </summary> /// <param name="novasDims">dimensões da imagem de saída.</param> /// <param name="location">posicionamento do Gzimo frente ao control.</param> /// <param name="_fatorPerspectiva">fator de divisão da cordenada aparente na perspectiva isométrica.</param> /// <param name="sizeLinha">tamanho da grossura da linha.</param> /// <param name="sizeLadoGzimo">dimensões do gzimo.</param> /// <param name="pai">Control parent do Gzimo.</param> /// <param name="funcaoPerspectiva">ponteiro de função para cálculo da perspectiva.</param> /// <param name="dimsImage">dimensões da imagem de entrada.</param> public GzimoEixos( Size novasDims, PointF location, double _fatorPerspectiva, double sizeLinha, double sizeLadoGzimo, Control pai, Matriz3DparaImagem2D.transformacaoPerspectiva funcaoPerspectiva, vetor2 dimsImage) : base(novasDims, location) { // inicializa a fonte para ser escrito letras de identificação, como uma fonte do tipo padrão, this.fonteGzimo = new Font(FontFamily.Families[0].Name, 15); this.locTransparentPlanesAndLegends = new PointF(this.locTransparentPlanesAndLegends.X + (float)dimsImage.X, this.locTransparentPlanesAndLegends.Y + (float)dimsImage.Y + 10); // guarda o ponteiro para a função de transformação de pontos 3D // para pontos 2D, utilizando a perspectiva isométrica ou geomé- // trica. this.perspectiva = funcaoPerspectiva; // set a posição do gzimo ante ao control pai. this.posicao = new PointF(location.X, location.Y); // seta a dimensão dos lados do Gzimo eixos. this.szLadoGzimo = sizeLadoGzimo; // seta a largura das linhas de desenho dos lados do Gzimo eixos. this.sizeLine = sizeLinha; // seta a propriedade de perspectiva (fator de divisão da cordenada de profundidade). this.fatorPerspectiva = _fatorPerspectiva; // inicializa o menu para controle da funções do Gzimo eixos. //*************************************************************************************************** // INICIA A COMBO BOX PARA CONTROLES DE ROTAÇÃO, FIXAÇÃO E REDIMENSIONAMENTO DO GZIMO CURRENTE. cmbBxControlesGzimoEixos = new ComboBox(); // seta algumas propriedades do controle do Gzimo eixos. cmbBxControlesGzimoEixos.Size = new Size(200, 50); cmbBxControlesGzimoEixos.Visible = true; // localização física em relação ao contro pai, da list box de controles do gzimo. cmbBxControlesGzimoEixos.Location = new Point(5, (int)this.locTransparentPlanesAndLegends.Y + 45 + 20 + 40); // adiciona as opções de controle. cmbBxControlesGzimoEixos.Items.Add("fixar/desafixar posição do Gzimo"); cmbBxControlesGzimoEixos.Items.Add("+/- ângulo da base XZ"); cmbBxControlesGzimoEixos.Items.Add("+/- ângulo da base YZ"); cmbBxControlesGzimoEixos.Items.Add("+/- ângulo da base XY"); cmbBxControlesGzimoEixos.Items.Add("+/- ângulo base cords. cilíndricas"); cmbBxControlesGzimoEixos.Items.Add("+/- ângulo profundidade cords. cilíndricas"); cmbBxControlesGzimoEixos.Items.Add("+/- as dimensões do Gzimo"); // adciona o menu de controle para o control pai. pai.Controls.Add(cmbBxControlesGzimoEixos); // prepara a imagem do botão de acionamento do plano XY. btnPlanoXY = new Button(); btnPlanoXY.Size = new Size(45, 45); btnPlanoXY.Image = new Bitmap(45, 45); Graphics grphs1 = Graphics.FromImage(btnPlanoXY.Image); Color corQ1 = Color.FromArgb(35, Color.Red); grphs1.FillRectangle(new SolidBrush(corQ1), new RectangleF(0.0F, 0.0F, 45.0F, 45.0F)); // desenha as letras dentro dos retângulo colorido grphs1.DrawString("XY", this.fonteGzimo, new SolidBrush(corQ1), new PointF(13.0F, 10.0F)); btnPlanoXY.Location = new Point((int)this.locTransparentPlanesAndLegends.X + 45 * 0 + 0 * 3, (int)this.locTransparentPlanesAndLegends.Y + 40); // prepara a imagem do botão de acionamento do plano XZ. btnPlanoXZ = new Button(); btnPlanoXZ.Size = new Size(45, 45); btnPlanoXZ.Image = new Bitmap(45, 45); Graphics grphs2 = Graphics.FromImage(btnPlanoXZ.Image); corQ1 = Color.FromArgb(35, Color.Green); grphs2.FillRectangle(new SolidBrush(corQ1), new RectangleF(0.0F, 0.0F, 45.0F, 45.0F)); // desenha as letras dentro dos retângulo colorido grphs2.DrawString("XZ", this.fonteGzimo, new SolidBrush(corQ1), new PointF(13.0F, 10.0F)); btnPlanoXZ.Location = new Point((int)this.locTransparentPlanesAndLegends.X + 45 * 1 + 1 * 3, (int)this.locTransparentPlanesAndLegends.Y + 40); // prepara a imagem do botão de acionamento do plano YZ. btnPlanoYZ = new Button(); btnPlanoYZ.Size = new Size(45, 45); btnPlanoYZ.Image = new Bitmap(45, 45); Graphics grphs3 = Graphics.FromImage(btnPlanoYZ.Image); corQ1 = Color.FromArgb(35, Color.Blue); grphs3.FillRectangle(new SolidBrush(corQ1), new RectangleF(0.0F, 0.0F, 45.0F, 45.0F)); // desenha as letras dentro dos retângulo colorido grphs3.DrawString("YZ", this.fonteGzimo, new SolidBrush(corQ1), new PointF(13.0F, 10.0F)); btnPlanoYZ.Location = new Point((int)this.locTransparentPlanesAndLegends.X + 45 * 2 + 2 * 3, (int)this.locTransparentPlanesAndLegends.Y + 40); btnPlanoXY.Click += btnPlanoXY_Click; btnPlanoXZ.Click += btnPlanoXZ_Click; btnPlanoYZ.Click += btnPlanoYZ_Click; pai.Controls.Add(btnPlanoXY); pai.Controls.Add(btnPlanoXZ); pai.Controls.Add(btnPlanoYZ); ToolTip toolPlanoXY = new ToolTip(); ToolTip toolPlanoXZ = new ToolTip(); ToolTip toolPlanoYZ = new ToolTip(); toolPlanoXY.SetToolTip(this.btnPlanoXY, "Clique para abilitar a rotação apenas o plano XY do cursor"); toolPlanoXZ.SetToolTip(this.btnPlanoXZ, "Clique para abilitar a rotação apenas o plano XZ do cursor"); toolPlanoYZ.SetToolTip(this.btnPlanoYZ, "Clique paa habilitar a rotação apenaso plano YZ' do cursor"); this.containerPai = pai; //********************************************************************************************************* // constrói o Gzimo eixos. this.constroiGzimo(); } // GzimoEixos()
/// <summary> /// rotaciona uma imagem nos eixos X e Y por um angulo, /// sendos os eixos retirados a partir de marcação numa imagem. /// </summary> /// <param name="cena">Imagem a ser rotacionada.</param> /// <param name="angle">angulo em graus para o qual os eixos X e Y serem transformados.</param> /// <param name="eixoX_2D">eixo X conseguido através de marcação na imagem.</param> /// <param name="eixoY_2D">eixo Y conseguido através de marcação na imagem.</param> /// <param name="dimCell">dimensões da imagem final, já processada.</param> /// <returns>retorna uma imagem rotacionada pelo angulo em graus [angle], aplicado em eixos X e Y, /// transformados para (1,0) e (0,1).</returns> public static Bitmap rotacionaImagemComDoisEixos2D(Bitmap cena, double[] angle, vetor2 eixoX_2D, vetor2 eixoY_2D, Size dimCell) { if (cena == null) { throw new Exception("erro no metodo rotacionaImagemComUmEixo2D(), imagem currente e' nula"); } // inicializa o eixo X, a partir do eixoX_2D, que é um eixo X aparente, conseguido com marcação na imagem. vetor2 ex = new vetor2(eixoX_2D.X, eixoX_2D.Y); // inicializa o eixo Y, a partir do eixoY_2D, que é um eixo Y aparente, conseguido com marcação na imagem. vetor2 ey = new vetor2(eixoY_2D.X, eixoY_2D.Y); // normaliza o eixo X [ex]. ex = vetor2.normaliza(ex); // normaliza o eixo Y [ey]. ey = vetor2.normaliza(ey); // constrói o eixo X como uma matriz [1,2]. MATRIZES.Matriz mtEixoX = new MATRIZES.Matriz(1, 2); mtEixoX.setElemento(0, 0, ex.X); mtEixoX.setElemento(0, 1, ex.Y); // constrói o eixo Y como uma matriz [1,2]. MATRIZES.Matriz mtEixoY = new MATRIZES.Matriz(1, 2); mtEixoY.setElemento(0, 0, ey.X); mtEixoY.setElemento(0, 1, ey.Y); // constroi a matriz de transformação (dos eixos construídos para os eixos (1,0) e (0,1). MATRIZES.Matriz mtrzTransf = new MATRIZES.Matriz(2, 2); mtrzTransf.setElemento(0, 0, ex.X); mtrzTransf.setElemento(0, 1, ex.Y); mtrzTransf.setElemento(1, 0, ey.X); mtrzTransf.setElemento(1, 1, ey.Y); // calcula a matriz inversa de transformação. MATRIZES.Matriz mtrzTransfInversa = MATRIZES.Matriz.MatrizInversa(mtrzTransf); // multiplica a matriz do eixo X pela matriz inversa de transformação. MATRIZES.Matriz mtEixoXTransformado = mtEixoX * mtrzTransfInversa; MATRIZES.Matriz mtEixoYTransformado = mtEixoY * mtrzTransfInversa; // rotaciona o eixo X transformado, com o ângulo 0. mtEixoXTransformado = angulos.rotacionaVetor(angle[0], mtEixoXTransformado); // rotaciona o eixo Y transformado, com o ângulo 1. mtEixoYTransformado = angulos.rotacionaVetor(angle[1], mtEixoYTransformado); // mutliplica os eixos X e Y pela matriz de transformação, retornando para o universo 2D inicial. mtEixoXTransformado = mtEixoXTransformado * mtrzTransf; mtEixoYTransformado = mtEixoYTransformado * mtrzTransf; // converte a matriz do eixo X para um [vetor2]. vetor2 eixoXFinal = new vetor2((double)mtEixoXTransformado.getElemento(0, 0), (double)mtEixoXTransformado.getElemento(0, 1)); // converte a matriz do eixo Y para um [vetor2]. vetor2 eixoYFinal = new vetor2((double)mtEixoYTransformado.getElemento(0, 0), (double)mtEixoYTransformado.getElemento(0, 1)); // normaliza os eixos finais. eixoXFinal = vetor2.normaliza(eixoXFinal); eixoYFinal = vetor2.normaliza(eixoYFinal); // retorna uma Imagem construida com os eixos finais. return(new Bitmap(aplicaEixos(cena, eixoXFinal, eixoYFinal, dimCell), dimCell)); } // rotacionaImagemComDoisEixos2D()
} // rotacionaMatriz3D() /// <summary> /// constrói a matriz 3D associado à imagem 2D de entrada. /// </summary> /// <param name="eixoX">eixo X, imaginado com o gzimo eixos.</param> /// <param name="eixoY">eixo Y, imaginado com o gzimo eixos.</param> /// <param name="eixoZ">eixo Z, imaginado com o gzimo eixos.</param> /// <param name="isUsaEixoZCalculado">calcula o eixo Z, se [true];</param> /// <param name="profundidadeObjeto">cumprimento no eixo Z da matriz 3D.</param> /// <param name="fatorPerspectiva">parâmetro de cálculo da perspectiva (isométrica ou geométrica).</param> /// <param name="funcPerspectiva">método a ser utilizada na perspectiva (isométrica ou geométrica).</param> /// <param name="msgErro">string guardando mensagens de erro geradas pelo método.</param> public void iniciaMatriz3D( vetor3 eixoX, vetor3 eixoY, vetor3 eixoZ, Bitmap cena, double profundidadeObjeto, double fatorPerspectiva, Matriz3DparaImagem2D.transformacaoPerspectiva funcPerspectiva, ref string msgErro) { this.isMatrizJaGerada = true; int x, y, z; vetor2 v2_0 = new vetor2(0.0, 0.0); try { Rectangle rectOldBordas = new Rectangle(0, 0, cena.Width, cena.Height); this.matrix = new vetor3[cena.Width, cena.Height, (int)profundidadeObjeto]; xmin = 100000.0; ymin = 100000.0; // calcula o ponto mínimo (xmin,ymin) for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { // inicia o ponto 3D. matrix[x, y, z] = new vetor3(x, y, z); vetor3 v3_0 = new vetor3(matrix[x, y, z]); v3_0.multiplicaPorUmaBase(eixoX, eixoY, eixoZ); v2_0 = funcPerspectiva(v3_0, fatorPerspectiva); if (v2_0.X < xmin) { xmin = v2_0.X; } if (v2_0.Y < ymin) { ymin = v2_0.Y; } } // for z } } // faz a ida, calculando o ponto 3D e através da perspectiva neste ponto, calcula a cor da imagem neste ponto 3D. for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { vetor3 v3_0 = new vetor3(matrix[x, y, z]); v3_0.multiplicaPorUmaBase(eixoX, eixoY, eixoZ); // calcula a perspectiva sobe o ponto 3D. v2_0 = funcPerspectiva(v3_0, fatorPerspectiva); if (((v2_0.X - xmin) < cena.Width) && ((v2_0.Y - ymin) < cena.Height) && ((v2_0.X - xmin) >= 0) && ((v2_0.Y - ymin) >= 0)) { Color cor = cena.GetPixel((int)(v2_0.X - xmin), (int)(v2_0.Y - ymin)); matrix[x, y, z].cor = cor; } // if } // for z } } } // try catch (Exception ex) { msgErro = "Erro ao iniciar o objeto 3D associado à imagem de entrada. Mensagem de erro: " + ex.Message; } // catch } // iniciaMatriz3D()
} // modificaRaioGzimo() /// <summary> /// converte um vetor 2D em um PointF. /// </summary> /// <param name="v">vetor 2D a ser convertido.</param> /// <returns>retorna um PointF com as cordenadas do vetor 2D.</returns> /// <param name="offsetPos">offset de deslocamento a ser colocado, útil quando a vetor 2D faz uma base ortonormal.</param> private PointF vetor2ToPointF(vetor2 v, PointF offsetPos) { return(new PointF((float)(v.X + offsetPos.X), (float)(v.Y + offsetPos.Y))); } // vetor2ToPointF()
} // constroiMatriz3D() /// <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 cubo.</param> /// <param name="eixoY">eixo Y 3D calculado com ferramentas como o gzimo cubo.</param> /// <param name="eixoZ">eixo Z 3D calculado com ferramentas como o gzimo cubo.</param> /// <param name="cena">imagem a ser processada.</param> /// <param name="fatorPerspetivaIsometrica">fator de divisão do eixo projetado para formar o eixo 2D.</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> /// public Bitmap rotacionaMatriz3D(vetor3 eixoX, vetor3 eixoY, vetor3 eixoZ, Bitmap cena, double fatorPerspetivaIsometrica, double profundidadeObjeto, double anguloXYEmGraus, double anguloYZEmGraus, double anguloXZEmGraus, ref string msgErro) { try { int x, y, z; for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { matrix[x, y, z] = new vetor3(x, y, z); vetor2 v2 = matrix[x, y, z].transformacaoPerspecctivaIsometrica(fatorPerspetivaIsometrica); Color cor = cena.GetPixel((int)v2.X, (int)v2.Y); matrix[x, y, z].cor = cor; } // for z } } eixoZ = eixoX & eixoY; eixoX.normaliza(); eixoY.normaliza(); eixoZ.normaliza(); eixoX.rotacionaVetorComPlanos(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); eixoY.rotacionaVetorComPlanos(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); eixoZ.rotacionaVetorComPlanos(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { matrix[x, y, z].multiplicaPorUmaBase(eixoX, eixoY, eixoZ); } } } vetor3 dims3 = new vetor3(cena.Width, cena.Height, profundidadeObjeto); vetor2 dims2 = dims3.transformacaoPerspecctivaIsometrica(fatorPerspetivaIsometrica); Bitmap cenaRotacionada = new Bitmap((int)dims2.X, (int)dims2.Y); Rectangle rectBordas = new Rectangle(0, 0, cenaRotacionada.Width, cenaRotacionada.Height); for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { vetor2 v2_0 = matrix[x, y, z].transformacaoPerspecctivaIsometrica(fatorPerspetivaIsometrica); if (this.validaVetor2(rectBordas, v2_0)) { cenaRotacionada.SetPixel((int)v2_0.X, (int)v2_0.Y, matrix[x, y, z].cor); } } //for z } } return(cenaRotacionada); } // try catch (Exception ex) { msgErro = "Erro no processamento da imagem a ser rotacionada em 3D. Motivo: " + ex.Message; return(null); } // catch } // constroiMatriz3D()
} // constroiMatriz3D() /// <summary> /// verifica se o vetor 2D está contido no Rectângulo 2D parâmetro. /// </summary> /// <param name="rect">rectângulo parâmetro.</param> /// <param name="v">vetor 2D a ser verificado se está contido.</param> /// <returns>retorna [true] se o vetor está contido, retorna [false] /// se o vetor não está contido pelo retângulo.</returns> bool validaVetor2(Rectangle rect, vetor2 v) { return((v.X >= rect.X) && (v.X < (rect.X + rect.Width)) && (v.Y >= rect.Y) && (v.Y < (rect.Y + rect.Height))); }
/// <summary> /// constroi uma lista de vetores 3D a partir de uma imagem em perspectiva isométrica, e alguns parâmetros. /// </summary> /// <param name="eixo2DX">vetor 2D representando o eixo X.</param> /// <param name="eixo2DZ">vetor 2D representando o eixo Z (profundidade)</param> /// <param name="cena">imagem a ser processada para gerar a lista de vetores 3D.</param> /// <param name="fatorPerspetivaIsometrica">fator de compactação para gerar as cordenadas 2D isométricas.</param> /// <param name="profundidadeImaginada">altura imaginária da imagem 3D.</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 que surgirem no processamento da imagem a ser rotacionada.</param> /// <returns></returns> public Bitmap rotacionaMatriz3D(vetor2 eixo2DX, vetor2 eixo2DY, Bitmap cena, double fatorPerspetivaIsometrica, int profundidadeImaginada, double anguloXYEmGraus, double anguloYZEmGraus, double anguloXZEmGraus, ref string msgErro) { try { this.matrix = new vetor3[cena.Width + 6, cena.Height + 6, profundidadeImaginada + 5]; vetor3 eixoX = new vetor3(0.0, 0.0, 0.0); vetor3 eixoY = new vetor3(0.0, 0.0, 0.0); vetor3 eixoZ = new vetor3(0.0, 0.0, 0.0); int x, y, z; for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { matrix[x, y, z] = new vetor3(x, y, z); vetor2 v2 = matrix[x, y, z].transformacaoPerspecctivaIsometrica(fatorPerspetivaIsometrica); Color cor = cena.GetPixel((int)v2.X, (int)v2.Y); matrix[x, y, z].cor = cor; if (v2.Equals(eixo2DX)) { eixoX = new vetor3(matrix[x, y, z]); } if (v2.Equals(eixo2DY)) { eixoY = new vetor3(matrix[x, y, z]); } } // for z } } eixoZ = eixoX & eixoY; eixoX.normaliza(); eixoY.normaliza(); eixoZ.normaliza(); eixoX.rotacionaVetorComPlanos(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); eixoY.rotacionaVetorComPlanos(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); eixoZ.rotacionaVetorComPlanos(anguloXZEmGraus, anguloYZEmGraus, anguloXYEmGraus); for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { matrix[x, y, z].multiplicaPorUmaBase(eixoX, eixoY, eixoZ); } } } vetor3 dims3 = new vetor3(cena.Width, cena.Height, profundidadeImaginada); vetor2 dims2 = dims3.transformacaoPerspecctivaIsometrica(fatorPerspetivaIsometrica); Bitmap cenaRotacionada = new Bitmap((int)dims2.X, (int)dims2.Y); for (x = 0; x < matrix.GetLength(0); x++) { for (y = 0; y < matrix.GetLength(1); y++) { for (z = 0; z < matrix.GetLength(2); z++) { vetor2 v2_0 = matrix[x, y, z].transformacaoPerspecctivaIsometrica(fatorPerspetivaIsometrica); cenaRotacionada.SetPixel((int)v2_0.X, (int)v2_0.Y, matrix[x, y, z].cor); } //for z } } return(cenaRotacionada); } // try catch (Exception ex) { msgErro = "Erro no processamento da imagem a ser rotacionada. Motivo: " + ex.Message; return(null); } } // constroiMatriz3D()