ともさんのHP >プロブラミング >図形を拡大縮小/平行移動表示

【Java】図形を拡大縮小/平行移動して表示する方法

CADソフトを作るために、マウス操作で作図した図形を拡大縮小、平行移動する方法を考えました。

AffineTransformを使う方法

ネットで検索すると出てくるのが、AffineTransformを使う方法です。これが一般的だと思います...
ところが!実際に表示してみると、下のようになってしまいます。
図形の拡大縮小

線の太さや、ゴツゴツ感まで拡大されてしまいます。
これは嫌なので、座標変換する方法を考えました。
AffineTransformは表示するパネルの方を拡大縮小/平行移動する方法です。
表示する点の座標を変換して、パネル側に手を加えなければ、下のように拡大しても線の太さは変わりません。
図形の拡大縮小


下のメソッドを作りました。
kS()は表示する図形をパネル上の座標に変換するもの、sK()はその逆で、マウスカーソル下の座標を計算するときなどに使います。

sx,syは平行移動の値、ssx,ssyは直近の新たな平行移動値。
scaleは画面のスケール。Px,pyは業がパネルの中心座標。
これで拡大縮小と平行移動ができるようになります。Px,pyをパネルの中心にしているので、拡大縮小がパネルの中心を中心にしてなされます。
Point kS( Point p)
{
Point rp = new Point();
rp.x = (int)((p.x + sx)*scale+px+ssx);
rp.y= (int)((-p.y + sy)*scale+py+ssy);
return rp;
}

Point sK( Point p)
{
Point rp = new Point();
rp.x = (int)((p.x - ssx - px ) / scale - sx);
rp.y= -(int)((p.y - ssy - py ) / scale - sy);
return rp;
}

拡大縮小動画

画像だけではわかりにくいので動画もUPしておきます。

ソースコード

動画のソースコードは下記です。

package tomojavalib.test;

import java.awt.*;


import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;


import javax.swing.Jframe;
import javax.swing.Jpanel;

public class MouseCursor2 extends Jframe{
 int bai=0;
 //int cx=1;
 //int cy=1;
 double scale = 1. ;
double x=0.;
double y=0.;
 int tmpsx=0;
 int tmpsy=0;
 double sx=0.;
 double sy=0.;
 double ssx=0.;
 double ssy=0.;
Jpanel p = null;

double px=0.;
double py=0.;
int x1=-0;int y1=-0;
//int x2=25;int y2=25;
//拡大縮小
java.awt.geom.AffineTransform af = new java.awt.geom.AffineTransform();

public void paint(Graphics g){
 System.out.println("再描画");
 Graphics2D g2 = (Graphics2D)p.getGraphics();
 //スケールの変更
 if(bai==-1){scale=scale *.8;}else if(bai==1){scale=scale /.8;}
 //パネルの中心
 double px= (double)p.getWidth()/2.;double py= (double)p.getHeight()/2.;
 
 
 //パネル側を拡大縮小する場合
//  af.setToTranslation(sx*scale+px+ssx, sy*scale+py+ssy);
//  af.scale(scale, scale);
// g2.setTransform(af);
 
 
  //座標を変換する場合
x1= (int)((x + sx)*scale+px+ssx); 
y1= (int)((y + sy)*scale+py+ssy); 


 System.out.println(x1+" "+scale);
//後処理
sx=sx+ssx/scale;sy=sy+ssy/scale;
ssx=0.;ssy=0.;
//四角形の描画
int haba=(int)(25*scale);
 g2.drawRect(x1-haba, y1-haba, haba, haba);
 g2.drawOval(x1-haba, y1-haba, haba, haba);
// sscale =scale;
// System.out.println(x1 +" "+ x2 +" "+ y1 +" "+ y2 +" "+ bai +" "+ scale);
 bai=0;
}

public MouseCursor2()
{
 p = new Jpanel();
 p.setBackground(Color.red);
 Container contentPane = getContentPane();
 contentPane.add( p, BorderLayout.CENTER ); 
 setByougapanel(p);
}

public static void main(String[] args) {
 MouseCursor2 m = new MouseCursor2();
 m.setSize(640,480);
 m.setBackground(Color.WHITE);
 m.setVisible(true);
}

public void setByougapanel( Jpanel p )
{
//マウスイベントを発生させる。     
 p.addMouseListener(
  new MouseAdapter(){  
   //マウスクリック時のイベント
   public void mouseClicked(MouseEvent e){
 int mouseNo = e.getButton();
 if( mouseNo==1 ){ System.out.println("マウス左ボタンがクリックされました"); }  
 else if( mouseNo==2 ){ System.out.println("マウス中ボタン楽天 がクリックされました"); }
 else if( mouseNo==3 ){ System.out.println("マウス右ボタンがクリックされました"); }
   }
   public void mousePressed(MouseEvent e){
 int mouseNo = e.getButton();
 if( mouseNo==1 ){ System.out.println("マウス左ボタンが押されました"); }  
 else if( mouseNo==2 ){ tmpsx=e.getX();tmpsy=e.getY(); System.out.println("マウス中ボタンが押されました"); }
 else if( mouseNo==3 ){ System.out.println("マウス右ボタンが押されました"); }
   }
   public void mouseReleased(MouseEvent e){
     int mouseNo = e.getButton();
   if( mouseNo==1 ){ System.out.println("マウス左ボタンが放されました"); }  
   else if( mouseNo==2 ){
     System.out.println("マウス中ボタンが放されました");
     ssx = e.getX() - tmpsx ;ssy = e.getY() -tmpsy;
     e.consume();repaint();
   }
   else if( mouseNo==3 ){System.out.println("マウス右ボタンが放されました"); }
    }
  }
 );
 
//マウスがパネル上を動いたらイベントを発生させる。     
 p.addMouseMotionListener(
  new MouseMotionAdapter(){  
   //マウスが動いたときの処理
   public void mouseMoved(MouseEvent e){
   }
   //マウスがドラッグされた時のイベント
   public void mouseDragged(MouseEvent e){
 //System.out.println( "マウスがドラッグ" );
   }
  }
 );
//マウスホイールが動かされた場合のイベント

 p.addMouseWheelListener(
  new MouseWheelListener(){
   public void mouseWheelMoved(MouseWheelEvent e) {
  //  cad.mx = e.getX();cad.my = e.getY();
    bai = e.getWheelRotation() ;
    System.out.println(e.getWheelRotation());
    e.consume();
    repaint();
   }
  }
 );
}
}

最終更新日: 2018-12-21 08:45:48

ともさんのHP >プロブラミング >図形を拡大縮小/平行移動表示

広告
新着ページ

AIを利用し、衣服のデザイン画から型紙を制作する方法  
2つのアパレル3D技術でひらくオーダーメイド生産の手法  
【洋裁型紙】前後身頃の肩の傾きは何故前身頃の方が傾いているのか  
電子追尾式天体写真撮影法  
日本ミツバチ巣箱の種類  
ドラフター(製図台)でソーイング  
日本ミツバチが逃亡  
カメさんの箱庭  
天体用デジタルカメラの構造と天体写真  
Javaで静止画像(Jpeg)を動画(Mov)に変換  
USBカメラをJAVAで制御  

他のサイト

3D-CAD
洋裁CAD

いいねなど

 RSS 

Author: Tomoyuki Ito

このサイトの文章・写真の無断転載を禁じます