Files
secondo/Javagui/viewer/Fuzzy2D.java
2026-01-23 17:03:45 +08:00

547 lines
14 KiB
Java

//This file is part of SECONDO.
//Copyright (C) 2004, University in Hagen, Department of Computer Science,
//Database Systems for New Applications.
//SECONDO is free software; you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation; either version 2 of the License, or
//(at your option) any later version.
//SECONDO is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//You should have received a copy of the GNU General Public License
//along with SECONDO; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package viewer;
import viewer.viewer3d.graphic3d.*;
import java.awt.event.*;
import javax.swing.*;
import gui.*;
import java.awt.*;
import sj.lang.ListExpr;
import viewer.viewer3d.objects.*;
import java.beans.*;
import gui.idmanager.*;
import viewer.fuzzy2d.*;
import javax.swing.event.*;
import tools.Reporter;
/** this class provioded a viewer for fuzzy spatial objects
* the objects are displayed with 2 dimensions
* to show the membership value one can for each object the
* color for the values 0 and 1. For membershipvalues in(0,1)
* is a linear approximatiopn between the Colors used.
* To display the 3the dimension is also used a ZBuffer.
*/
public class Fuzzy2D extends SecondoViewer implements ApplyListener{
/** creates the new Viewer */
public Fuzzy2D(){
Img = new FuzzyImage(pw,ph);
ImgPanel = new JPanel(){
public void paint(Graphics G){
super.paint(G);
G.drawImage(Img,0,0,null);
}
};
ImgPanel.setSize(pw,ph);
Dimension D = new Dimension(pw,ph);
ImgPanel.setMinimumSize(D);
ImgPanel.setMaximumSize(D);
ImgPanel.setPreferredSize(D);
ScrollPane = new JScrollPane(ImgPanel);
ComboBox = new JComboBox();
setLayout(new BorderLayout());
JPanel P= new JPanel();
P.add(ComboBox);
P.add(CoordLabel);
P.setLayout(new GridLayout(2,1));
add(P,BorderLayout.NORTH);
add(ScrollPane,BorderLayout.CENTER);
add(BBLabel,BorderLayout.SOUTH);
((Graphics2D)Img.getGraphics()).setBackground(new Color(255,255,255));
ImgPanel.repaint();
// build the MenuExtension
JMenuItem MI_ShowSettings = ObjectMenu.add("settings");
MI_ShowSettings.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
showObjectSettings();
}
});
JMenuItem MI_HideSelectedObject=ObjectMenu.add("hide");
MI_HideSelectedObject.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
hideSelectedObject();
}
});
JMenuItem MI_ShowViewConfig = ViewMenu.add("settings");
MI_ShowViewConfig.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
showViewSettings();
}
});
JMenuItem MI_AutoBB = ViewMenu.add("automatic bounding box");
MI_AutoBB.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
if(!AutoBoundingBox){
AutoBoundingBox=true;
update();
}
}});
MenuExtension.addMenu(ObjectMenu);
MenuExtension.addMenu(ViewMenu);
MouseInputListener MIL=new MouseInputAdapter(){
public void mouseMoved(MouseEvent evt){
double[] wc = Img.getWorld(evt.getX(),evt.getY());
// round to 3 positions after comma
wc[0] = ((int)(wc[0]*1000))/1000.0;
wc[1] = ((int)(wc[1]*1000))/1000.0;
CoordLabel.setText("("+wc[0]+" , "+wc[1]+")");
}
public void mousePressed(MouseEvent evt){
startX = evt.getX();
startY = evt.getY();
}
public void mouseDragged(MouseEvent evt){
double[] wc = Img.getWorld(evt.getX(),evt.getY());
// round to 3 positions after comma
wc[0] = ((int)(wc[0]*1000))/1000.0;
wc[1] = ((int)(wc[1]*1000))/1000.0;
CoordLabel.setText("("+wc[0]+" , "+wc[1]+")");
if(isPainting)
drawRectangle(startX,startY,oldX,oldY);
oldX = evt.getX();
oldY = evt.getY();
drawRectangle(startX,startY,oldX,oldY);
isPainting=true;
}
public void mouseReleased(MouseEvent evt){
if(isPainting)
drawRectangle(startX,startY,oldX,oldY);
isPainting=false;
// set the new BoundingBox
AutoBoundingBox = false;
double[] P1 = Img.getWorld(startX,startY);
double[] P2 = Img.getWorld(oldX,oldY);
BB2.setTo(P1[0],P1[1],P2[0],P2[1]);
Img.setBoundingBox(BB2);
BB2.equalize(Img.getBoundingBox());
update();
}
public void mouseClicked(MouseEvent evt){
selectNextAt(evt.getX(),evt.getY());
}
public void drawRectangle(int x1,int y1,int x2,int y2){
Graphics2D G = (Graphics2D) ImgPanel.getGraphics();
G.setColor(Color.green);
G.setXORMode(Color.white);
int x = Math.min(x1,x2);
int w = Math.abs(x1-x2);
int y = Math.min(y1,y2);
int h= Math.abs(y1-y2);
G.drawRect(x,y,w,h);
}
private int startX;
private int startY;
private int oldX;
private int oldY;
private boolean isPainting = false;
};
ImgPanel.addMouseListener(MIL);
ImgPanel.addMouseMotionListener(MIL);
update();
}
/* find the next Object3D which lays under (x,y) and selected it */
private void selectNextAt(int x, int y){
int count = ComboBox.getItemCount();
if(count<=0)
return;
double[] Pos = Img.getWorld(x,y);
double exactness = Img.getWorldAccuracy(Math.max(Img.getPointSize()/2,2));
int index = ComboBox.getSelectedIndex();
if(index<0)
index=0;
else
index++; // begin after selected object
boolean found = false;
int next=index;
for(int i=0;i<count&&!found;i++){
next = (index+i)%count;
Object3D O3D = (Object3D) ComboBox.getItemAt(next);
if(O3D.nearByXY(Pos[0],Pos[1],exactness))
found = true;
}
if(found)
ComboBox.setSelectedIndex(next);
else
ComboBox.setSelectedIndex(-1);
}
/** remove the selected object*/
private void hideSelectedObject(){
Object3D O3D = (Object3D) ComboBox.getSelectedItem();
if(O3D==null)
return;
ID id = O3D.getID();
removeGraphicalObjects(id);
ComboBox.removeItem(O3D);
Img.paint();
ImgPanel.repaint();
if(VC!=null)
VC.removeObject(null);
}
/** return the name "Fuzzy2D"*/
public String getName(){
return "Fuzzy2D";
}
/** take the setting of the current ViewConfig */
public void apply(Object source){
if(source.equals(View)) {
AutoBoundingBox = View.getAutoBoundingBox();
BorderSize = View.getBorderSize();
Proportional = View.getProportional();
if(!AutoBoundingBox){
BoundingBox2D B = View.getBoundingBox();
BB2.equalize(B);
Img.setBoundingBox(BB2);
BB2.equalize(Img.getBoundingBox());
View.setBoundingBox(BB2);
}
Img.setProportional(Proportional);
Img.paintBorders(View.getBorderPaint());
Img.setPointSize(View.getPointSize());
update();
}
}
/** adds a SecondoObject to this viewer */
public boolean addObject(SecondoObject o){
int index = getIndexOf(o);
if(index>=0){ // object allready displayed
ComboBox.setSelectedIndex(index);
return true;
}
ListExpr LE = o.toListExpr();
if(LE.listLength()!=2)
return false;
ListExpr type = LE.first();
ListExpr value = LE.second();
if(! (type.isAtom() && type.atomType()==ListExpr.SYMBOL_ATOM))
return false;
String TypeName = type.symbolValue();
if (TypeName.equals("fpoint")){
FPoint3D P3D = new FPoint3D();
if(!P3D.readFromSecondoObject(o))
return false;
Point3DVector PV = P3D.getPoints();
if(PV!=null)
for(int i=0;i<PV.getSize();i++)
myPoints.append(PV.get(i));
ComboBox.addItem(P3D);
update();
ComboBox.setSelectedIndex(ComboBox.getItemCount()-1);
return true;
}else if(TypeName.equals("fline")){
FLine3D L3D = new FLine3D();
if(!L3D.readFromSecondoObject(o))
return false;
Line3DVector LV = L3D.getLines();
ComboBox.addItem(L3D);
if(LV!=null)
for(int i=0;i<LV.getSize();i++)
myLines.append(LV.get(i));
update();
ComboBox.setSelectedIndex(ComboBox.getItemCount()-1);
return true;
} else if(TypeName.equals("fregion")){
FRegion3D R3D = new FRegion3D();
if(!R3D.readFromSecondoObject(o))
return false;
Triangle3DVector TV = R3D.getTriangles();
ComboBox.addItem(R3D);
if(TV!=null)
for(int i=0;i<TV.getSize();i++)
myTriangles.append(TV.get(i));
update();
ComboBox.setSelectedIndex(ComboBox.getItemCount()-1);
return true;
} else
return false;
}
/** shows a ViewConfig and changed the View */
private void showViewSettings(){
if(View==null){
View = new ViewConfig(VC.getMainFrame());
View.addApplyListener(this);
}
if(AutoBoundingBox){
BB2.readFrom(BB3);
View.setBoundingBox(BB2);
}
View.setBorderPaint(Img.isPaintingBorders());
View.setProportional(Proportional);
View.setBorderSize(BorderSize);
View.setAutoBoundingBox(AutoBoundingBox);
View.setPointSize(Img.getPointSize());
View.setVisible(true);
}
/** inserts all points, lines and triangles from O */
private void addGraphicalObjects(Object3D O){
Triangle3DVector Trs = O.getTriangles();
if(Trs!=null)
for(int i=0;i<Trs.getSize();i++)
myTriangles.append(Trs.get(i));
Line3DVector Lns = O.getLines();
if(Lns!=null)
for(int i=0;i<Lns.getSize();i++)
myLines.append(Lns.get(i));
Point3DVector Pts = O.getPoints();
if(Pts!=null)
for(int i=0;i<Pts.getSize();i++)
myPoints.append(Pts.get(i));
}
/** computes the current bounding box in tzhe world */
private void computeBoundingBox(){
BB3.set(0,0,0,0,0,0);
for(int i=0;i<ComboBox.getItemCount();i++){
Object3D O3D = (Object3D) ComboBox.getItemAt(i);
if(i==0)
BB3.equalize(O3D.getBoundingBox());
else
BB3.extend(O3D.getBoundingBox());
}
}
/** remove the given Object from this viewer*/
public void removeObject(SecondoObject o){
removeAll();
/* ID id = o.getID();
removeGraphicalObjects(id);
int index = getIndexOf(o);
if(index>=0)
ComboBox.removeItemAt(index);
Img.paint();
ImgPanel.repaint();
*/
}
/** remove all objects from this viewer */
public void removeAll(){
ComboBox.removeAllItems();
Img.removeAll();
myPoints.empty();
myLines.empty();
myTriangles.empty();
Img.paint();
ImgPanel.repaint();
}
/** remove all graphical object with given ID */
private void removeGraphicalObjects(ID id){
int i=0;
while (i<myPoints.getSize())
if(myPoints.get(i).getID().equals(id))
myPoints.remove(i);
else
i++;
i=0;
while (i<myLines.getSize())
if(myLines.get(i).getID().equals(id))
myLines.remove(i);
else
i++;
i=0;
while (i<myTriangles.getSize())
if(myTriangles.get(i).getID().equals(id))
myTriangles.remove(i);
else
i++;
Img.remove(id);
}
/** returns true if o is a fuzzy object */
public boolean canDisplay(SecondoObject o){
ListExpr LE = o.toListExpr();
if(LE.listLength()!=2) return false;
ListExpr type = LE.first();
if (!(type.isAtom() && type.atomType()==ListExpr.SYMBOL_ATOM))
return false;
String TypeName = type.symbolValue();
return (TypeName.equals("fpoint") || TypeName.equals("fregion") || TypeName.equals("fline"));
}
/** returns true if o already displayes */
public boolean isDisplayed(SecondoObject o){
return getIndexOf(o)>=0;
}
/** select O in the ComboBox if displayed */
public boolean selectObject(SecondoObject O){
int index = getIndexOf(O);
if (index<0)
return false;
else{
ComboBox.setSelectedIndex(index);
return true;
}
}
/** returns the menuextension for this viewer */
public MenuVector getMenuVector(){
return MenuExtension;
}
/** returns the index of SO in the ComboBox indicated by the ID
* if the combobox not contains SO -1 is returned
*/
private int getIndexOf(SecondoObject SO){
int pos = -1;
int count= ComboBox.getItemCount();
boolean found =false;
ID id = SO.getID();
for(int i=0;i<count && !found;i++){
Object3D O3D = (Object3D)ComboBox.getItemAt(i);
if(id.equals(O3D.getID())){
pos=i;
found = true;
}
}
return pos;
}
/* computes the image and paint it */
private void update(){
computeBoundingBox();
DisplayBB.readFrom(BB3);
BBLabel.setText("BoundingBox ="+DisplayBB);
Img.removeAll();
if (AutoBoundingBox){
AutoBB2.setTo(BB3.getMinX()-BorderSize,BB3.getMinY()-BorderSize,
BB3.getMaxX()+BorderSize,BB3.getMaxY()+BorderSize);
Img.setBoundingBox(AutoBB2);
}
Img.add(myPoints);
Img.add(myLines);
Img.add(myTriangles);
Img.paint();
ImgPanel.repaint();
}
/** shows the settings dialog for the selected object */
private void showObjectSettings(){
Object3D O3D = (Object3D) ComboBox.getSelectedItem();
if(O3D==null){
Reporter.showError("no Object selected");
return;
}
O3D.showSettings(VC.getMainFrame());
removeGraphicalObjects(O3D.getID());
addGraphicalObjects(O3D);
update();
}
private Point3DVector myPoints=new Point3DVector();
private Line3DVector myLines= new Line3DVector();
private Triangle3DVector myTriangles=new Triangle3DVector();
private BoundingBox3D BB3=new BoundingBox3D();
private JScrollPane ScrollPane;
private FuzzyImage Img;
private JComboBox ComboBox;
private JPanel ImgPanel;
private JLabel BBLabel = new JLabel();
private int pw=1280;
private int ph=1024;
private MenuVector MenuExtension = new MenuVector();
private JMenu ObjectMenu = new JMenu("Object");
private JMenu ViewMenu = new JMenu("View");
private JLabel CoordLabel = new JLabel("(0,0)");
private BoundingBox2D DisplayBB = new BoundingBox2D();
private ViewConfig View;
private boolean AutoBoundingBox = true;
private double BorderSize = 0.0;
private BoundingBox2D BB2 = new BoundingBox2D();
private BoundingBox2D AutoBB2 = new BoundingBox2D();
private boolean Proportional = true;
}