/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- DlgAnalyzeProjection
- resetState
- getParameterType
- getParameters
- stateChanged
- addActionListener
- removeActionListener
- requireSrc
- writeImage
- calcpoint
package jp.ac.nime.computer.grpsimulator;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.TitledBorder;
import java.io.*;
import java.util.*;
import jp.ac.nime.computer.grpsimulator.VecPr.*;
/** 投影モデル用の設定ダイアログ
*
* @version 1.0.0
* @author kikuchi
*/
public class DlgAnalyzeProjection extends JPanel
implements ChangeListener, ParameterSetting, OperationDialog
{
private JSlider jSlider1_;
private JSlider jSlider2_;
private ImageViewPanel canvas_;
private String srcPath_;
private BufferedImage img_; // パネルに設定する画像
private ActionListener actionListener_;
/** Creates new form DlgContrast */
public DlgAnalyzeProjection() {
setLayout(new BorderLayout());
setBorder(new TitledBorder(GrpSim.res_.getString("DlgDescriptProjectionLabel")));
setMaximumSize(new Dimension(320, 300));
setMinimumSize(new Dimension(320, 300));
setPreferredSize(new Dimension(320, 300));
JPanel jPanel1 = new JPanel();
jPanel1.setLayout(new BoxLayout(jPanel1, BoxLayout.Y_AXIS));
// カメラと投影面と物体を示す図
canvas_ = new ImageViewPanel(300, 160);
jPanel1.add(canvas_);
// 投影面とカメラの距離
JLabel jLabel1 = new JLabel();
jLabel1.setText(GrpSim.res_.getString("DlgDescriptProjectionSlider1Label"));
jPanel1.add(jLabel1);
jSlider1_ = new JSlider(50, 200);
jSlider1_.setMajorTickSpacing(50);
jSlider1_.setMinorTickSpacing(10);
jSlider1_.setPaintLabels(true);
jSlider1_.setPaintTicks(true);
jSlider1_.setValue(100);
jSlider1_.addChangeListener(this);
jPanel1.add(jSlider1_);
/*
// カメラの位置
JLabel jLabel2 = new JLabel();
jLabel2.setText(GrpSim.res_.getString("DlgDescriptProjectionSlider2Label"));
jPanel1.add(jLabel2);
jSlider2_ = new JSlider(-60, 60);
jSlider2_.setMajorTickSpacing(30);
jSlider2_.setMinorTickSpacing(10);
jSlider2_.setPaintLabels(true);
jSlider2_.setPaintTicks(true);
jSlider2_.setValue(0);
jSlider2_.addChangeListener(this);
jPanel1.add(jSlider2_);
*/
add(jPanel1, BorderLayout.NORTH);
// 画像バッファ
img_ = new BufferedImage(300, 160, BufferedImage.TYPE_INT_ARGB);
canvas_.setImage(img_);
//writeImage(img_, jSlider1_.getValue(), jSlider2_.getValue());
writeImage(img_, jSlider1_.getValue(), 0);
}
/** ダイアログの状態をリセットする */
public void resetState() {
actionListener_.actionPerformed(new ActionEvent(this,ActionEvent.ACTION_PERFORMED,"ParameterChanged"));
}
public int getParameterType() {
return ParameterSetting.PARAM_TYPE_DESCRIPT_PROJECTION;
}
public int[] getParameters() {
int ret[] = new int[2];
ret[0] = jSlider1_.getValue(); // 投影面
ret[1] = 0; //jSlider2_.getValue(); // カメラ
return ret;
}
public void stateChanged(ChangeEvent evt) {
// 再描画
//writeImage(img_, jSlider1_.getValue(), jSlider2_.getValue());
writeImage(img_, jSlider1_.getValue(), 0);
repaint();
JSlider source = (JSlider) evt.getSource();
if ( !source.getValueIsAdjusting() )
actionListener_.actionPerformed(new ActionEvent(this,ActionEvent.ACTION_PERFORMED,"ParameterChanged"));
}
public void addActionListener(ActionListener listener) {
actionListener_ = AWTEventMulticaster.add(actionListener_, listener);
}
public void removeActionListener(ActionListener listener) {
actionListener_ = AWTEventMulticaster.remove(actionListener_, listener);
}
/** 変換元画像を必要とするかどうかを返す
* @return 変換元画像を必要とするならtrueを返す
*/
public boolean requireSrc() {
return false;
}
// カメラと投影面と物体の画像を作成する
private static void writeImage(BufferedImage img, int nDis, int nCmr) {
Graphics2D g = img.createGraphics();
// 白でクリア
g.setBackground(Color.white);
g.clearRect(0, 0, img.getWidth(), img.getHeight());
g.setStroke(new BasicStroke(0.0f)); // 一番細く 引数はfloat
// 図形の位置
int box[][] = {{220, -70, 40, 40}, {260, +20, 40, 40}};
// 図形2の位置
int shifty = img.getHeight() / 2;
// 視点の位置を示すライン
int x, y;
x = 10;
y = 5;
g.setPaint(Color.black); // 黒
//g.draw(new Line2D.Double(x, y, x, img.getHeight() - y));
// 図形1
g.setPaint(Color.blue);
for (int i = 0; i < 2; i ++) {
g.fill(new Rectangle2D.Double(box[i][0], box[i][1] + shifty, box[i][2], box[i][3]));
//System.out.println(box[i][0] + ", " + box[i][0] + ", " + box[i][2] + ", " + box[i][3]);
}
// 投影面の位置を示すライン
// パラレル
int tx;
tx = 10 + nDis;
y = 5;
g.setPaint(Color.black);
g.draw(new Line2D.Double(tx, y, tx, img.getHeight() - y));
// 投影面に平行の線 と 投影面のところにboxを書く
g.setPaint(Color.red);
for (int i = 0; i < 2; i ++) {
g.draw(new Line2D.Double(tx, box[i][1] + shifty, box[i][0], box[i][1] + shifty));
g.draw(new Line2D.Double(tx, box[i][1] + box[i][2] - 1 + shifty , box[i][0], box[i][1] + box[i][2] - 1 + shifty));
g.fill(new Rectangle2D.Double(tx -1, box[i][1] + shifty, 2 , box[i][3]));
}
// パースペクティブ
// カメラ位置にカメラのマークを書く
int cx = 10;
int cy = shifty + nCmr;
g.setPaint(Color.green);
g.fill(new Rectangle2D.Double(cx - 2, cy - 2, 4 , 4));
// カメラ位置から図形の4点までラインを引く
tx -= cx; // 投影面座標補正
for (int i = 0; i < 2; i ++) {
if (nCmr < box[i][1]) {
g.draw(new Line2D.Double(cx, cy, box[i][0] + box[i][2], box[i][1] + shifty));
g.draw(new Line2D.Double(cx, cy, box[i][0], box[i][1] + box[i][3] + shifty));
// 投影面
calcpoint(g, cx, cy, box[i][0] + box[i][2], box[i][1] + shifty, box[i][0], box[i][1] + box[i][3] + shifty, tx);
} else if (nCmr > box[i][1] + box[i][3]) {
g.draw(new Line2D.Double(cx, cy, box[i][0], box[i][1] + shifty));
g.draw(new Line2D.Double(cx, cy, box[i][0] + box[i][2], box[i][1] + box[i][3] + shifty));
// 投影面
calcpoint(g, cx, cy, box[i][0], box[i][1] + shifty, box[i][0] + box[i][2], box[i][1] + box[i][3] + shifty, tx);
} else {
g.draw(new Line2D.Double(cx, cy, box[i][0], box[i][1] + shifty));
g.draw(new Line2D.Double(cx, cy, box[i][0], box[i][1] + box[i][3] + shifty));
// 投影面
calcpoint(g, cx, cy, box[i][0], box[i][1] + shifty, box[i][0], box[i][1] + box[i][3] + shifty, tx);
}
}
g.dispose();
}
// 投影面に図形を投影する
private static void calcpoint(Graphics2D g, int cx, int cy, int sx1, int sy1, int sx2, int sy2, int tx) {
int sx, sy;
int px1, py1;
int px2, py2;
sx1 -= cx;
sy1 -= cy;
px1 = tx;
py1 = (px1 * sy1) / sx1;
px1 += cx;
py1 += cy;
sx2 -= cx;
sy2 -= cy;
px2 = tx;
py2 = (px2 * sy2) / sx2;
px2 += cx;
py2 += cy;
if (py2 > py1)
g.fill(new Rectangle2D.Double(px1 -1, py1 , 2 , py2 - py1 ));
else
g.fill(new Rectangle2D.Double(px1 -1, py2 , 2 , py1 - py2 ));
}
}