Escalonar Polígonos

Fala galera. Seguinte, no meu programa eu to colocando agora a opção de trocar a resolução das imagens editadas. Só que, para tanto, eu tenho que pegar cada desenho feito modificar sua a localidade das extremidades. Consegui fazer funcionar muito bem com retângulos, círculos e até linhas livres, mas com polígonos não tá dando muito certo. acompanhem o código.

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setFimX(int)
	 */
	@Override
	public Desenho setFimX(int fimX) {
		// TODO Auto-generated method stub
		if(fimX != this.getFimX()){
			int origem = this.getOrigemX();
			float escala = (fimX - this.getOrigemX()) /(float)this.poligono.getBounds().width;
			AffineTransform af = new AffineTransform();
			af.setToTranslation(-this.getOrigemX(),0);
			modificaPoligono(af);
			af.setToScale(escala,1);
			modificaPoligono(af);
			af.setToTranslation(origem,0);
			modificaPoligono(af);
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setFimY(int)
	 */
	@Override
	public Desenho setFimY(int fimY) {
		// TODO Auto-generated method stub
		if(fimY != this.getFimY()){
			int origem = this.getOrigemY();
			float escala = (fimY - this.getOrigemY()) /(float)this.poligono.getBounds().height;
			AffineTransform af = new AffineTransform();
			af.setToTranslation(0, -this.getOrigemY());
			modificaPoligono(af);
			af.setToScale(1,escala);
			modificaPoligono(af);
			af.setToTranslation(0, origem);
			modificaPoligono(af);
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setOrigemX(int)
	 */
	@Override
	public Desenho setOrigemX(int origemX) {
		// TODO Auto-generated method stub
		if(origemX != this.getOrigemX()){
			float escala = (this.getFimX() - origemX) /(float)this.poligono.getBounds().width;
			AffineTransform af = new AffineTransform();
			af.setToTranslation(-this.getOrigemX(),0);
			modificaPoligono(af);
			af.setToScale(escala,1);
			modificaPoligono(af);
			af.setToTranslation(origemX,0);
			modificaPoligono(af);
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setOrigemY(int)
	 */
	@Override
	public Desenho setOrigemY(int origemY) {
		// TODO Auto-generated method stub
		if(origemY != this.getOrigemY()){
			float escala = (this.getFimY() - origemY) /(float)this.poligono.getBounds().height;
			AffineTransform af = new AffineTransform();
			af.setToTranslation(0,-this.getOrigemY());
			modificaPoligono(af);
			af.setToScale(1,escala);
			modificaPoligono(af);
			af.setToTranslation(0,origemY);
			modificaPoligono(af);
		}
		return this;
	}

	/**
	 * Modifica o polígono conforme a matriz de tranformação fornecida
	 * @param af
	 */
	private void modificaPoligono(AffineTransform af) {
		if(this.geraPoligono().npoints > 0){
		List<Point2D> pontos = new ArrayList<Point2D>();
		for(int i =0; i < this.geraPoligono().npoints;i++){
			pontos.add(af.transform(new Point(this.geraPoligono().xpoints[i], this.geraPoligono().ypoints[i]),null));
		}
		this.geraPoligono().reset();
		for (Point2D point : pontos) {
			this.acrescentaExtremo((int)point.getX(), (int)point.getY());
		}
		}else{
			for (Line2D linha : this.linhas) {
				linha.getP1().setLocation(af.transform(linha.getP1(), null));
				linha.getP2().setLocation(af.transform(linha.getP2(), null));
			}
		}
		
	}

Onde polígono é do tipo Polygon mesmo e linhas é uma list do tipo Line2D, onde as extremidades dessas linhas formas as bordas dos polígono(isso não pode ser alterado facilmente).

Então, conseguem perceber algum erro ai? Qualquer coisa serve. Agradeço desde já.

Não basta só mudar o AffineTransform do Graphics2D no início e então redesenhar tudo?

Uma dúvida. Seu editor é vetorial ou por pixel? Também estou fazendo um editor, mas ele é mais no estilo Photoshop, com filtros e tudo mais.

O problema é que daí os novos desenhos que eu acrescentasse também seriam escalonados. A única forma de isso funcionar é se cada desenho tivesse seu affine transform associado(Hum…).

Eu queria optar por modificar os desenhos logo por que assim eu economizaria processamento. Eu sei que não consome tanto assim fazer uma mudança de coordenadas boba, mas eu não posso me arriscar com java, já conhecido pelo seu desempenho relativamente baixo em CG.

É por isso também que aquela solução que tu colocou lá sobre rotacionar textos em outro tópico pode não funcionar pra mim, pois lá o contexto é modificado, e eu queria modificar o texto mesmo, talzez através de algum método, sei lá.

É um editor por pixel ainda, mas como todas as formas e textos ficam na memória do programa, nada impede que no futuro eu implemente um exportador ou importador vetorial. Mas como meu editor ainda não tem nem uma forma de criar curvas simples ainda, isso vai ter que espera um pouco.

E esse seu editor que você tá criando, vai ser algo comercial, livre mesmo, online pra usuários pagantes? Já tá a que pé? Você conseguiu fazer a ferramenta de zoom funcionar bem? pois a minha tá com um problema por causa do Viewport que fica mudando de tamanho, aí eu não consigo manter o usuário na região onde ele deu o zoom. Alguma dica pra isso talvez?

Minha ferramenta não é open source. É só para uso pessoal, para meus estudos no mestrado.

Se quiser dar uma olhada:
http://dl.dropbox.com/u/8258820/Imagem.zip

Não acho má idéia cada desenho ter sua transformação associada. Pelo menos isso é bem comum nas aplicações vetoriais que já trabalhei.
Você pode usar o método create() do Graphics2D para implementar o conceito de pilhas de transformações e de grafo de cena.

Pilha de tranformação??? Grafo de Cena??? Existe essas coisa? Tsc, quando eu pensei que já sabia bastante de CG…

Bem, vou continuar insistindo por enquanto, acho que meu erro pode estar em ficar usando inte no lugar de float pra coordenadas. Se não isso, depois vejo o que faço.

Mudando de assunto, muito legal tua ferramenta. até pensei em usar internalframes também, mas vi umas dificuldades que tiraram meu ânimo.

De toda forma, se alguém tiver outra sugestão, to no aguardo aí, viu galera?

Eu estudo CG há pelo menos 8 anos, e ainda acho que sei pouco. Tem muita, muita, muita, muita coisa para conhecer… heheheheh

Galera acabei por descobrir que meu erro estava em vários lugares.

Primeiro, eu não deveria usar o método getBounds() quando eu tenho um método getLargura() e getAltura() na minha classe.

O segundo erro é que quando eu usava o getP1() e o alterava, eu não alterava a linha junto. Entendam, o método getP1() retorna um ponto que é independente da linha em que ele estava, então os procedimentos em 95 e 96 eram inúteis. Tinha outros erros também, mais eles não aparecem no trecho de código postado. Vejam como ficou a versão final:

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setFimX(int)
	 */
	@Override
	public Desenho setFimX(int fimX) {
		// TODO Auto-generated method stub
		if(fimX != this.getFimX()){
			int origem = this.getOrigemX();
			float escala = (fimX - this.getOrigemX()) /(float)this.getLargura();
			AffineTransform af = new AffineTransform();
			af.setToTranslation(-this.getOrigemX(),0);
			modificaPoligono(af);
			af.setToScale(escala,1);
			modificaPoligono(af);
			af.setToTranslation(origem,0);
			modificaPoligono(af);
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setFimY(int)
	 */
	@Override
	public Desenho setFimY(int fimY) {
		// TODO Auto-generated method stub
		if(fimY != this.getFimY()){
			int origem = this.getOrigemY();
			float escala = (fimY - this.getOrigemY()) /(float)this.getAltura();
			AffineTransform af = new AffineTransform();
			af.setToTranslation(0, -this.getOrigemY());
			modificaPoligono(af);
			af.setToScale(1,escala);
			modificaPoligono(af);
			af.setToTranslation(0, origem);
			modificaPoligono(af);
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setOrigemX(int)
	 */
	@Override
	public Desenho setOrigemX(int origemX) {
		// TODO Auto-generated method stub
		if(origemX != this.getOrigemX()){
			float escala = (this.getFimX() - origemX) /(float)this.getLargura();
			AffineTransform af = new AffineTransform();
			af.setToTranslation(-this.getOrigemX(),0);
			modificaPoligono(af);
			af.setToScale(escala,1);
			modificaPoligono(af);
			af.setToTranslation(origemX,0);
			modificaPoligono(af);
		}
		return this;
	}

	/* (non-Javadoc)
	 * @see br.ericware.desenhos.Desenho#setOrigemY(int)
	 */
	@Override
	public Desenho setOrigemY(int origemY) {
		// TODO Auto-generated method stub
		if(origemY != this.getOrigemY()){
			float escala = (this.getFimY() - origemY) /(float)this.getAltura();
			AffineTransform af = new AffineTransform();
			af.setToTranslation(0,-this.getOrigemY());
			modificaPoligono(af);
			af.setToScale(1,escala);
			modificaPoligono(af);
			af.setToTranslation(0,origemY);
			modificaPoligono(af);
		}
		return this;
	}

	/**
	 * Modifica o polígono conforme a matriz de tranformação fornecida
	 * @param af
	 */
	private void modificaPoligono(AffineTransform af) {
		if(this.geraPoligono().npoints > 0){
		List<Point2D> pontos = new ArrayList<Point2D>();
		for(int i =0; i < this.geraPoligono().npoints;i++){
			pontos.add(af.transform(new Point(this.geraPoligono().xpoints[i], this.geraPoligono().ypoints[i]),null));
		}
		this.geraPoligono().reset();
		for (Point2D point : pontos) {
			this.acrescentaExtremo((int)point.getX(), (int)point.getY());
		}
		}else{
			for (Line2D linha : this.linhas) {
				linha.setLine(af.transform(linha.getP1(), null), af.transform(linha.getP2(), null));
			}
		}
		
	}

O pior é que eu descobri que quando eu escalono as linhas, elas não ficam juntas dando aquele efeito de preenchimento, ou seja, eu dancei de novo. Mas, pra quem tiver um problema por aí, fica a dica.