Salve Galera!
Estou estudando Graphics2D e estou com uma dúvida.
Quero setar o AffineTransform() do contexto grafico de um JPanel, e inverter o eixo “Y”.
Ou seja, quero por exemplo, que o “x=0” e “y=0”, fique no canto inferior esqeurdo da tela, sacaram? E qualquer coisa que eu quera desenhar deste contexto gráfico e aumentar o valor de “Y”, o desenho fique mais alto na tela.
Não tenho certeza se é na cassle “AffineTransform()” que faz isso, mas…
Esquero que eu me fiz entender, rsrs.
Agradeço a atenção.
A classe affine transform é até capaz de tudo isso que você quer sim, mas primeiro você precisa entender que affine tranform nada mais é que uma matriz de mudança de coordenada, então pra apreender a mexer com ela, primeiro tem que apreender o que é mudança de coordena e o como usar uma matriz para executar uma mudança de coordenada em duas dimensões. Como eu aprendi tudo na faculdade em posso te ajudar muito:P
Para entender como o AffineTransform funciona leia:
http://pontov.com.br/site/arquitetura/54-matematica-e-fisica/238-matrizes-e-transformacoes-parte-1
http://pontov.com.br/site/arquitetura/54-matematica-e-fisica/267-matrizes-e-transformacoes-parte-2
É possível inverter o sistema de coordenadas em y. Basta realizar uma escala de -1 nesse eixo e então uma translação do tamanho da tela para cima (não me recordo se o sistema de coordenadas do Java é o da mão direita ou esquerda, então, você terá que testar a ordem das transformações).
Como o Java não trabalha com o mapeamento da projeção, infelizmente essa transformação sempre será dependente do tamanho do canvas. =(
Obrigado elissonandrade, pela atenção.
ViniGodoy meu caro, o q me disse até funciona bem, mas veja um detalhes, tudo q eu desenho como Strings e bitmaps por exemplo, vai ser desenhado de pontacabeça…
Tem alguma maneira de configurar o que eu quero e ele continuar desenhando estes elementos normalmente???
Segue meu código:
package painelDesenho;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.NoninvertibleTransformException;
import javax.swing.JPanel;
public class PainelDesenho extends JPanel{
Shape forma;
AffineTransform at;
public PainelDesenho() {
GeneralPath p = new GeneralPath();
p.moveTo(0.0, 0.0);
p.lineTo(30.0, 0.0);
p.lineTo(38.0, 5.0);
p.lineTo(30.0, 10.0);
p.lineTo(10.0, 10.0);
p.lineTo(10.0, 30.0);
p.lineTo(5.0, 22.0);
p.lineTo(0.0, 30.0);
p.closePath();
this.forma = p;
this.at = new AffineTransform();
}
private void desenhaSimbolo(Graphics2D g){
g.setColor(Color.WHITE);
g.draw(this.forma);
g.drawString("[x]", 43, 8); // <--- O caracter "x" e "y", são desenhados de pontacabeça...!! :P
g.drawString("[y]", 0, 43); // <--- O caracter "x" e "y", são desenhados de pontacabeça...!! :P
// Logo, tudo q eu for desenhar como por exemplo, caracteres, bimaps, etc, será desenhado
// em potacabeça...! :P
}
private void preConfiguracao(Graphics2D g){
g.setColor(Color.GRAY);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
this.at.setToTranslation(this.getWidth()/2, this.getHeight()/2);
this.at.scale(1, -1);
g.setTransform(this.at);
}
@Override
public void paint(Graphics graphics) {
Graphics2D g = (Graphics2D) graphics.create();
this.preConfiguracao(g);
this.desenhaSimbolo(g);
g.dispose();
}
}
Acho que só criando sua própria versão do DrawString e mapeando manualmente as coordenadas.
Hehehehe, ok Vini, acho que ai complica as coisas, rsrsrs, mesmo assim eu agradeço.
Abraço!
Cara, acho que nem precisa de tudo isso não. draw string aceita um segundo argumento onde você pode colocar seu próprio affine tranform específico praquela string, daí você inverte sua string também e fica tudo certo.
Tem uma solução que já utilizei, não sei se é boa ou não para o seu caso… para meu projeto específico facilitou, mas fico com um pouco de vergonha de mostrar nesse tópico que tem gente que manja pra caramba de graficos… rsrs
Trata-se de ter um sistema de coordenadas “virtuais”, que tem o eixo y invertido e medidas lógicas fixas para x e y (por exemplo, um canvas de 1000 por 1000 unidades).
Guardo as coordenadas e dimensões dos objetos do modelo nesse sistema de coordenadas lógicas.
E existe um objeto responsável por converter esse sistema lógico para o sistema de coordenadas de tela. Ele calcula para cada ponto o valor correspondente, pois se mantém atualizado sobre as dimensões físicas do frame.
Facilita um pouco os cálculos de posicionamento, e vc ainda leva de graça a habilidade de mudar o tamanho da tela e as proporções de tamanho entre os objetos permanecerem iguais. A desvantagem é que os métodos de desenho ficam um pouco mais sujos, pois é preciso converter cada ponto:
Mais ou menos assim:
[code]// Traçando uma linha do meio para o canto superior direito da tela:
// Os pontos sao tratados no sistema de medidas lógico, uma area de 1000 por 1000 unidades.
Point meioDaTela = new Point(500,500);
Point superiorDireito = new Point(1000,1000);
// A referencia converter é o conversor entre sistemas de medida, e foi instanciado anteriormente com as
// medidas reais da tela.
Point meioDaTelaPhys = converter.toScreenCoordinates(meioDaTela);
Point superiorDireitoPhys = converter.toScreenCoordinates(superiorDireito);
g.drawLine(meioDaTelaPhys.x, meioDaTelaPhys.y, superiorDireitoPhys.x, superiorDireitoPhys.y);[/code]
gomesrod, cara! Gostei do seu jeito de pensar, tbm não sei se esta certo, mas vou refletir a respeito, gostei do lance que tu disse de redimensionar a tela, VALEU cara!
Para eu ter um parâmetro, o que vocês acharam da idéo do gomesrod ???