2009-03-27 9 views
6

私はAffineTransformを使用してその中心から矩形を拡大縮小しようとしています。私は解決策が明らかだと確信していますが、私はそれを動作させることはできません!ここまで私がこれまでテストしたことは...AffineTransform:中心からシェイプを拡大する

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.geom.AffineTransform; 

import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

public class Test extends JPanel { 
    Test() 
     { 
     super(null); 
     setOpaque(true); 
     setBackground(Color.WHITE); 
     setPreferredSize(new Dimension(200,200)); 
     } 
    @Override 
    protected void paintComponent(Graphics g1) { 
     super.paintComponent(g1); 
     Rectangle r= new Rectangle(5,5,getWidth()-10,getHeight()-10); 
     double cx= r.getCenterX(); 
     double cy= r.getCenterY(); 
     Graphics2D g=(Graphics2D)g1; 
     g.setColor(Color.BLACK); 
     AffineTransform old= g.getTransform(); 
     for(double zoom=0.9; zoom>=0.5; zoom-=0.1) 
      { 
      AffineTransform tr2= new AffineTransform(old); 
      tr2.translate(-cx, -cy); 
      tr2.scale(zoom, zoom); 
      tr2.translate(cx/zoom,cy/zoom); 
      g.setTransform(tr2); 
      g.draw(r); 
      g.setTransform(old); 
      } 
     } 


    public static void main(String[] args) { 
     JOptionPane.showMessageDialog(null, new Test()); 
     } 
    } 

しかし、うまくいきません....ご提案はありますか?

+0

私はあなたが同心円状/内部の長方形を追跡しようとしていると仮定? – basszero

答えて

5

長方形を扱うときの意味を見ています。理由は、翻訳の最初の計算でコンテナオブジェクトのサイズが考慮されなかったためです。

利用代わりに、この:これが何をしているか

tr2.translate(
    (this.getWidth()/2) - (r.getWidth()*(zoom))/2, 
    (this.getHeight()/2) - (r.getHeight()*(zoom))/2 
); 
tr2.scale(zoom,zoom); 
g.setTransform(tr2); 

はそれをスケーリングする前に、パネルの中央に長方形を翻訳しています。私のテストではうまく動作します。

5

スケーリングは長方形の左上隅の位置を修正すると仮定します(これは正しいと思いますが、私はJavaでグラフィックスを作成してから長い時間がかかりました)、逆の方向に矩形を変換する必要がありますスケーリング。

tr2.translate(
    r.getWidth()*(1-zoom)/2, 
    r.getHeight()*(1-zoom)/2 
); 
tr2.scale(zoom,zoom); 
g.setTransform(tr2); 

したがって、幅と高さの変更の左上半分を移動します。

+0

動作していないようです。 –

+0

あなたの解決策は動作しませんが、私にいくつかの新しいアイディアがあります。ありがとうございました – Pierre

+0

@mmyers:あなたはどのような結果を得ていますか?私は仕事中のJava IDEにアクセスできないので、自分でテストすることはできません。私は主に記憶から取り組んでいます。 – Welbog

0

これには、トランスフォームのコンジュゲートと呼ばれる処理が含まれます。 Sは、あなたがしたいスケーリングがあり、そしてTは、あなたのスケーリングの中心になることですポイントにポイント(0,0)かかり変換であれば、それは仕事をしていません変換

です

T(S(inverse(T)))

0

(後で)パネルの寸法に関する事前知識なしに動作するソリューションです。

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Shape; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Ellipse2D; 

import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

public class Test extends JPanel 
    { 
    private static final long serialVersionUID = 1L; 
    private Test() 
     { 
     super(null); 
     setOpaque(true); 
     setBackground(Color.WHITE); 
     setPreferredSize(new Dimension(600,600)); 
     } 

    @Override 
    protected void paintComponent(Graphics g1) { 
     super.paintComponent(g1); 
     Shape r= new Ellipse2D.Double(5,380,400,200); 
     double cx= r.getBounds2D().getCenterX(); 
     double cy= r.getBounds2D().getCenterY(); 
     Graphics2D g=(Graphics2D)g1; 
     g.setColor(Color.BLACK); 
     AffineTransform old= g.getTransform(); 
     g.drawLine((int)cx-10, (int)cy, (int)cx+10, (int)cy); 
     g.drawLine((int)cx, (int)cy-10, (int)cx, (int)cy+10); 
     for(double zoom=1; zoom>=0.1; zoom-=0.1) 
       { 


       AffineTransform tr2 =AffineTransform.getTranslateInstance(-cx, -cy); 
       AffineTransform tr= AffineTransform.getScaleInstance(zoom,zoom); 
       tr.concatenate(tr2); tr2=tr; 
       tr =AffineTransform.getTranslateInstance(cx, cy); 
       tr.concatenate(tr2); tr2=tr; 

       tr= new AffineTransform(old); 
       tr.concatenate(tr2); tr2=tr; 

       g.setTransform(tr2); 



       g.draw(r); 
       g.setTransform(old); 
       } 
     } 


    public static void main(String[] args) { 
     JOptionPane.showMessageDialog(null, new Test()); 
     } 
    } 
0
私はブリトニースピアの顔(DAY)クロップ矩形は、その中心点の周りに拡張しなければならなかったクロップするデスクトップアプリケーションに取り組んでいた

:一般的に

import javafx.scene.Cursor; 
import javafx.scene.Group; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.input.ScrollEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.Paint; 
import javafx.scene.shape.Rectangle; 

class ResizableRectangle extends Rectangle { 

ResizableRectangle(double x, double y, double width, double height, Group group) { 

    super(x, y, width, height); 

    // Set scroll listener for crop selection 
    group.addEventHandler(ScrollEvent.SCROLL, event -> { 
    double zoomFactor = 1.10; 
    double deltaY = event.getDeltaY(); 
    if (deltaY > 0) { 
    zoomFactor = 2.0 - zoomFactor; 
    } 

    super.setX(getX() + (super.getWidth() * (1 - zoomFactor)/2)); // Set new X position 
    super.setWidth(getWidth() * zoomFactor); // Set new Width 

    super.setY(getY() + (super.getHeight() * (1 - zoomFactor)/2)); // Set new Y position 
    super.setHeight(getHeight() * zoomFactor); // Set new Height 

    event.consume(); 
    }); 
}); 
} 

は、アルゴリズムは次のように動作します。

  • と矩形のx値を翻訳:y + (height * (1 - zoomFactor)/2):とy値を変換x + (width * (1 - zoomFactor)/2)
  • 新しい高さを設定width * zoomFactor
  • :に新しい幅を設定し
  • height * zoomFactor
関連する問題