/// <summary> /// constutor. /// </summary> /// <param name="cena">Imagem para ser processada neste control (retirada dos eixos 2D).</param> /// <param name="location">Parâmetro de posição do canto superior esquerdo do control.</param> /// <param name="pai">control que servirá de container para o control currente.</param> ///<param name="tamanhoGzimo">determina as dimensões do Gzimo.</param> ///<param name="tamanhoImagens">estabelece o tamanho de cada imagem adicionada ao control</param> /// <param name="typeGzm">tipo de cursor especial que age sobre o control</param> /// <param name="extensionSize">número para aumento da área de atuação do control currente.</param> /// <param name="fatorIsometrico">fator de divisão do eixo 3D que é projetado nos eixos 2D.</param> /// <param name="tipoPerspectiva">tipo de perspectiva [true]: isométrica, [false]: geométrica.</param> public usrCtrBxDeterminaEixos(Bitmap _cena, PointF location, Control pai, Size tamanhoGzimo, Size tamanhoImagens, double fatorIsometrico, bool tipoPerspectiva) { if (tipoPerspectiva) { this.perspectiva = vetor3.transformacaoPerspectivaIsometrica; } else { this.perspectiva = vetor3.transformacaoPerspectivaGeometrica; } this.fatorIso = fatorIsometrico; this.perspectivaIsometrica = tipoPerspectiva; this.typeAngleForRotationGzimo = vetor3.tipoAngulo.Relativo; this.Location = new Point((int)location.X, (int)location.Y); this.cena = new Bitmap(_cena); this.lstBasesGuardadas = new List <vetor3[]>(); this.cmBxBasesGuardadas = new ComboBox(); posicaoCursor = new PointF(location.X, location.Y); Matriz3DparaImagem2D.transformacaoPerspectiva perspectiva = null; if (tipoPerspectiva) { perspectiva = vetor3.transformacaoPerspectivaIsometrica; } else { perspectiva = vetor3.transformacaoPerspectivaGeometrica; } this.gzimosCurrentes = new GzimoEixos[1]; //________________________________________________________________________________________________________________________ // incializa a imagem que guardará tudo para ser desenhado neste control. cenaInteira = new Bitmap((int)(this.cena.Width * 4.0), (int)(this.cena.Height * 4.0)); //_________________________________________________________________________________________________________________________ // seta o ponteiro de função de evento de girar a roda do mouse. this.MouseWheel += usrCtrBxDeterminaEixos_MouseWheel; // seta o ponteiro de função de eventos de clicar com o mouse sobre o control. this.MouseDown += usrCtrBxDeterminaEixos_MouseWheel; // adiciona o control à window pai. pai.Controls.Add(this); // calcula o tamanho do current control. this.Size = new Size(this.cenaInteira.Width + 20, this.cenaInteira.Height + 20); // seta o control container. this.controlContainer = pai; // redesenha o control. this.Refresh(); }
} // 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()
} // constroi Gzimo. /// <summary> /// desenha Gzimo em cruz. /// </summary> /// <param name="g">dispositivo de imagem a ser utilizado.</param> /// <param name="cor">cor do Gzimo.</param> public override void drawGzimo(Graphics g, Color cor, Matriz3DparaImagem2D.transformacaoPerspectiva perspectiva) { //___________________________________________________________________________________ // calcula os pontos que serão utilizados no desenho do Gzimo. PointF ini1 = new PointF((float)(xi + posicao.X - szNovo.Width / 2), (float)(yi + posicao.Y - szNovo.Height / 2)); PointF fini1 = new PointF((float)(posicao.X + xm1 - szNovo.Width / 2), (float)(posicao.Y + ym1 - szNovo.Height / 2)); PointF ini2 = new PointF((float)(xm2 + posicao.X - szNovo.Width / 2), (float)(ym2 + posicao.Y - szNovo.Height / 2)); PointF fini2 = new PointF((float)(posicao.X + xf - szNovo.Width / 2), (float)(posicao.Y + yf - szNovo.Height / 2)); //_______________________________________________________________________________________ // seleciona um pincel com cor [cor] e grossura do pincel 3.5F Pen pincel = new Pen(cor, 3.5F); // desenha o Gzimo. g.DrawLine(pincel, ini1, fini1); g.DrawLine(pincel, ini2, fini2); } // drawGzimo()
} // 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()
} // Gzimo() /// <summary> /// método virtual, deve ser substituído. Se não for substituído, será /// lançado uma exception. /// </summary> /// <param name="g">disposito gráfico para desenho do Gzimo.</param> /// <param name="cor">cor do Gzimo.</param> public virtual void drawGzimo(Graphics g, Color cor, Matriz3DparaImagem2D.transformacaoPerspectiva perspectiva) { throw new Exception("Método não implementado!"); } // void drawGzimo()
} // vetor2ToPointF() /// <summary> /// desenha num dispositivo gráfico o Gzimo na forma de um eixos, /// para auxiliar as rotações. /// </summary> /// <param name="g">dispositivo gráfico para desenho.</param> /// <param name="cor">cor do Gzimo.</param> /// <param name="perspectiva">ponteiro para função de cálculo da perspectiva.</param> public override void drawGzimo(Graphics g, Color cor, Matriz3DparaImagem2D.transformacaoPerspectiva perspectiva) { // desenho ds plano XZ no gzimo. if (this.showPlanoXZ) { this.drawATransparentPlane(new Point((int)this.locTransparentPlanesAndLegends.X + 45 * 0 + 0 * 3, (int)this.locTransparentPlanesAndLegends.Y), g, Color.FromArgb(35, Color.Green), new vetor2(this.posicao.X, this.posicao.Y), 6, 2, 3, 7); } // desenho do plano YZ no gzimo. if (this.showPlanoYZ) { this.drawATransparentPlane(new PointF((int)this.locTransparentPlanesAndLegends.X + 45 * 1 + 1 * 3, (int)this.locTransparentPlanesAndLegends.Y), g, Color.FromArgb(35, Color.Blue), new vetor2(this.posicao.X, this.posicao.Y), 6, 2, 0, 4); } // desenho do plano XY no gzimo. if (this.showPlanoXY) { this.drawATransparentPlane(new PointF((int)this.locTransparentPlanesAndLegends.X + 45 * 2 + 2 * 3, (int)this.locTransparentPlanesAndLegends.Y), g, Color.FromArgb(35, Color.Red), new vetor2(this.posicao.X, this.posicao.Y), 2, 3, 1, 0); } // desenha a legenda de orientaçâo do gzimo. this.drawLegend(g, new vetor2(this.locTransparentPlanesAndLegends.X - 45 - 20, this.locTransparentPlanesAndLegends.Y + 45 + 20), new vetor3(0.0, 0.0, 0.0)); Pen pincel = new Pen(cor, (float)this.sizeLine); for (int x = 0; x < this.indicesPontosCordsGzimoEixos.Count; x++) { // destaca o ponto que representa o eixo Z. if ((indicesPontosCordsGzimoEixos[x][0] == 0) || (indicesPontosCordsGzimoEixos[x][1] == 0)) { pincel.Color = Color.Blue; } else { // destaca os pontos que se ligam até a origem dos eixos do Gzimo eixos. if ((this.indicesPontosCordsGzimoEixos[x][0] == 6) || (this.indicesPontosCordsGzimoEixos[x][1] == 6)) { if ((indicesPontosCordsGzimoEixos[x][0] == 4) || (indicesPontosCordsGzimoEixos[x][1] == 4)) { pincel.Color = Color.Red; } if ((indicesPontosCordsGzimoEixos[x][0] == 7) || (indicesPontosCordsGzimoEixos[x][1] == 7)) { pincel.Color = Color.Green; } if ((indicesPontosCordsGzimoEixos[x][0] == 2) || (indicesPontosCordsGzimoEixos[x][1] == 2)) { pincel.Color = Color.Blue; } } // if indicesPontosCordsGzimoEixos[x][0]==0 else { // partes do eixos que não são eixos pincel.Color = cor; } // else } // else if (((this.indicesPontosCordsGzimoEixos[x][0] == 6) || (this.indicesPontosCordsGzimoEixos[x][1] == 6)) && ((this.indicesPontosCordsGzimoEixos[x][0] == 4) || (this.indicesPontosCordsGzimoEixos[x][1] == 4) || (this.indicesPontosCordsGzimoEixos[x][0] == 7) || (this.indicesPontosCordsGzimoEixos[x][1] == 7) || (this.indicesPontosCordsGzimoEixos[x][0] == 2) || (this.indicesPontosCordsGzimoEixos[x][1] == 2))) { // inicializa os vetores para desenho. vetor3 v3_0 = new vetor3(this.cordsGzimoEixos[indicesPontosCordsGzimoEixos[x][0]]); vetor3 v3_1 = new vetor3(this.cordsGzimoEixos[indicesPontosCordsGzimoEixos[x][1]]); // multiplica os vetores para desenho pela base ortonormal currente. v3_0.multiplicaPorUmaBase(this.eixoXGzimo, this.eixoYGzimo, this.eixoZGzimo); v3_1.multiplicaPorUmaBase(this.eixoXGzimo, this.eixoYGzimo, this.eixoZGzimo); // desenha a linha entre os vetores para desenho. this.drawLinePerspective(g, v3_0, v3_1, pincel); } // if } // for x pincel.Dispose(); } // void DrawGzimo().
/// <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()