├── logo.png
├── src
├── doc
│ ├── applet-demo.jar
│ ├── sample_capture.png
│ ├── demo.xml
│ ├── demo.html
│ └── demo.jnlp
├── main
│ ├── java
│ │ └── net
│ │ │ └── ericaro
│ │ │ └── surfaceplotter
│ │ │ ├── Mapper.java
│ │ │ ├── surface
│ │ │ ├── SurfaceColor.java
│ │ │ ├── SurfaceUtils.java
│ │ │ ├── ColorModel.java
│ │ │ ├── ArraySurfaceModel.java
│ │ │ ├── LineAccumulator.java
│ │ │ ├── SurfaceVertex.java
│ │ │ ├── SurfaceModel.java
│ │ │ ├── ColorModelSet.java
│ │ │ ├── Projector.java
│ │ │ ├── VerticalConfigurationPanel.java
│ │ │ └── AbstractSurfaceModel.java
│ │ │ ├── JSurfaceApplet.java
│ │ │ ├── beans
│ │ │ ├── ModelBindedBeanProperty.java
│ │ │ ├── ModelSource.java
│ │ │ ├── JPlotTypeComboBox.java
│ │ │ ├── JGridBagScrollPane.java
│ │ │ ├── JPlotColorComboBox.java
│ │ │ ├── JEnumComboBox.java
│ │ │ ├── JBindedRadioButton.java
│ │ │ ├── JScrollablePanel.java
│ │ │ ├── JBindedCheckBox.java
│ │ │ └── BeanProperty.java
│ │ │ ├── DefaultSurfaceModel.java
│ │ │ ├── JSurfacePanel.jfd
│ │ │ ├── JSurfacePanel.java
│ │ │ ├── ProgressiveSurfaceModel.java
│ │ │ └── AbstractSurfaceModel.java
│ └── resources
│ │ └── net
│ │ └── ericaro
│ │ └── surfaceplotter
│ │ ├── JSurfacePanel.properties
│ │ └── surface
│ │ └── VerticalConfigurationPanel.properties
└── test
│ └── java
│ ├── SimpleRun.java
│ ├── Sample.java
│ └── Sample.jfd
├── .gitignore
├── README.md
└── pom.xml
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericaro/surfaceplotter/HEAD/logo.png
--------------------------------------------------------------------------------
/src/doc/applet-demo.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericaro/surfaceplotter/HEAD/src/doc/applet-demo.jar
--------------------------------------------------------------------------------
/src/doc/sample_capture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericaro/surfaceplotter/HEAD/src/doc/sample_capture.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # maven
2 | target
3 |
4 | # eclipse
5 | .project
6 | .classpath
7 | .settings
8 | .externalToolBuilders
9 |
10 | # java
11 | *.class
12 |
13 | # python
14 | *.pyc
15 |
16 | # gedit backup files
17 | *~
18 | *.*~
19 |
--------------------------------------------------------------------------------
/src/doc/demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
When a GridBagLayout has not enough room to layout its component, it moves 11 | * from preferredsize to minimum size. Standard scrollpane have a very small minimumsize, and it DOES not depend on the viewport view. 12 | *
Therefore, this scrollpane does not collapse to a very small minimum size. 13 | *
if one direction is set to fixed (either
widthFixed
heightFixed) then the minimum size for this 14 | * direction = the preffered size. 15 | * 16 | * @author eric 17 | * 18 | */ 19 | public class JGridBagScrollPane extends JScrollPane{ 20 | 21 | private boolean widthFixed =false; 22 | private boolean heightFixed = false; 23 | 24 | 25 | 26 | 27 | public JGridBagScrollPane() { 28 | super(); 29 | } 30 | 31 | 32 | 33 | 34 | public JGridBagScrollPane(Component view, int vsbPolicy, int hsbPolicy) { 35 | super(view, vsbPolicy, hsbPolicy); 36 | } 37 | 38 | 39 | 40 | 41 | public JGridBagScrollPane(Component view) { 42 | super(view); 43 | } 44 | 45 | 46 | 47 | 48 | public JGridBagScrollPane(int vsbPolicy, int hsbPolicy) { 49 | super(vsbPolicy, hsbPolicy); 50 | } 51 | 52 | 53 | 54 | 55 | @Override 56 | public Dimension getMinimumSize() { 57 | Dimension min = super.getMinimumSize(); 58 | int w = min.width; 59 | int h = min.height; 60 | if (widthFixed){ 61 | w = getPreferredSize().width; // the content size 62 | w+= getVerticalScrollBar().getWidth(); 63 | } 64 | if (heightFixed){ 65 | h = getPreferredSize().height; // the content size 66 | h+= getHorizontalScrollBar().getHeight(); 67 | } 68 | 69 | return new Dimension(w, h); 70 | } 71 | 72 | 73 | @Override 74 | public void layout() { 75 | boolean vertical = getVerticalScrollBar().isVisible(); 76 | super.layout(); 77 | if (vertical != getVerticalScrollBar().isVisible() ){ 78 | getParent().invalidate() ; 79 | getParent().validate(); 80 | } 81 | } 82 | 83 | 84 | 85 | 86 | public boolean isWidthFixed() { 87 | return widthFixed; 88 | } 89 | 90 | 91 | 92 | /** 93 | * 94 | * @param widthFixed true to force the minimum width to preferred's width. 95 | */ 96 | public void setWidthFixed(boolean widthFixed) { 97 | firePropertyChange("widthFixed", this.widthFixed , this.widthFixed = widthFixed); 98 | invalidate(); 99 | if (getParent()!=null) 100 | getParent().validate(); 101 | } 102 | 103 | 104 | 105 | 106 | public boolean isHeightFixed() { 107 | return heightFixed; 108 | } 109 | 110 | 111 | 112 | /** 113 | * 114 | * @param heightFixed true to force the minimum height to preferred's height. 115 | */ 116 | public void setHeightFixed(boolean heightFixed) { 117 | firePropertyChange("heightFixed", this.heightFixed , this.heightFixed = heightFixed); 118 | if (getParent()!=null) 119 | getParent().validate(); 120 | } 121 | 122 | 123 | 124 | 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/net/ericaro/surfaceplotter/beans/JPlotColorComboBox.java: -------------------------------------------------------------------------------- 1 | /* 2 | ____ _____ ___ ____ __ ____ _____ _ _ ____ ____ 3 | ( _ \( _ )/ __)( ___) /__\ ( _ \( _ )( \/\/ )( ___)( _ \ 4 | )(_) ))(_)(( (__ )__) /(__)\ )___/ )(_)( ) ( )__) ) / 5 | (____/(_____)\___)(____)(__)(__) (__) (_____)(__/\__)(____)(_)\_) 6 | 7 | * Created 20 mai 2011 by : eric@doceapower.com 8 | * Copyright Docea Power 2011 9 | * Any reproduction or distribution prohibited without express written permission from Docea Power 10 | *************************************************************************** 11 | */ 12 | package net.ericaro.surfaceplotter.beans; 13 | 14 | import net.ericaro.surfaceplotter.surface.SurfaceModel.PlotColor; 15 | 16 | /** 17 | * @author eric 18 | * 19 | */ 20 | public class JPlotColorComboBox extends JEnumComboBox
LineAccumulator accumulates line drawing information and
36 | * then draws all accumulated lines together. It is used as contour lines accumulator
37 | * in Surface Plotter.
38 | *
39 | * @author Yanto Suryono
40 | */
41 |
42 | public class LineAccumulator {
43 | private ListLineAccumulator
47 | */
48 |
49 | LineAccumulator() {
50 | accumulator = new LinkedListLineAccumulator class.
93 | *
94 | * @see LineAccumulator
95 | */
96 |
97 | class LineRecord {
98 | /**
99 | * @param x1 the first point's x coordinate
100 | */
101 | public final int x1;
102 |
103 | /**
104 | * @param y1 the first point's y coordinate
105 | */
106 | public final int y1;
107 |
108 | /**
109 | * @param x2 the second point's x coordinate
110 | */
111 | public final int x2;
112 |
113 | /**
114 | * @param y2 the second point's y coordinate
115 | */
116 | public final int y2;
117 |
118 | /**
119 | * The constructor of LineRecord
120 | *
121 | * @param x1 the first point's x coordinate
122 | * @param y1 the first point's y coordinate
123 | * @param x2 the second point's x coordinate
124 | * @param y2 the second point's y coordinate
125 | */
126 |
127 | LineRecord(int x1, int y1, int x2, int y2) {
128 | super();
129 | this.x1 = x1; this.y1 = y1;
130 | this.x2 = x2; this.y2 = y2;
131 | }
132 | }
133 |
134 |
--------------------------------------------------------------------------------
/src/main/java/net/ericaro/surfaceplotter/DefaultSurfaceModel.java:
--------------------------------------------------------------------------------
1 | package net.ericaro.surfaceplotter;
2 |
3 | import java.util.List;
4 | import java.util.concurrent.ExecutionException;
5 |
6 | import javax.swing.SwingWorker;
7 |
8 | import net.ericaro.surfaceplotter.surface.AbstractSurfaceModel;
9 | import net.ericaro.surfaceplotter.surface.SurfaceModel;
10 | import net.ericaro.surfaceplotter.surface.SurfaceVertex;
11 |
12 |
13 | /**
14 | * {@link DefaultSurfaceModel} provides a simple way to fill the {@link AbstractSurfaceModel} using the Plotter interface.
15 | */
16 | public class DefaultSurfaceModel extends AbstractSurfaceModel implements SurfaceModel {
17 |
18 |
19 |
20 | private Mapper mapper;
21 | protected SurfaceVertex[][] surfaceVertex;
22 | /**
23 | * Empty Surface Model
24 | */
25 | public DefaultSurfaceModel() {
26 | super();
27 | }
28 |
29 |
30 | public SwingWorkerSurfaceVertex represents a surfaceVertex in 3D space.
32 | *
33 | * @author Yanto Suryono
34 | */
35 |
36 | public final class SurfaceVertex {
37 | private Point projection;
38 | private int project_index;
39 |
40 |
41 | private static int master_project_index = 0; // over 4 billion times to reset
42 |
43 | /**
44 | * The x coordinate
45 | */
46 | public float x;
47 |
48 | /**
49 | * The y coordinate
50 | */
51 | public float y;
52 |
53 | /**
54 | * The z coordinate
55 | */
56 | public float z;
57 |
58 | /**
59 | * The constructor of SurfaceVertex.
60 | * The x and y coordinated must be in normalized form, i.e: in the range -10 .. +10.
61 | *
62 | * @param ix the x coordinate
63 | * @param iy the y coordinate
64 | * @param iz the z coordinate
65 | */
66 |
67 | public SurfaceVertex(float ix, float iy, float iz)
68 | {
69 | x = ix; y = iy; z = iz;
70 | project_index = master_project_index-1;
71 | }
72 |
73 | /**
74 | * Determines whether this surfaceVertex is invalid, i.e has invalid coordinates value.
75 | *
76 | * @return true if this surfaceVertex is invalid
77 | */
78 |
79 | public final boolean isInvalid() {
80 | return Float.isNaN(z);
81 | }
82 |
83 | /**
84 | * Gets the 2D projection of the surfaceVertex.
85 | *
86 | * @return the 2D projection
87 | */
88 |
89 | public final Point projection(Projector projector) {
90 | if (project_index != master_project_index) {
91 | projection = projector.project(x,y,(z-projector.zmin)*projector.zfactor-10);
92 | project_index = master_project_index;
93 | }
94 | return projection;
95 | }
96 |
97 | /**
98 | * Transforms coordinate values to fit the scaling factor of the
99 | * projector. This routine is only used for transforming center of projection
100 | * in Surface Plotter.
101 | */
102 |
103 | public final void transform(Projector projector) {
104 | x = x / projector.getXScaling();
105 | y = y / projector.getYScaling();
106 | z = (projector.zmax-projector.zmin)*(z/projector.getZScaling()+10)/20 + projector.zmin;
107 | }
108 |
109 | /**
110 | * Invalidates all vertices. This will force the projector
111 | * to recalculate surfaceVertex projection.
112 | */
113 |
114 | public static void invalidate() {
115 | master_project_index++;
116 | }
117 |
118 | /**
119 | * Sets the projector to project this surfaceVertex.
120 | *
121 | * @param projector the projector
122 | */
123 | /*
124 | public void setProjector(Projector projector) {
125 | this.projector = projector;
126 | }
127 | /**/
128 | /**
129 | * Sets the minimum and maximum value of z range.
130 | * This values is used to compute a factor to normalized
131 | * z values into the range -10 .. +10.
132 | *
133 | * @param zmin the minimum z
134 | * @param zmax the maximum z
135 | */
136 |
137 | }
138 |
139 |
--------------------------------------------------------------------------------
/src/test/java/Sample.jfd:
--------------------------------------------------------------------------------
1 |
2 | true if the checkbox is checked,
105 | * false otherwise
106 | */
107 | public boolean isExpectDelay();
108 |
109 | /**
110 | * Determines whether to show bounding box.
111 | *
112 | * @return true if to show bounding box
113 | */
114 | public boolean isBoxed();
115 |
116 | /**
117 | * Determines whether to show x-y mesh.
118 | *
119 | * @return true if to show x-y mesh
120 | */
121 | public boolean isMesh();
122 | /**
123 | * Determines whether to scale axes and bounding box.
124 | *
125 | * @return true if to scale bounding box
126 | */
127 |
128 | public boolean isScaleBox();
129 |
130 | /**
131 | * Determines whether to show x-y ticks.
132 | *
133 | * @return true if to show x-y ticks
134 | */
135 | public boolean isDisplayXY();
136 | /**
137 | * Determines whether to show z ticks.
138 | *
139 | * @return true if to show z ticks
140 | */
141 | public boolean isDisplayZ();
142 | /**
143 | * Determines whether to show face grids.
144 | *
145 | * @return true if to show face grids
146 | */
147 | public boolean isDisplayGrids();
148 | /**
149 | * Determines whether the first function is selected.
150 | *
151 | * @return true if the first function is checked,
152 | * false otherwise
153 | */
154 | public boolean isPlotFunction1();
155 |
156 | /**
157 | * Determines whether the first function is selected.
158 | *
159 | * @return true if the first function is checked,
160 | * false otherwise
161 | */
162 |
163 | public boolean isPlotFunction2();
164 |
165 | /**
166 | * Sets data availability flag
167 | */
168 | public boolean isDataAvailable();
169 |
170 |
171 | }
172 |
173 |
--------------------------------------------------------------------------------
/src/main/java/net/ericaro/surfaceplotter/surface/ColorModelSet.java:
--------------------------------------------------------------------------------
1 | package net.ericaro.surfaceplotter.surface;
2 |
3 | import java.awt.Color;
4 |
5 | import net.ericaro.surfaceplotter.surface.SurfaceModel.PlotColor;
6 | import net.ericaro.surfaceplotter.surface.SurfaceModel.PlotType;
7 |
8 |
9 | /** A simple {@link SurfaceColor} implementations that uses two ColorMode per plot type.
10 |
11 | * @author Eric
12 | * @date jeudi 8 avril 2004 15:45:40
13 | */
14 | public class ColorModelSet implements SurfaceColor
15 | {
16 |
17 | public static float RED_H=0.941896f;
18 | public static float RED_S=0.7517241f;
19 | public static float RED_B=0.5686275f;
20 |
21 | public static float GOLD_H=0.1f;
22 | public static float GOLD_S=0.9497207f;
23 | public static float GOLD_B=0.7019608f;
24 |
25 |
26 | protected ColorModel dualshade;
27 | protected ColorModel grayscale;
28 | protected ColorModel spectrum;
29 | protected ColorModel fog;
30 | protected ColorModel opaque;
31 |
32 | protected ColorModel alt_dualshade;
33 | protected ColorModel alt_grayscale;
34 | protected ColorModel alt_spectrum;
35 | protected ColorModel alt_fog;
36 | protected ColorModel alt_opaque;
37 |
38 | protected Color lineColor=Color.DARK_GRAY;
39 | protected Color lineboxColor=Color.getHSBColor(0f,0f,0.5f);
40 | protected Color lightColor=Color.WHITE;
41 | // Color(192,220,192); existing
42 | protected Color boxColor=Color.getHSBColor(0f,0f,0.95f);//Color.getHSBColor(226f/240f,145f/240f,1f);
43 |
44 | public ColorModelSet()
45 | {
46 | /*
47 | float[] f = Color.RGBtoHSB(255,255,255, new float[4]);
48 | System.out.print("DP_RED=(");
49 | for (int i=0;i<3;i++) { System.out.println((i==0?"":",")+f[i]);}
50 | */
51 |
52 | dualshade= new ColorModel( ColorModel.DUALSHADE, RED_H , RED_S , RED_B , 0.4f , 1f );
53 | grayscale= new ColorModel( ColorModel.DUALSHADE, 0f , 0f , 0f , 0f , 1f );
54 | spectrum= new ColorModel( ColorModel.SPECTRUM , 0f , 1f , 1f , 0f , .6666f );
55 | fog= new ColorModel( ColorModel.FOG , RED_H , RED_S , RED_B , 0f , 1f );
56 | opaque= new ColorModel( ColorModel.OPAQUE , RED_H , 0.1f , 1f , 0f , 0f );
57 |
58 |
59 |
60 | alt_dualshade= new ColorModel( ColorModel.DUALSHADE, GOLD_H , GOLD_S , GOLD_B , 0.4f , 1f );
61 | alt_grayscale= new ColorModel( ColorModel.DUALSHADE, 0f , 0f , 0f , 0f , 1f );
62 | alt_spectrum= new ColorModel( ColorModel.SPECTRUM , 0f , 1f , 0.8f , 0f , .6666f );
63 | alt_fog= new ColorModel( ColorModel.FOG , GOLD_H , 0f , GOLD_B , 0f , 1f );
64 | alt_opaque= new ColorModel( ColorModel.OPAQUE , GOLD_H , 0.1f , 1f , 0f , 0f );
65 |
66 | }
67 |
68 | protected PlotColor color_mode= PlotColor.SPECTRUM;
69 | public void setPlotColor(PlotColor v)
70 | {
71 | this.color_mode=v;
72 | }
73 | protected PlotType plot_mode= PlotType.CONTOUR;
74 | public void setPlotType(PlotType type)
75 | {
76 | this.plot_mode=type;
77 | }
78 |
79 | /* (non-Javadoc)
80 | * @see net.ericaro.surfaceplotter.SurfaceColor#getBackgroundColor()
81 | */
82 | public Color getBackgroundColor(){return lightColor;}
83 | /* (non-Javadoc)
84 | * @see net.ericaro.surfaceplotter.SurfaceColor#getLineBoxColor()
85 | */
86 | public Color getLineBoxColor() {return lineboxColor;}
87 | /* (non-Javadoc)
88 | * @see net.ericaro.surfaceplotter.SurfaceColor#getBoxColor()
89 | */
90 | public Color getBoxColor() {return boxColor;}
91 | /* (non-Javadoc)
92 | * @see net.ericaro.surfaceplotter.SurfaceColor#getLineColor()
93 | */
94 | public Color getLineColor(){return lineColor;}
95 | /* (non-Javadoc)
96 | * @see net.ericaro.surfaceplotter.SurfaceColor#getTextColor()
97 | */
98 | public Color getTextColor() {return lineColor;}
99 |
100 | /* (non-Javadoc)
101 | * @see net.ericaro.surfaceplotter.SurfaceColor#getLineColor(int, float)
102 | */
103 | public Color getLineColor(int curve, float z)
104 | {
105 | return Color.BLACK;
106 | //return Color.BLUE;
107 | /**
108 | if (plot_mode==PlotType.WIREFRAME)
109 | {
110 | return Color.BLACK;
111 | }
112 | return getPolygonColor(curve, 1-z);
113 | /*
114 | if (
115 | color_mode==PlotColor.GRAYSCALE ||
116 | color_mode==PlotColor.SPECTRUM||
117 | color_mode==PlotColor.DUALSHADE)
118 | return grayscale.getPolygonColor(1-z);
119 | else return Color.DARK_GRAY;
120 | */
121 | /*
122 | Color c= getPolygonColor(curve, z);
123 | float[] f= c.getComponents(new float[4]);
124 | float ff=f[2];
125 | if (ff<0.5f) ff=1f;
126 | if (ff<0) ff++;
127 | */
128 | //return Color.getHSBColor(f[0],f[1],ff);
129 | /**/
130 | }
131 |
132 | /* (non-Javadoc)
133 | * @see net.ericaro.surfaceplotter.SurfaceColor#getPolygonColor(int, float)
134 | */
135 | public Color getPolygonColor(int curve, float z)
136 | {
137 | if (curve==1) return getFirstPolygonColor(z);
138 | if (curve==2) return getSecondPolygonColor(z);
139 | return Color.blue;
140 | }
141 |
142 | /* (non-Javadoc)
143 | * @see net.ericaro.surfaceplotter.SurfaceColor#getFirstPolygonColor(float)
144 | */
145 | public Color getFirstPolygonColor(float z)
146 | {
147 | //contour,density plot does not fit with opaque color
148 | if(plot_mode==PlotType.CONTOUR ||plot_mode==PlotType.DENSITY)
149 | {
150 | if (color_mode==PlotColor.OPAQUE)
151 | return dualshade.getPolygonColor(z);
152 | }
153 |
154 | switch ( color_mode)
155 | {
156 | case OPAQUE :return opaque.getPolygonColor(z);
157 | case GRAYSCALE :return grayscale.getPolygonColor(z);
158 | case SPECTRUM :return spectrum.getPolygonColor(z);
159 | case DUALSHADE :return dualshade.getPolygonColor(z);
160 | case FOG :return fog.getPolygonColor(z);
161 | default: return Color.blue;
162 | }
163 | }
164 |
165 | /* (non-Javadoc)
166 | * @see net.ericaro.surfaceplotter.SurfaceColor#getSecondPolygonColor(float)
167 | */
168 | public Color getSecondPolygonColor(float z)
169 | {
170 | //contour,density plot does not fit with opaque color
171 | if(plot_mode==PlotType.CONTOUR ||plot_mode==PlotType.DENSITY)
172 | {
173 | if (color_mode==PlotColor.OPAQUE)
174 | return alt_dualshade.getPolygonColor(z);
175 | }
176 | switch ( color_mode)
177 | {
178 | case OPAQUE :return alt_opaque.getPolygonColor(z);
179 | case GRAYSCALE :return alt_grayscale.getPolygonColor(z);
180 | case SPECTRUM :return alt_spectrum.getPolygonColor(z);
181 | case DUALSHADE :return alt_dualshade.getPolygonColor(z);
182 | case FOG :return alt_fog.getPolygonColor(z);
183 | default: return Color.blue;
184 | }
185 | }
186 |
187 | /*
188 | protected float dualshadeColorFirstHue=0.2f;//0.7f;//0.1f;//0.941f; // first curve hue color
189 | protected float dualshadeColorSecondHue=0.7f;
190 | protected float dualshadeSaturation = 0.9125f;//0.604f; //
191 | protected float dualshadeOffset=0.3f;
192 | protected float whiteblack = 0.3f;
193 |
194 |
195 | */
196 |
197 | }//end of class
198 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 | 14 | * It allocate an HD array , and start with a single face, then 4, then 16 etc. until reaching the goal HD definition. 15 | *
16 | * This defines the 17 | * 18 | *
19 | * def 20 | *21 | * 22 | * variable: def=0 means 1 face, def=1 means 4 faces etc. 23 | */ 24 | public class ProgressiveSurfaceModel extends AbstractSurfaceModel implements SurfaceModel { 25 | 26 | protected SurfaceVertex[][] highDefinitionVertex; 27 | protected SurfaceVertex[][] surfaceVertex; 28 | protected Mapper mapper; 29 | int currentDefinition = -1; 30 | int availableDefinition = -1; 31 | int maxDefinition = 6; 32 | 33 | /** 34 | * Empty Surface Model 35 | */ 36 | public ProgressiveSurfaceModel() { 37 | super(); 38 | } 39 | 40 | public void setMapper(Mapper mapper) { 41 | this.mapper = mapper; 42 | } 43 | 44 | 45 | public SwingWorker
Projector projects points in 3D space to 2D space.
29 | *
30 | * @author Yanto Suryono
31 | */
32 |
33 | public final class Projector {
34 | private float scale_x, scale_y, scale_z; // 3D scaling factor
35 | private float distance; // distance to object
36 | private float _2D_scale; // 2D scaling factor
37 | private float rotation, elevation; // rotation and elevation angle
38 | private float sin_rotation, cos_rotation; // sin and cos of rotation angle
39 | private float sin_elevation, cos_elevation; // sin and cos of elevation angle
40 | private int _2D_trans_x, _2D_trans_y; // 2D translation
41 | private int x1, x2, y1, y2; // projection area
42 | private int center_x, center_y; // center of projection area
43 |
44 | private int trans_x, trans_y;
45 | private float factor;
46 | private float sx_cos, sy_cos, sz_cos;
47 | private float sx_sin, sy_sin, sz_sin;
48 |
49 | private final float DEGTORAD = (float)Math.PI / 180;
50 |
51 | //was static in SurfaceVertex ! now Dynamic in Projector
52 | float zmin, zmax;
53 | float zfactor;
54 |
55 |
56 | /**
57 | * The constructor of Projector.
58 | */
59 |
60 | public Projector() {
61 | setScaling(1);
62 | setRotationAngle(0);
63 | setElevationAngle(0);
64 | setDistance(10);
65 | set2DScaling(1);
66 | set2DTranslation(0,0);
67 | }
68 |
69 | /**
70 | * Sets the projection area.
71 | *
72 | * @param r the projection area
73 | */
74 |
75 | public void setProjectionArea(Rectangle r) {
76 | x1 = r.x; x2 = x1 + r.width;
77 | y1 = r.y; y2 = y1 + r.height;
78 | center_x = (x1 + x2) / 2;
79 | center_y = (y1 + y2) / 2;
80 |
81 | trans_x = center_x + _2D_trans_x;
82 | trans_y = center_y + _2D_trans_y;
83 | }
84 |
85 | /**
86 | * Sets the rotation angle.
87 | *
88 | * @param angle the rotation angle in degrees
89 | */
90 |
91 | public void setRotationAngle(float angle) {
92 | rotation = angle;
93 | sin_rotation = (float)Math.sin(angle * DEGTORAD);
94 | cos_rotation = (float)Math.cos(angle * DEGTORAD);
95 |
96 | sx_cos = -scale_x * cos_rotation;
97 | sx_sin = -scale_x * sin_rotation;
98 | sy_cos = -scale_y * cos_rotation;
99 | sy_sin = scale_y * sin_rotation;
100 | }
101 |
102 | /**
103 | * Gets current rotation angle.
104 | *
105 | * @return the rotation angle in degrees.
106 | */
107 |
108 | public float getRotationAngle() {
109 | return rotation;
110 | }
111 |
112 | /**
113 | * Gets the sine of rotation angle.
114 | *
115 | * @return the sine of rotation angle
116 | */
117 |
118 | public float getSinRotationAngle() {
119 | return sin_rotation;
120 | }
121 |
122 | /**
123 | * Gets the cosine of rotation angle.
124 | *
125 | * @return the cosine of rotation angle
126 | */
127 |
128 | public float getCosRotationAngle() {
129 | return cos_rotation;
130 | }
131 |
132 | /**
133 | * Sets the elevation angle.
134 | *
135 | * @param angle the elevation angle in degrees
136 | */
137 |
138 | public void setElevationAngle(float angle) {
139 | elevation = angle;
140 | sin_elevation = (float)Math.sin(angle * DEGTORAD);
141 | cos_elevation = (float)Math.cos(angle * DEGTORAD);
142 | sz_cos = scale_z * cos_elevation;
143 | sz_sin = scale_z * sin_elevation;
144 | }
145 |
146 | /**
147 | * Gets current elevation angle.
148 | *
149 | * @return the elevation angle in degrees.
150 | */
151 |
152 | public float getElevationAngle() {
153 | return elevation;
154 | }
155 |
156 | /**
157 | * Gets the sine of elevation angle.
158 | *
159 | * @return the sine of elevation angle
160 | */
161 |
162 | public float getSinElevationAngle() {
163 | return sin_elevation;
164 | }
165 |
166 | /**
167 | * Gets the cosine of elevation angle.
168 | *
169 | * @return the cosine of elevation angle
170 | */
171 |
172 | public float getCosElevationAngle() {
173 | return cos_elevation;
174 | }
175 |
176 | /**
177 | * Sets the projector distance.
178 | *
179 | * @param new_distance the new distance
180 | */
181 |
182 | public void setDistance(float new_distance) {
183 | distance = new_distance;
184 | factor = distance * _2D_scale;
185 | }
186 |
187 | /**
188 | * Gets the projector distance.
189 | *
190 | * @return the projector distance
191 | */
192 |
193 | public float getDistance() {
194 | return distance;
195 | }
196 |
197 | /**
198 | * Sets the scaling factor in x direction.
199 | *
200 | * @param scaling the scaling factor
201 | */
202 |
203 | public void setXScaling(float scaling) {
204 | scale_x = scaling;
205 | sx_cos = -scale_x * cos_rotation;
206 | sx_sin = -scale_x * sin_rotation;
207 | }
208 |
209 | /**
210 | * Gets the scaling factor in x direction.
211 | *
212 | * @return the scaling factor
213 | */
214 |
215 | public float getXScaling() {
216 | return scale_x;
217 | }
218 |
219 | /**
220 | * Sets the scaling factor in y direction.
221 | *
222 | * @param scaling the scaling factor
223 | */
224 |
225 | public void setYScaling(float scaling) {
226 | scale_y = scaling;
227 | sy_cos = -scale_y * cos_rotation;
228 | sy_sin = scale_y * sin_rotation;
229 | }
230 |
231 | /**
232 | * Gets the scaling factor in y direction.
233 | *
234 | * @return the scaling factor
235 | */
236 |
237 | public float getYScaling() {
238 | return scale_y;
239 | }
240 |
241 | /**
242 | * Sets the scaling factor in z direction.
243 | *
244 | * @param scaling the scaling factor
245 | */
246 |
247 | public void setZScaling(float scaling) {
248 | scale_z = scaling;
249 | sz_cos = scale_z * cos_elevation;
250 | sz_sin = scale_z * sin_elevation;
251 | }
252 |
253 | /**
254 | * Gets the scaling factor in z direction.
255 | *
256 | * @return the scaling factor
257 | */
258 |
259 | public float getZScaling() {
260 | return scale_z;
261 | }
262 |
263 | /**
264 | * Sets the scaling factor in all direction.
265 | *
266 | * @param x the scaling factor in x direction
267 | * @param y the scaling factor in y direction
268 | * @param z the scaling factor in z direction
269 | */
270 |
271 | public void setScaling(float x, float y, float z) {
272 | scale_x = x; scale_y = y; scale_z = z;
273 |
274 | sx_cos = -scale_x * cos_rotation;
275 | sx_sin = -scale_x * sin_rotation;
276 | sy_cos = -scale_y * cos_rotation;
277 | sy_sin = scale_y * sin_rotation;
278 | sz_cos = scale_z * cos_elevation;
279 | sz_sin = scale_z * sin_elevation;
280 | }
281 |
282 | /**
283 | * Sets the same scaling factor for all direction.
284 | *
285 | * @param scaling the scaling factor
286 | */
287 |
288 | public void setScaling(float scaling) {
289 | scale_x = scale_y = scale_z = scaling;
290 |
291 | sx_cos = -scale_x * cos_rotation;
292 | sx_sin = -scale_x * sin_rotation;
293 | sy_cos = -scale_y * cos_rotation;
294 | sy_sin = scale_y * sin_rotation;
295 | sz_cos = scale_z * cos_elevation;
296 | sz_sin = scale_z * sin_elevation;
297 | }
298 |
299 | /**
300 | * Sets the 2D scaling factor.
301 | *
302 | * @param scaling the scaling factor
303 | */
304 |
305 | public void set2DScaling(float scaling) {
306 | _2D_scale = scaling;
307 | factor = distance * _2D_scale;
308 | }
309 |
310 | /**
311 | * Gets the 2D scaling factor.
312 | *
313 | * @return the scaling factor
314 | */
315 |
316 | public float get2DScaling() {
317 | return _2D_scale;
318 | }
319 |
320 | /**
321 | * Sets the 2D translation.
322 | *
323 | * @param x the x translation
324 | * @param y the y translation
325 | */
326 |
327 | public void set2DTranslation(int x, int y) {
328 | _2D_trans_x = x; _2D_trans_y = y;
329 |
330 | trans_x = center_x + _2D_trans_x;
331 | trans_y = center_y + _2D_trans_y;
332 | }
333 |
334 | /**
335 | * Sets the 2D x translation.
336 | *
337 | * @param x the x translation
338 | */
339 |
340 | public void set2D_xTranslation(int x) {
341 | _2D_trans_x = x;
342 | trans_x = center_x + _2D_trans_x;
343 | }
344 |
345 | /**
346 | * Gets the 2D x translation.
347 | *
348 | * @return the x translation
349 | */
350 |
351 | public int get2D_xTranslation() {
352 | return _2D_trans_x;
353 | }
354 |
355 | /**
356 | * Sets the 2D y translation.
357 | *
358 | * @param y the y translation
359 | */
360 |
361 | public void set2D_yTranslation(int y) {
362 | _2D_trans_y = y;
363 | trans_y = center_y + _2D_trans_y;
364 | }
365 |
366 | /**
367 | * Gets the 2D y translation.
368 | *
369 | * @return the y translation
370 | */
371 |
372 | public int get2D_yTranslation() {
373 | return _2D_trans_y;
374 | }
375 |
376 | /**
377 | * Projects 3D points.
378 | *
379 | * @param x the x coordinate
380 | * @param y the y coordinate
381 | * @param z the z coordinate
382 | */
383 |
384 | public final Point project(float x, float y, float z) {
385 | float temp;
386 |
387 | // rotates
388 |
389 | temp = x;
390 | x = x * sx_cos + y * sy_sin;
391 | y = temp * sx_sin + y * sy_cos;
392 |
393 | // elevates and projects
394 |
395 | temp = factor / (y * cos_elevation - z * sz_sin + distance);
396 | return new Point((int)(Math.round(x * temp) + trans_x),
397 | (int)(Math.round((y * sin_elevation + z * sz_cos) * -temp) + trans_y));
398 | }
399 |
400 |
401 |
402 | public void setZRange(float zmin, float zmax) {
403 | this.zmin = zmin; this.zmax = zmax;
404 | this.zfactor = 20/(zmax-zmin);
405 | }
406 |
407 | }
408 |
--------------------------------------------------------------------------------
/src/main/java/net/ericaro/surfaceplotter/surface/VerticalConfigurationPanel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by JFormDesigner on Thu Oct 07 17:39:55 CEST 2010
3 | */
4 |
5 | package net.ericaro.surfaceplotter.surface;
6 |
7 | import java.awt.Color;
8 | import java.awt.Font;
9 | import java.awt.GridBagConstraints;
10 | import java.awt.GridBagLayout;
11 | import java.awt.Insets;
12 | import java.util.ResourceBundle;
13 | import javax.swing.*;
14 |
15 | import javax.swing.ButtonGroup;
16 | import javax.swing.JLabel;
17 | import javax.swing.border.EmptyBorder;
18 |
19 | import net.ericaro.surfaceplotter.DefaultSurfaceModel;
20 | import net.ericaro.surfaceplotter.beans.JBindedCheckBox;
21 | import net.ericaro.surfaceplotter.beans.JBindedRadioButton;
22 | import net.ericaro.surfaceplotter.beans.JScrollablePanel;
23 | import net.ericaro.surfaceplotter.beans.ModelSource;
24 |
25 |
26 | /** A Vertical Configuration panel for the {@link DefaultSurfaceModel}.
27 | * @author eric
28 | */
29 | public class VerticalConfigurationPanel extends JScrollablePanel {
30 | public VerticalConfigurationPanel() {
31 | initComponents();
32 | }
33 |
34 | public void setModel(AbstractSurfaceModel model) {
35 | modelSource1.setSurfaceModel(model);
36 | }
37 |
38 |
39 |
40 | private void initComponents() {
41 | // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
42 | ResourceBundle bundle = ResourceBundle.getBundle("net.ericaro.surfaceplotter.surface.VerticalConfigurationPanel");
43 | label1 = new JLabel();
44 | boxed = new JBindedCheckBox();
45 | scaleBox = new JBindedCheckBox();
46 | label3 = new JLabel();
47 | displayXY = new JBindedCheckBox();
48 | displayZ = new JBindedCheckBox();
49 | label6 = new JLabel();
50 | displayGrids = new JBindedCheckBox();
51 | mesh = new JBindedCheckBox();
52 | expectDelay = new JBindedCheckBox();
53 | label4 = new JLabel();
54 | hiddenMode = new JBindedRadioButton();
55 | spectrumMode = new JBindedRadioButton();
56 | grayScaleMode = new JBindedRadioButton();
57 | dualShadeMode = new JBindedRadioButton();
58 | fogMode = new JBindedRadioButton();
59 | label5 = new JLabel();
60 | wireframeType = new JBindedRadioButton();
61 | surfaceType = new JBindedRadioButton();
62 | contourType = new JBindedRadioButton();
63 | densityType = new JBindedRadioButton();
64 | label2 = new JLabel();
65 | firstFunctionOnly = new JBindedRadioButton();
66 | secondFunctionOnly = new JBindedRadioButton();
67 | bothFunction = new JBindedRadioButton();
68 | modelSource1 = new ModelSource();
69 | abstractSurfaceModel1 = new DefaultSurfaceModel();
70 |
71 | //======== this ========
72 | setBorder(new EmptyBorder(6, 6, 6, 6));
73 | setBackground(Color.white);
74 | setAlignmentY(0.0F);
75 | setLayout(new GridBagLayout());
76 | ((GridBagLayout)getLayout()).columnWidths = new int[] {6, 0, 0};
77 | ((GridBagLayout)getLayout()).rowHeights = new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
78 | ((GridBagLayout)getLayout()).columnWeights = new double[] {0.0, 1.0, 1.0E-4};
79 | ((GridBagLayout)getLayout()).rowWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0E-4};
80 |
81 | //---- label1 ----
82 | label1.setText(bundle.getString("label1.text"));
83 | label1.setFont(label1.getFont().deriveFont(label1.getFont().getStyle() | Font.BOLD));
84 | label1.setBackground(Color.white);
85 | add(label1, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
86 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
87 | new Insets(6, 0, 0, 0), 0, 0));
88 |
89 | //---- boxed ----
90 | boxed.setText(bundle.getString("boxed.text"));
91 | boxed.setBackground(Color.white);
92 | boxed.setSourceBean(modelSource1);
93 | boxed.setPropertyName("boxed");
94 | boxed.setMargin(new Insets(0, 0, 0, 0));
95 | add(boxed, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
96 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
97 | new Insets(0, 0, 0, 0), 0, 0));
98 |
99 | //---- scaleBox ----
100 | scaleBox.setText(bundle.getString("scaleBox.text"));
101 | scaleBox.setBackground(Color.white);
102 | scaleBox.setSourceBean(modelSource1);
103 | scaleBox.setPropertyName("scaleBox");
104 | scaleBox.setMargin(new Insets(0, 0, 0, 0));
105 | add(scaleBox, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0,
106 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
107 | new Insets(0, 0, 0, 0), 0, 0));
108 |
109 | //---- label3 ----
110 | label3.setText(bundle.getString("label3.text"));
111 | label3.setFont(label3.getFont().deriveFont(label3.getFont().getStyle() | Font.BOLD));
112 | label3.setBackground(Color.white);
113 | add(label3, new GridBagConstraints(0, 3, 2, 1, 0.0, 0.0,
114 | GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
115 | new Insets(6, 0, 0, 0), 0, 0));
116 |
117 | //---- displayXY ----
118 | displayXY.setText(bundle.getString("displayXY.text"));
119 | displayXY.setBackground(Color.white);
120 | displayXY.setSourceBean(modelSource1);
121 | displayXY.setPropertyName("displayXY");
122 | displayXY.setMargin(new Insets(0, 0, 0, 0));
123 | add(displayXY, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0,
124 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
125 | new Insets(0, 0, 0, 0), 0, 0));
126 |
127 | //---- displayZ ----
128 | displayZ.setText(bundle.getString("displayZ.text"));
129 | displayZ.setBackground(Color.white);
130 | displayZ.setSourceBean(modelSource1);
131 | displayZ.setPropertyName("displayZ");
132 | displayZ.setMargin(new Insets(0, 0, 0, 0));
133 | add(displayZ, new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0,
134 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
135 | new Insets(0, 0, 0, 0), 0, 0));
136 |
137 | //---- label6 ----
138 | label6.setText(bundle.getString("label6.text"));
139 | label6.setFont(label6.getFont().deriveFont(label6.getFont().getStyle() | Font.BOLD));
140 | label6.setBackground(Color.white);
141 | add(label6, new GridBagConstraints(0, 6, 2, 1, 0.0, 0.0,
142 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
143 | new Insets(6, 0, 0, 0), 0, 0));
144 |
145 | //---- displayGrids ----
146 | displayGrids.setText(bundle.getString("displayGrids.text"));
147 | displayGrids.setBackground(Color.white);
148 | displayGrids.setSourceBean(modelSource1);
149 | displayGrids.setPropertyName("displayGrids");
150 | displayGrids.setMargin(new Insets(0, 0, 0, 0));
151 | add(displayGrids, new GridBagConstraints(1, 7, 1, 1, 0.0, 0.0,
152 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
153 | new Insets(0, 0, 0, 0), 0, 0));
154 |
155 | //---- mesh ----
156 | mesh.setText(bundle.getString("mesh.text"));
157 | mesh.setBackground(Color.white);
158 | mesh.setSourceBean(modelSource1);
159 | mesh.setPropertyName("mesh");
160 | mesh.setMargin(new Insets(0, 0, 0, 0));
161 | add(mesh, new GridBagConstraints(1, 8, 1, 1, 0.0, 0.0,
162 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
163 | new Insets(0, 0, 0, 0), 0, 0));
164 |
165 | //---- expectDelay ----
166 | expectDelay.setText(bundle.getString("expectDelay.text"));
167 | expectDelay.setBackground(Color.white);
168 | expectDelay.setSourceBean(modelSource1);
169 | expectDelay.setPropertyName("expectDelay");
170 | expectDelay.setMargin(new Insets(0, 0, 0, 0));
171 | add(expectDelay, new GridBagConstraints(1, 9, 1, 1, 0.0, 0.0,
172 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
173 | new Insets(0, 0, 0, 0), 0, 0));
174 |
175 | //---- label4 ----
176 | label4.setText(bundle.getString("label4.text"));
177 | label4.setFont(label4.getFont().deriveFont(label4.getFont().getStyle() | Font.BOLD));
178 | label4.setBackground(Color.white);
179 | add(label4, new GridBagConstraints(0, 10, 2, 1, 0.0, 0.0,
180 | GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
181 | new Insets(6, 0, 0, 0), 0, 0));
182 |
183 | //---- hiddenMode ----
184 | hiddenMode.setText(bundle.getString("hiddenMode.text"));
185 | hiddenMode.setBackground(Color.white);
186 | hiddenMode.setSourceBean(modelSource1);
187 | hiddenMode.setPropertyName("hiddenMode");
188 | hiddenMode.setMargin(new Insets(0, 0, 0, 0));
189 | add(hiddenMode, new GridBagConstraints(1, 11, 1, 1, 0.0, 0.0,
190 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
191 | new Insets(0, 0, 0, 0), 0, 0));
192 |
193 | //---- spectrumMode ----
194 | spectrumMode.setText(bundle.getString("spectrumMode.text"));
195 | spectrumMode.setBackground(Color.white);
196 | spectrumMode.setSourceBean(modelSource1);
197 | spectrumMode.setPropertyName("spectrumMode");
198 | spectrumMode.setMargin(new Insets(0, 0, 0, 0));
199 | add(spectrumMode, new GridBagConstraints(1, 12, 1, 1, 0.0, 0.0,
200 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
201 | new Insets(0, 0, 0, 0), 0, 0));
202 |
203 | //---- grayScaleMode ----
204 | grayScaleMode.setText(bundle.getString("grayScaleMode.text"));
205 | grayScaleMode.setBackground(Color.white);
206 | grayScaleMode.setSourceBean(modelSource1);
207 | grayScaleMode.setPropertyName("grayScaleMode");
208 | grayScaleMode.setMargin(new Insets(0, 0, 0, 0));
209 | add(grayScaleMode, new GridBagConstraints(1, 13, 1, 1, 0.0, 0.0,
210 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
211 | new Insets(0, 0, 0, 0), 0, 0));
212 |
213 | //---- dualShadeMode ----
214 | dualShadeMode.setText(bundle.getString("dualShadeMode.text"));
215 | dualShadeMode.setBackground(Color.white);
216 | dualShadeMode.setSourceBean(modelSource1);
217 | dualShadeMode.setPropertyName("dualShadeMode");
218 | dualShadeMode.setMargin(new Insets(0, 0, 0, 0));
219 | add(dualShadeMode, new GridBagConstraints(1, 14, 1, 1, 0.0, 0.0,
220 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
221 | new Insets(0, 0, 0, 0), 0, 0));
222 |
223 | //---- fogMode ----
224 | fogMode.setText(bundle.getString("fogMode.text"));
225 | fogMode.setBackground(Color.white);
226 | fogMode.setSourceBean(modelSource1);
227 | fogMode.setPropertyName("fogMode");
228 | fogMode.setMargin(new Insets(0, 0, 0, 0));
229 | add(fogMode, new GridBagConstraints(1, 15, 1, 1, 0.0, 0.0,
230 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
231 | new Insets(0, 0, 0, 0), 0, 0));
232 |
233 | //---- label5 ----
234 | label5.setText(bundle.getString("label5.text"));
235 | label5.setFont(label5.getFont().deriveFont(label5.getFont().getStyle() | Font.BOLD));
236 | label5.setBackground(Color.white);
237 | add(label5, new GridBagConstraints(0, 16, 2, 1, 0.0, 0.0,
238 | GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
239 | new Insets(6, 0, 0, 0), 0, 0));
240 |
241 | //---- wireframeType ----
242 | wireframeType.setText(bundle.getString("wireframeType.text"));
243 | wireframeType.setBackground(Color.white);
244 | wireframeType.setSourceBean(modelSource1);
245 | wireframeType.setPropertyName("wireframeType");
246 | wireframeType.setMargin(new Insets(0, 0, 0, 0));
247 | add(wireframeType, new GridBagConstraints(1, 17, 1, 1, 0.0, 0.0,
248 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
249 | new Insets(0, 0, 0, 0), 0, 0));
250 |
251 | //---- surfaceType ----
252 | surfaceType.setText(bundle.getString("surfaceType.text"));
253 | surfaceType.setBackground(Color.white);
254 | surfaceType.setSourceBean(modelSource1);
255 | surfaceType.setPropertyName("surfaceType");
256 | surfaceType.setMargin(new Insets(0, 0, 0, 0));
257 | add(surfaceType, new GridBagConstraints(1, 18, 1, 1, 0.0, 0.0,
258 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
259 | new Insets(0, 0, 0, 0), 0, 0));
260 |
261 | //---- contourType ----
262 | contourType.setText(bundle.getString("contourType.text"));
263 | contourType.setBackground(Color.white);
264 | contourType.setSourceBean(modelSource1);
265 | contourType.setPropertyName("contourType");
266 | contourType.setMargin(new Insets(0, 0, 0, 0));
267 | add(contourType, new GridBagConstraints(1, 19, 1, 1, 0.0, 0.0,
268 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
269 | new Insets(0, 0, 0, 0), 0, 0));
270 |
271 | //---- densityType ----
272 | densityType.setText(bundle.getString("densityType.text"));
273 | densityType.setBackground(Color.white);
274 | densityType.setSourceBean(modelSource1);
275 | densityType.setPropertyName("densityType");
276 | densityType.setMargin(new Insets(0, 0, 0, 0));
277 | add(densityType, new GridBagConstraints(1, 20, 1, 1, 0.0, 0.0,
278 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
279 | new Insets(0, 0, 0, 0), 0, 0));
280 |
281 | //---- label2 ----
282 | label2.setText(bundle.getString("label2.text"));
283 | label2.setFont(label2.getFont().deriveFont(label2.getFont().getStyle() | Font.BOLD));
284 | label2.setBackground(Color.white);
285 | add(label2, new GridBagConstraints(0, 21, 2, 1, 0.0, 0.0,
286 | GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
287 | new Insets(6, 0, 0, 0), 0, 0));
288 |
289 | //---- firstFunctionOnly ----
290 | firstFunctionOnly.setText(bundle.getString("firstFunctionOnly.text"));
291 | firstFunctionOnly.setBackground(Color.white);
292 | firstFunctionOnly.setSourceBean(modelSource1);
293 | firstFunctionOnly.setPropertyName("firstFunctionOnly");
294 | firstFunctionOnly.setProperty(true);
295 | firstFunctionOnly.setMargin(new Insets(0, 0, 0, 0));
296 | add(firstFunctionOnly, new GridBagConstraints(1, 22, 1, 1, 0.0, 0.0,
297 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
298 | new Insets(0, 0, 0, 0), 0, 0));
299 |
300 | //---- secondFunctionOnly ----
301 | secondFunctionOnly.setText(bundle.getString("secondFunctionOnly.text"));
302 | secondFunctionOnly.setBackground(Color.white);
303 | secondFunctionOnly.setSourceBean(modelSource1);
304 | secondFunctionOnly.setPropertyName("secondFunctionOnly");
305 | secondFunctionOnly.setProperty(true);
306 | secondFunctionOnly.setMargin(new Insets(0, 0, 0, 0));
307 | add(secondFunctionOnly, new GridBagConstraints(1, 23, 1, 1, 0.0, 0.0,
308 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
309 | new Insets(0, 0, 0, 0), 0, 0));
310 |
311 | //---- bothFunction ----
312 | bothFunction.setText(bundle.getString("bothFunction.text"));
313 | bothFunction.setBackground(Color.white);
314 | bothFunction.setSourceBean(modelSource1);
315 | bothFunction.setPropertyName("bothFunction");
316 | bothFunction.setMargin(new Insets(0, 0, 0, 0));
317 | add(bothFunction, new GridBagConstraints(1, 24, 1, 1, 0.0, 0.0,
318 | GridBagConstraints.CENTER, GridBagConstraints.BOTH,
319 | new Insets(0, 0, 0, 0), 0, 0));
320 |
321 | //---- modelSource1 ----
322 | modelSource1.setSurfaceModel(abstractSurfaceModel1);
323 |
324 | //---- abstractSurfaceModel1 ----
325 | abstractSurfaceModel1.setSecondFunctionOnly(true);
326 |
327 | //---- buttonGroup1 ----
328 | ButtonGroup buttonGroup1 = new ButtonGroup();
329 | buttonGroup1.add(hiddenMode);
330 | buttonGroup1.add(spectrumMode);
331 | buttonGroup1.add(grayScaleMode);
332 | buttonGroup1.add(dualShadeMode);
333 | buttonGroup1.add(fogMode);
334 |
335 | //---- buttonGroup2 ----
336 | ButtonGroup buttonGroup2 = new ButtonGroup();
337 | buttonGroup2.add(wireframeType);
338 | buttonGroup2.add(surfaceType);
339 | buttonGroup2.add(contourType);
340 | buttonGroup2.add(densityType);
341 |
342 | //---- buttonGroup3 ----
343 | ButtonGroup buttonGroup3 = new ButtonGroup();
344 | buttonGroup3.add(firstFunctionOnly);
345 | buttonGroup3.add(secondFunctionOnly);
346 | buttonGroup3.add(bothFunction);
347 | // JFormDesigner - End of component initialization //GEN-END:initComponents
348 | }
349 |
350 | // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
351 | private JLabel label1;
352 | private JBindedCheckBox boxed;
353 | private JBindedCheckBox scaleBox;
354 | private JLabel label3;
355 | private JBindedCheckBox displayXY;
356 | private JBindedCheckBox displayZ;
357 | private JLabel label6;
358 | private JBindedCheckBox displayGrids;
359 | private JBindedCheckBox mesh;
360 | private JBindedCheckBox expectDelay;
361 | private JLabel label4;
362 | private JBindedRadioButton hiddenMode;
363 | private JBindedRadioButton spectrumMode;
364 | private JBindedRadioButton grayScaleMode;
365 | private JBindedRadioButton dualShadeMode;
366 | private JBindedRadioButton fogMode;
367 | private JLabel label5;
368 | private JBindedRadioButton wireframeType;
369 | private JBindedRadioButton surfaceType;
370 | private JBindedRadioButton contourType;
371 | private JBindedRadioButton densityType;
372 | private JLabel label2;
373 | private JBindedRadioButton firstFunctionOnly;
374 | private JBindedRadioButton secondFunctionOnly;
375 | private JBindedRadioButton bothFunction;
376 | private ModelSource modelSource1;
377 | private DefaultSurfaceModel abstractSurfaceModel1;
378 | // JFormDesigner - End of variables declaration //GEN-END:variables
379 | }
380 |
--------------------------------------------------------------------------------
/src/main/java/net/ericaro/surfaceplotter/surface/AbstractSurfaceModel.java:
--------------------------------------------------------------------------------
1 | package net.ericaro.surfaceplotter.surface;
2 |
3 | import java.beans.PropertyChangeSupport;
4 | import java.io.File;
5 | import java.io.IOException;
6 |
7 | import javax.swing.event.ChangeEvent;
8 | import javax.swing.event.ChangeListener;
9 | import javax.swing.event.EventListenerList;
10 | import javax.swing.event.SwingPropertyChangeSupport;
11 |
12 | import net.ericaro.surfaceplotter.Mapper;
13 |
14 | /** Abstract implementation that handles everything but the surfaceVertex array
15 | *
16 | * @author eric
17 | *
18 | */
19 | public abstract class AbstractSurfaceModel implements SurfaceModel{
20 |
21 | /**
22 | * Interface returned by this object to write values in this model
23 | *
24 | * @author eric
25 | */
26 | public interface Plotter {
27 | public int getHeight();
28 |
29 | public int getWidth();
30 |
31 | public float getX(int i);
32 |
33 | public float getY(int j);
34 |
35 | public void setValue(int i, int j, float v1, float v2);
36 |
37 | }
38 | /**
39 | * internally used to ceil values
40 | *
41 | * @param d
42 | * @param digits
43 | * @return
44 | */
45 | public static synchronized double ceil(double d, int digits) {
46 | if (d == 0)
47 | return d;
48 | long og = (long) Math.ceil((Math.log(Math.abs(d)) / Math.log(10)));
49 | double factor = Math.pow(10, digits - og);
50 | double res = Math.ceil((d * factor)) / factor;
51 | return res;
52 | }
53 |
54 | /**
55 | * internally used to floor values
56 | *
57 | * @param d
58 | * @param digits
59 | * @return
60 | */
61 | public static synchronized double floor(double d, int digits) {
62 | if (d == 0)
63 | return d;
64 | // computes order of magnitude
65 | long og = (long) Math.ceil((Math.log(Math.abs(d)) / Math.log(10)));
66 |
67 | double factor = Math.pow(10, digits - og);
68 | // the matissa
69 | double res = Math.floor((d * factor)) / factor;
70 | // res contains the closed power of ten
71 | return res;
72 | }
73 |
74 | private static final int INIT_CALC_DIV = 20;
75 | private static final int INIT_DISP_DIV = 20;
76 |
77 |
78 | protected boolean autoScaleZ = true;
79 |
80 |
81 | /**
82 | * Determines whether to show bounding box.
83 | *
84 | * @return true if to show bounding box
85 | */
86 | protected boolean boxed;
87 | protected int calcDivisions = INIT_CALC_DIV;
88 | protected ColorModelSet colorModel;
89 | protected int contourLines;
90 | /**
91 | * Sets data availability flag
92 | */
93 | protected boolean dataAvailable;
94 | protected int dispDivisions = INIT_DISP_DIV;
95 | /**
96 | * Determines whether to show face grids.
97 | *
98 | * @return true if to show face grids
99 | */
100 | protected boolean displayGrids;
101 | /**
102 | * Determines whether to show x-y ticks.
103 | *
104 | * @return true if to show x-y ticks
105 | */
106 | protected boolean displayXY;
107 |
108 | /**
109 | * Determines whether to show z ticks.
110 | *
111 | * @return true if to show z ticks
112 | */
113 | protected boolean displayZ;
114 |
115 | /**
116 | * Determines whether the delay regeneration checkbox is checked.
117 | *
118 | * @return true if the checkbox is checked, false otherwise
119 | */
120 | protected boolean expectDelay = false;
121 |
122 | /**
123 | * Determines whether the first function is selected.
124 | *
125 | * @return true if the first function is checked, false otherwise
126 | */
127 |
128 | protected boolean hasFunction1 = true;
129 |
130 | /**
131 | * Determines whether the first function is selected.
132 | *
133 | * @return true if the first function is checked, false otherwise
134 | */
135 | protected boolean hasFunction2 = true;
136 |
137 | protected EventListenerList listenerList = new EventListenerList();
138 |
139 | /**
140 | * Determines whether to show x-y mesh.
141 | *
142 | * @return true if to show x-y mesh
143 | */
144 | protected boolean mesh;
145 |
146 | protected PlotColor plotColor;
147 |
148 | protected boolean plotFunction1 = hasFunction1;
149 |
150 | protected boolean plotFunction2 = hasFunction2;
151 |
152 | protected PlotType plotType = PlotType.SURFACE;
153 |
154 | private Projector projector;
155 |
156 | protected PropertyChangeSupport property;
157 |
158 | /**
159 | * Determines whether to scale axes and bounding box.
160 | *
161 | * @return true if to scale bounding box
162 | */
163 |
164 | protected boolean scaleBox;
165 |
166 | protected float xMax = 1f;
167 |
168 | protected float xMin;
169 | protected float yMax = 1f;
170 |
171 | protected float yMin;
172 | protected float z1Max;// the max computed
173 |
174 | protected float z1Min;// the min computed
175 | protected float z2Max;// the max computed
176 |
177 | protected float z2Min;// the min computed
178 | protected float zMax;
179 |
180 | protected float zMin;
181 |
182 | /**
183 | * Empty Surface Model
184 | */
185 | public AbstractSurfaceModel() {
186 | super();
187 | property = new SwingPropertyChangeSupport(this);
188 | setColorModel(new ColorModelSet());
189 |
190 | setCalcDivisions(50);
191 | setDispDivisions(50);
192 | setContourLines(10);
193 |
194 | setXMin(-3);
195 | setXMax(3);
196 | setYMin(-3);
197 | setYMax(3);
198 |
199 | setBoxed(false);
200 | setDisplayXY(false);
201 | setExpectDelay(false);
202 | setAutoScaleZ(true);
203 | setDisplayZ(false);
204 | setMesh(true);
205 | setPlotType(PlotType.SURFACE);
206 | setFirstFunctionOnly(true);
207 | setPlotColor(PlotColor.SPECTRUM);
208 | }
209 |
210 | public void addChangeListener(ChangeListener ol) {
211 | listenerList.add(ChangeListener.class, ol);
212 | }
213 |
214 | public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) {
215 | property.addPropertyChangeListener(listener);
216 | }
217 |
218 | public void addPropertyChangeListener(String propertyName, java.beans.PropertyChangeListener listener) {
219 | property.addPropertyChangeListener(propertyName, listener);
220 | }
221 |
222 |
223 |
224 | /**
225 | * Autoscale based on actual values
226 | */
227 | public void autoScale() {
228 | // compute auto scale and repaint
229 | if (!autoScaleZ)
230 | return;
231 | if (plotFunction1 && plotFunction2) {
232 | setZMin(Math.min(z1Min, z2Min));
233 | setZMax(Math.max(z1Max, z2Max));
234 | } else {
235 | if (plotFunction1) {
236 | setZMin(z1Min);
237 | setZMax(z1Max);
238 | }
239 | if (plotFunction2) {
240 | setZMin(z2Min);
241 | setZMax(z2Max);
242 | }
243 | }
244 | }
245 |
246 | public void exportCSV(File file) throws IOException {
247 | SurfaceVertex[][] surfaceVertex = getSurfaceVertex();
248 | if (file == null)
249 | return;
250 | java.io.FileWriter w = new java.io.FileWriter(file);
251 | float stepx, stepy, x, y;
252 | float xi, xx, yi, yx;
253 | int i, j, k;
254 |
255 |
256 | try {
257 | xi = getXMin();
258 | yi = getYMin();
259 | xx = getXMax();
260 | yx = getYMax();
261 | if ((xi >= xx) || (yi >= yx))
262 | throw new NumberFormatException();
263 | } catch (NumberFormatException e) {
264 | setMessage("Error in ranges");
265 | return;
266 | }
267 |
268 | calcDivisions = getCalcDivisions();
269 | // func1calc = f1; func2calc = f2;
270 |
271 | stepx = (xx - xi) / calcDivisions;
272 | stepy = (yx - yi) / calcDivisions;
273 |
274 | if (surfaceVertex == null)
275 | return;
276 | i = 0;
277 | j = 0;
278 | k = 0;
279 | x = xi;
280 | y = yi;
281 |
282 | w.write("X\\Y->Z;");
283 | while (j <= calcDivisions) {
284 |
285 | w.write(Float.toString(y));
286 | if (j != calcDivisions)
287 | w.write(';');
288 | j++;
289 | y += stepy;
290 | k++;
291 | }
292 | w.write("\n");
293 | // first line written
294 | i = 0;
295 | j = 0;
296 | k = 0;
297 | x = xi;
298 | y = yi;
299 |
300 | while (i <= calcDivisions) {
301 | w.write(Float.toString(x));
302 | w.write(';');
303 | while (j <= calcDivisions) {
304 | w.write(Float.toString(surfaceVertex[0][k].z));
305 | if (j != calcDivisions)
306 | w.write(';');
307 | j++;
308 | y += stepy;
309 | k++;
310 | // setMessage("Calculating : " + k*100/total + "% completed");
311 | }
312 | w.write('\n');
313 | // first line written
314 | j = 0;
315 | y = yi;
316 | i++;
317 | x += stepx;
318 | }
319 | w.flush();
320 | w.close();
321 |
322 | }
323 |
324 | private void fireAllFunction(boolean oldHas1, boolean oldHas2) {
325 | property.firePropertyChange("firstFunctionOnly", (!oldHas2) && oldHas1, (!plotFunction2) && plotFunction1);
326 | property.firePropertyChange("secondFunctionOnly", (!oldHas1) && oldHas2, (!plotFunction1) && plotFunction2);
327 | property.firePropertyChange("bothFunction", oldHas1 && oldHas2, plotFunction1 && plotFunction2);
328 | autoScale();
329 |
330 | }
331 |
332 | private void fireAllMode(PlotColor oldValue, PlotColor newValue) {
333 | for (PlotColor c : PlotColor.values())
334 | property.firePropertyChange(c.getPropertyName(), oldValue == c, newValue == c);
335 | }
336 |
337 | private void fireAllType(PlotType oldValue, PlotType newValue) {
338 | for (PlotType c : PlotType.values())
339 | property.firePropertyChange(c.getPropertyName(), oldValue == c, newValue == c);
340 | }
341 |
342 | protected void fireStateChanged() {
343 | // Guaranteed to return a non-null array
344 | Object[] listeners = listenerList.getListenerList();
345 | // Process the listeners last to first, notifying
346 | // those that are interested in this event
347 | ChangeEvent e = null;
348 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
349 | if (listeners[i] == ChangeListener.class) {
350 | // Lazily create the event:
351 | if (e == null)
352 | e = new ChangeEvent(this);
353 | ((ChangeListener) listeners[i + 1]).stateChanged(e);
354 | }
355 | }
356 | }
357 |
358 | public int getCalcDivisions() {
359 | return calcDivisions;
360 | }
361 |
362 | public SurfaceColor getColorModel() {
363 | return colorModel;
364 | }
365 |
366 | public int getContourLines() {
367 | return contourLines;
368 | }
369 |
370 | public int getDispDivisions() {
371 | if (dispDivisions > calcDivisions)
372 | dispDivisions = calcDivisions;
373 | while ((calcDivisions % dispDivisions) != 0)
374 | dispDivisions++;
375 | return dispDivisions;
376 | }
377 |
378 | public PlotColor getPlotColor() {
379 | return plotColor;
380 | }
381 |
382 | public PlotType getPlotType() {
383 | return plotType;
384 | }
385 |
386 | public Projector getProjector() {
387 | if (projector == null) {
388 | projector = new Projector();
389 | projector.setDistance(70);
390 | projector.set2DScaling(15);
391 | projector.setRotationAngle(125);
392 | projector.setElevationAngle(10);
393 | }
394 | return projector;
395 | }
396 |
397 | public PropertyChangeSupport getPropertyChangeSupport() {
398 | if (property == null)
399 | property = new SwingPropertyChangeSupport(this);
400 | return property;
401 | }
402 |
403 | public float getXMax() {
404 | return xMax;
405 | }
406 |
407 | public float getXMin() {
408 | return xMin;
409 | }
410 |
411 | public float getYMax() {
412 | return yMax;
413 | }
414 |
415 | public float getYMin() {
416 | return yMin;
417 | }
418 |
419 | public float getZMax() {
420 | return zMax;
421 | }
422 |
423 | public float getZMin() {
424 | return zMin;
425 | }
426 |
427 | public boolean isAutoScaleZ() {
428 | return autoScaleZ;
429 | }
430 |
431 | public boolean isBothFunction() {
432 | return plotFunction1 && plotFunction2;
433 | }
434 |
435 | public boolean isBoxed() {
436 | return boxed;
437 | }
438 |
439 | public boolean isContourType() {
440 | return plotType == PlotType.CONTOUR;
441 | }
442 |
443 | public boolean isDataAvailable() {
444 | return dataAvailable;
445 | }
446 |
447 | public boolean isDensityType() {
448 | return plotType == PlotType.DENSITY;
449 | }
450 |
451 | public boolean isDisplayGrids() {
452 | return displayGrids;
453 | }
454 |
455 | public boolean isDisplayXY() {
456 | return displayXY;
457 | }
458 |
459 | public boolean isDisplayZ() {
460 | return displayZ;
461 | }
462 |
463 | public boolean isDualShadeMode() {
464 | return plotColor == PlotColor.DUALSHADE;
465 | }
466 |
467 | public boolean isExpectDelay() {
468 | return expectDelay;
469 | }
470 |
471 | public boolean isFirstFunctionOnly() {
472 | return plotFunction1 && !plotFunction2;
473 | }
474 |
475 | public boolean isFogMode() {
476 | return plotColor == PlotColor.FOG;
477 | }
478 |
479 | public boolean isGrayScaleMode() {
480 | return plotColor == PlotColor.GRAYSCALE;
481 | }
482 |
483 | public boolean isHiddenMode() {
484 | return plotColor == PlotColor.OPAQUE;
485 | }
486 |
487 | public boolean isMesh() {
488 | return mesh;
489 | }
490 |
491 | public boolean isPlotFunction1() {
492 | return plotFunction1;
493 | }
494 |
495 | public boolean isPlotFunction2() {
496 | return plotFunction2;
497 | }
498 |
499 | public boolean isScaleBox() {
500 | return scaleBox;
501 | }
502 |
503 | public boolean isSecondFunctionOnly() {
504 | return (!plotFunction1) && plotFunction2;
505 | }
506 |
507 | public boolean isSpectrumMode() {
508 | return plotColor == PlotColor.SPECTRUM;
509 | }
510 |
511 | public boolean isSurfaceType() {
512 | return plotType == PlotType.SURFACE;
513 | }
514 |
515 | public boolean isWireframeType() {
516 | return plotType == PlotType.WIREFRAME;
517 | }
518 |
519 | public void removeChangeListener(ChangeListener ol) {
520 | listenerList.remove(ChangeListener.class, ol);
521 | }
522 |
523 | public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) {
524 | property.removePropertyChangeListener(listener);
525 | }
526 |
527 | public void removePropertyChangeListener(String propertyName, java.beans.PropertyChangeListener listener) {
528 | property.removePropertyChangeListener(propertyName, listener);
529 | }
530 |
531 | /**
532 | * Called when automatic rotation stops
533 | */
534 |
535 | public void rotationStops() {
536 |
537 | // setting_panel.rotationStops();
538 | }
539 |
540 | public void setAutoScaleZ(boolean autoScaleZ) {
541 | getPropertyChangeSupport().firePropertyChange("this.autoScaleZ", this.autoScaleZ, this.autoScaleZ = autoScaleZ);
542 | autoScale();
543 | }
544 |
545 | public void setBothFunction(boolean val) {
546 | setPlotFunction12(val, val);
547 | }
548 |
549 | public void setBoxed(boolean boxed) {
550 | getPropertyChangeSupport().firePropertyChange("boxed", this.boxed, this.boxed = boxed);
551 | }
552 |
553 | protected void setColorModel(ColorModelSet colorModel) {
554 | getPropertyChangeSupport().firePropertyChange("colorModel", this.colorModel, this.colorModel = colorModel);
555 | if (colorModel != null) {
556 | colorModel.setPlotColor(plotColor); // this shouls be handled by the model itself, without any
557 | colorModel.setPlotType(plotType);
558 | }
559 | }
560 |
561 | public void setContourLines(int contourLines) {
562 | getPropertyChangeSupport().firePropertyChange("contourLines", this.contourLines, this.contourLines = contourLines);
563 | }
564 |
565 | public void setContourType(boolean val) {
566 | setPlotType(val ? PlotType.CONTOUR : PlotType.SURFACE);
567 | }
568 |
569 | public void setDataAvailable(boolean dataAvailable) {
570 | getPropertyChangeSupport().firePropertyChange("dataAvailable", this.dataAvailable, this.dataAvailable = dataAvailable);
571 | }
572 |
573 | public void setDensityType(boolean val) {
574 | setPlotType(val ? PlotType.DENSITY : PlotType.SURFACE);
575 | }
576 |
577 | public void setDispDivisions(int dispDivisions) {
578 | getPropertyChangeSupport().firePropertyChange("dispDivisions", this.dispDivisions, this.dispDivisions = dispDivisions);
579 | }
580 |
581 | public void setDualShadeMode(boolean val) {
582 | setPlotColor(val ? PlotColor.DUALSHADE : PlotColor.SPECTRUM);
583 | }
584 |
585 | public void setFirstFunctionOnly(boolean val) {
586 | setPlotFunction12(val, !val);
587 | }
588 |
589 | public void setFogMode(boolean val) {
590 | setPlotColor(val ? PlotColor.FOG : PlotColor.SPECTRUM);
591 | }
592 |
593 | public void setGrayScaleMode(boolean val) {
594 | setPlotColor(val ? PlotColor.GRAYSCALE : PlotColor.SPECTRUM);
595 | }
596 |
597 | public void setHiddenMode(boolean val) {
598 | setPlotColor(val ? PlotColor.OPAQUE : PlotColor.SPECTRUM);
599 | }
600 |
601 |
602 | /**
603 | * Sets the text of status line
604 | *
605 | * @param text
606 | * new text to be displayed
607 | */
608 |
609 | public void setMessage(String text) {
610 | // @todo
611 | // System.out.println("Message"+text);
612 | }
613 |
614 | public void setPlotFunction1(boolean plotFunction1) {
615 | setPlotFunction12(plotFunction1, plotFunction2);
616 | }
617 |
618 | public void setPlotColor(PlotColor plotColor) {
619 | PlotColor old = this.plotColor;
620 | getPropertyChangeSupport().firePropertyChange("plotColor", this.plotColor, this.plotColor = plotColor);
621 | fireAllMode(old, this.plotColor);
622 | if (colorModel != null)
623 | colorModel.setPlotColor(plotColor); // this should be handled by the model itself, without any
624 | }
625 |
626 | public void setPlotFunction12(boolean p1, boolean p2) {
627 | boolean o1 = this.plotFunction1;
628 | boolean o2 = this.plotFunction2;
629 |
630 | this.plotFunction1 = hasFunction1 && p1;
631 | property.firePropertyChange("plotFunction1", o1, p1);
632 |
633 | this.plotFunction2 = hasFunction2 && p2;
634 | property.firePropertyChange("plotFunction1", o2, p2);
635 | fireAllFunction(o1, o2);
636 | }
637 |
638 | public void setPlotFunction2(boolean v) {
639 | setPlotFunction12(plotFunction1, plotFunction2);
640 | }
641 |
642 | public void setPlotType(PlotType plotType) {
643 | PlotType o = this.plotType;
644 | this.plotType = plotType;
645 | if (colorModel != null)
646 | colorModel.setPlotType(plotType); // this should be handled by the model itself, without any
647 | property.firePropertyChange("plotType", o, this.plotType);
648 | fireAllType(o, this.plotType);
649 | }
650 |
651 | public void setSecondFunctionOnly(boolean val) {
652 | setPlotFunction12(!val, val);
653 | }
654 |
655 | public void setSpectrumMode(boolean val) {
656 | setPlotColor(val ? PlotColor.SPECTRUM : PlotColor.GRAYSCALE);
657 | }
658 |
659 | public void setSurfaceType(boolean val) {
660 | setPlotType(val ? PlotType.SURFACE : PlotType.WIREFRAME);
661 | }
662 |
663 | public void setWireframeType(boolean val) {
664 | if (val)
665 | setPlotType(PlotType.WIREFRAME);
666 | else
667 | setPlotType(PlotType.SURFACE);
668 | }
669 |
670 | public void setXMax(float xMax) {
671 | getPropertyChangeSupport().firePropertyChange("xMax", this.xMax, this.xMax = xMax);
672 | }
673 |
674 | public void setXMin(float xMin) {
675 | getPropertyChangeSupport().firePropertyChange("xMin", this.xMin, this.xMin = xMin);
676 | }
677 |
678 | public void setYMax(float yMax) {
679 | getPropertyChangeSupport().firePropertyChange("yMax", this.yMax, this.yMax = yMax);
680 | }
681 |
682 | public void setYMin(float yMin) {
683 | getPropertyChangeSupport().firePropertyChange("yMin", this.yMin, this.yMin = yMin);
684 | }
685 |
686 | public void setZMax(float zMax) {
687 | if (zMax <= zMin)
688 | return;
689 | getPropertyChangeSupport().firePropertyChange("zMax", this.zMax, this.zMax = zMax);
690 | }
691 |
692 | public void setZMin(float zMin) {
693 | if (zMin >= zMax)
694 | return;
695 | getPropertyChangeSupport().firePropertyChange("zMin", this.zMin, this.zMin = zMin);
696 | }
697 |
698 | public void setDisplayGrids(boolean displayGrids) {
699 | getPropertyChangeSupport().firePropertyChange("displayGrids", this.displayGrids, this.displayGrids = displayGrids);
700 | }
701 |
702 | public void setDisplayXY(boolean displayXY) {
703 | getPropertyChangeSupport().firePropertyChange("displayXY", this.displayXY, this.displayXY = displayXY);
704 | }
705 |
706 | public void setDisplayZ(boolean displayZ) {
707 | getPropertyChangeSupport().firePropertyChange("displayZ", this.displayZ, this.displayZ = displayZ);
708 | }
709 |
710 | public void setExpectDelay(boolean expectDelay) {
711 | getPropertyChangeSupport().firePropertyChange("expectDelay", this.expectDelay, this.expectDelay = expectDelay);
712 | }
713 |
714 | public void setMesh(boolean mesh) {
715 | getPropertyChangeSupport().firePropertyChange("mesh", this.mesh, this.mesh = mesh);
716 | }
717 |
718 | public void setScaleBox(boolean scaleBox) {
719 | getPropertyChangeSupport().firePropertyChange("scaleBox", this.scaleBox, this.scaleBox = scaleBox);
720 | }
721 |
722 | public void toggleAutoScaleZ() {
723 | setAutoScaleZ(!isAutoScaleZ());
724 | }
725 |
726 | public void toggleBoxed() {
727 | setBoxed(!isBoxed());
728 | }
729 |
730 |
731 |
732 | public void setCalcDivisions(int calcDivisions) {
733 | getPropertyChangeSupport().firePropertyChange("calcDivisions", this.calcDivisions, this.calcDivisions = calcDivisions);
734 | }
735 |
736 | /**
737 | * Processes menu events
738 | *
739 | * @param item
740 | * the selected menu item
741 | */
742 |
743 | public void toggleDisplayGrids() {
744 | setDisplayGrids(!isDisplayGrids());
745 | }
746 |
747 | /**
748 | * Sets file name
749 | */
750 |
751 | public void toggleDisplayXY() {
752 | setDisplayXY(!isDisplayXY());
753 | }
754 |
755 | public void toggleDisplayZ() {
756 | setDisplayZ(!isDisplayZ());
757 | }
758 |
759 | public void toggleExpectDelay() {
760 | setExpectDelay(!isExpectDelay());
761 | }
762 |
763 | public void toggleMesh() {
764 | setMesh(!isMesh());
765 | }
766 |
767 | public void togglePlotFunction1() {
768 | setPlotFunction1(!isPlotFunction1());
769 |
770 | }
771 |
772 | public void togglePlotFunction2() {
773 | setPlotFunction2(!isPlotFunction2());
774 |
775 | }
776 |
777 | public void toggleScaleBox() {
778 | setScaleBox(!isScaleBox());
779 | }
780 |
781 | }
782 |
--------------------------------------------------------------------------------
/src/main/java/net/ericaro/surfaceplotter/AbstractSurfaceModel.java:
--------------------------------------------------------------------------------
1 | package net.ericaro.surfaceplotter;
2 |
3 | import java.beans.PropertyChangeSupport;
4 | import java.io.File;
5 | import java.io.IOException;
6 |
7 | import javax.swing.event.ChangeEvent;
8 | import javax.swing.event.ChangeListener;
9 | import javax.swing.event.SwingPropertyChangeSupport;
10 |
11 | import net.ericaro.surfaceplotter.surface.ColorModelSet;
12 | import net.ericaro.surfaceplotter.surface.Projector;
13 | import net.ericaro.surfaceplotter.surface.SurfaceColor;
14 | import net.ericaro.surfaceplotter.surface.SurfaceModel;
15 | import net.ericaro.surfaceplotter.surface.SurfaceVertex;
16 | import net.ericaro.surfaceplotter.surface.SurfaceModel.PlotColor;
17 | import net.ericaro.surfaceplotter.surface.SurfaceModel.PlotType;
18 |
19 |
20 | /**
21 | * {@link AbstractSurfaceModel} provides a writable implementation of the {@link SurfaceModel} interface.
22 | * Writting is available throught setters for any properties, and through a simple "Plotter" interface, to fill the curves.
23 | */
24 | public class AbstractSurfaceModel implements SurfaceModel {
25 |
26 | /**
27 | * Interface returned by this object to write values in this model
28 | *
29 | * @author eric
30 | */
31 | public interface Plotter {
32 | public int getHeight();
33 |
34 | public int getWidth();
35 |
36 | public float getX(int i);
37 |
38 | public float getY(int j);
39 |
40 | public void setValue(int i, int j, float v1, float v2);
41 |
42 | }
43 |
44 | /**
45 | * Parses defined functions and calculates surface vertices
46 | */
47 | class PlotterImpl implements Plotter {
48 | int calcDivisions;
49 | boolean f1, f2;
50 | int i, j, total;
51 | int imgheight = 0;
52 | int imgwidth = 0;
53 |
54 | float min1, max1, min2, max2;
55 | int[] pixels = null;
56 | float stepx, stepy;
57 | float xfactor;
58 | float xi, xx, yi, yx;
59 |
60 | float yfactor;
61 |
62 | public PlotterImpl() {
63 | // reads the calcDivision that will be used
64 | calcDivisions = getCalcDivisions();
65 | setDataAvailable(false); // clean space
66 | total = (calcDivisions + 1) * (calcDivisions + 1); // compute total size
67 | f1 = hasFunction1;
68 | f2 = hasFunction2; // define the size of the plot
69 | surfaceVertex = allocateMemory(f1, f2, total); // allocate surfaceVertex
70 | setSurfaceVertex(surfaceVertex); // define as the current surfaceVertex
71 | setDataAvailable(true);
72 | min1 = max1 = min2 = max2 = Float.NaN;
73 | getProjector();
74 | try {
75 | xi = getXMin();
76 | yi = getYMin();
77 | xx = getXMax();
78 | yx = getYMax();
79 | if ((xi >= xx) || (yi >= yx))
80 | throw new NumberFormatException();
81 | } catch (NumberFormatException e) {
82 | setMessage("Error in ranges");
83 | return;
84 | }
85 | stepx = (xx - xi) / calcDivisions;
86 | stepy = (yx - yi) / calcDivisions;
87 | xfactor = 20 / (xx - xi);
88 | yfactor = 20 / (yx - yi);
89 |
90 | // fill the surface surfaceVertex with NaN
91 | for (int i = 0; i <= calcDivisions; i++)
92 | for (int j = 0; j <= calcDivisions; j++) {
93 | int k = i * (calcDivisions + 1) + j;
94 |
95 | float x = getX(i);
96 | float y = getY(j);
97 | if (f1) {
98 | surfaceVertex[0][k] = new SurfaceVertex((x - xi) * xfactor - 10, (y - yi) * yfactor - 10, Float.NaN);
99 | }
100 | if (f2) {
101 | surfaceVertex[1][k] = new SurfaceVertex((x - xi) * xfactor - 10, (y - yi) * yfactor - 10, Float.NaN);
102 | }
103 | }
104 |
105 | }
106 |
107 | public int getHeight() {
108 | return calcDivisions + 1;
109 | }
110 |
111 | public int getWidth() {
112 | return calcDivisions + 1;
113 | }
114 |
115 | /**
116 | * Get the x float value that can be used to compute the fonction at
117 | * position i.
118 | *
119 | * @param i
120 | * index 0<=i<=calcDivisions.
121 | * @author eric
122 | */
123 | public float getX(int i) {
124 | return xi + i * stepx;
125 | }
126 |
127 | /**
128 | * Get the x float value that can be used to compute the fonction at
129 | * position i.
130 | *
131 | * @param j
132 | * index 0<=j<=calcDivisions.
133 | * @author eric
134 | */
135 | public float getY(int j) {
136 | return yi + j * stepy;
137 | }
138 |
139 | /**
140 | * Put an actual value at the (i,j) position for both first and second curve
141 | *
142 | * @param i
143 | * index 0<=i<=calcDivisions.
144 | * @param j
145 | * index 0<=j<=calcDivisions.
146 | * @param v
147 | * value at that point.
148 | * @see package.class
149 | * @author eric
150 | */
151 | public void setValue(int i, int j, float v1, float v2) {
152 | // v contains the value, and i, j the coordinate in the array
153 | float x = getX(i);
154 | float y = getY(j);
155 | int k = i * (calcDivisions + 1) + j;
156 | if (f1) {
157 |
158 | // v = compute(x,y);
159 | if (Float.isInfinite(v1))
160 | v1 = Float.NaN;
161 | if (!Float.isNaN(v1)) {
162 | if (Float.isNaN(max1) || (v1 > max1))
163 | max1 = v1;
164 | else if (Float.isNaN(min1) || (v1 < min1))
165 | min1 = v1;
166 | }
167 | surfaceVertex[0][k] = new SurfaceVertex((x - xi) * xfactor - 10, (y - yi) * yfactor - 10, v1);
168 | }
169 | if (f2) {
170 | // v = (float)parser2.evaluate();
171 | if (Float.isInfinite(v2))
172 | v2 = Float.NaN;
173 | if (!Float.isNaN(v2)) {
174 | if (Float.isNaN(max2) || (v2 > max2))
175 | max2 = v2;
176 | else if (Float.isNaN(min2) || (v2 < min2))
177 | min2 = v2;
178 | }
179 | surfaceVertex[1][k] = new SurfaceVertex((x - xi) * xfactor - 10, (y - yi) * yfactor - 10, v2);
180 | }
181 | z1Min = (float) floor(min1, 2);
182 | z1Max = (float) ceil(max1, 2);
183 | z2Min = (float) floor(min2, 2);
184 | z2Max = (float) ceil(max2, 2);
185 |
186 | autoScale();
187 | fireStateChanged();
188 | }
189 | }
190 |
191 | private static final int INIT_CALC_DIV = 20;
192 | private static final int INIT_DISP_DIV = 20;
193 |
194 | /**
195 | * internally used to ceil values
196 | *
197 | * @param d
198 | * @param digits
199 | * @return
200 | */
201 | public static synchronized double ceil(double d, int digits) {
202 | if (d == 0)
203 | return d;
204 | long og = (long) Math.ceil((Math.log(Math.abs(d)) / Math.log(10)));
205 | double factor = Math.pow(10, digits - og);
206 | double res = Math.ceil((d * factor)) / factor;
207 | return res;
208 | }
209 |
210 | /**
211 | * internally used to floor values
212 | *
213 | * @param d
214 | * @param digits
215 | * @return
216 | */
217 | public static synchronized double floor(double d, int digits) {
218 | if (d == 0)
219 | return d;
220 | // computes order of magnitude
221 | long og = (long) Math.ceil((Math.log(Math.abs(d)) / Math.log(10)));
222 |
223 | double factor = Math.pow(10, digits - og);
224 | // the matissa
225 | double res = Math.floor((d * factor)) / factor;
226 | // res contains the closed power of ten
227 | return res;
228 | }
229 |
230 | protected boolean autoScaleZ = true;
231 |
232 | /**
233 | * Determines whether to show bounding box.
234 | *
235 | * @return true if to show bounding box
236 | */
237 | protected boolean boxed;
238 | protected int calcDivisions = INIT_CALC_DIV;
239 | protected ColorModelSet colorModel;
240 | protected int contourLines;
241 | /**
242 | * Sets data availability flag
243 | */
244 | protected boolean dataAvailable;
245 | protected int dispDivisions = INIT_DISP_DIV;
246 | /**
247 | * Determines whether to show face grids.
248 | *
249 | * @return true if to show face grids
250 | */
251 | protected boolean displayGrids;
252 | /**
253 | * Determines whether to show x-y ticks.
254 | *
255 | * @return true if to show x-y ticks
256 | */
257 | protected boolean displayXY;
258 |
259 | /**
260 | * Determines whether to show z ticks.
261 | *
262 | * @return true if to show z ticks
263 | */
264 | protected boolean displayZ;
265 |
266 | /**
267 | * Determines whether the delay regeneration checkbox is checked.
268 | *
269 | * @return true if the checkbox is checked, false otherwise
270 | */
271 | protected boolean expectDelay = false;
272 |
273 | /**
274 | * Determines whether the first function is selected.
275 | *
276 | * @return true if the first function is checked, false otherwise
277 | */
278 |
279 | protected boolean hasFunction1 = true;
280 |
281 | /**
282 | * Determines whether the first function is selected.
283 | *
284 | * @return true if the first function is checked, false otherwise
285 | */
286 | protected boolean hasFunction2 = true;
287 |
288 | javax.swing.event.EventListenerList listenerList = new javax.swing.event.EventListenerList();
289 |
290 | /**
291 | * Determines whether to show x-y mesh.
292 | *
293 | * @return true if to show x-y mesh
294 | */
295 | protected boolean mesh;
296 |
297 | protected PlotColor plotColor;
298 |
299 | protected boolean plotFunction1 = hasFunction1;
300 |
301 | protected boolean plotFunction2 = hasFunction2;
302 |
303 | protected PlotType plotType = PlotType.SURFACE;
304 |
305 | private Projector projector;
306 |
307 | protected PropertyChangeSupport property;
308 |
309 | /**
310 | * Determines whether to scale axes and bounding box.
311 | *
312 | * @return true if to scale bounding box
313 | */
314 |
315 | protected boolean scaleBox;
316 |
317 | protected SurfaceVertex[][] surfaceVertex;
318 | protected float xMax;
319 |
320 | protected float xMin;
321 | protected float yMax;
322 |
323 | protected float yMin;
324 | protected float z1Max;// the max computed
325 |
326 | protected float z1Min;// the min computed
327 | protected float z2Max;// the max computed
328 |
329 | protected float z2Min;// the min computed
330 | protected float zMax;
331 |
332 | protected float zMin;
333 |
334 | /**
335 | * Empty Surface Model
336 | */
337 | public AbstractSurfaceModel() {
338 | super();
339 | property = new SwingPropertyChangeSupport(this);
340 | setColorModel(new ColorModelSet());
341 | }
342 |
343 | public void addChangeListener(ChangeListener ol) {
344 | listenerList.add(ChangeListener.class, ol);
345 | }
346 |
347 | public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) {
348 | property.addPropertyChangeListener(listener);
349 | }
350 |
351 | public void addPropertyChangeListener(String propertyName, java.beans.PropertyChangeListener listener) {
352 | property.addPropertyChangeListener(propertyName, listener);
353 | }
354 |
355 | /**
356 | * Allocates Memory
357 | */
358 |
359 | private SurfaceVertex[][] allocateMemory(boolean f1, boolean f2, int total) {
360 | SurfaceVertex[][] vertex = null;
361 | try {
362 | vertex = new SurfaceVertex[2][total];
363 | if (!f1)
364 | vertex[0] = null;
365 | if (!f2)
366 | vertex[1] = null;
367 | } catch (OutOfMemoryError e) {
368 | setMessage("Not enough memory");
369 | } catch (Exception e) {
370 | setMessage("Error: " + e.toString());
371 | }
372 | return vertex;
373 | }
374 |
375 | /**
376 | * Autoscale based on actual values
377 | */
378 | public void autoScale() {
379 | // compute auto scale and repaint
380 | if (!autoScaleZ)
381 | return;
382 | if (plotFunction1 && plotFunction2) {
383 | setZMin(Math.min(z1Min, z2Min));
384 | setZMax(Math.max(z1Max, z2Max));
385 | } else {
386 | if (plotFunction1) {
387 | setZMin(z1Min);
388 | setZMax(z1Max);
389 | }
390 | if (plotFunction2) {
391 | setZMin(z2Min);
392 | setZMax(z2Max);
393 | }
394 | }
395 | }
396 |
397 | public void exportCSV(File file) throws IOException {
398 |
399 | if (file == null)
400 | return;
401 | java.io.FileWriter w = new java.io.FileWriter(file);
402 | float stepx, stepy, x, y, v;
403 | float xi, xx, yi, yx;
404 | float min, max;
405 | boolean f1, f2;
406 | int i, j, k, total;
407 |
408 | f1 = true;
409 | f2 = true; // until no method is defined to set functions ...
410 | // image conversion
411 |
412 | int[] pixels = null;
413 | int imgwidth = 0;
414 | int imgheight = 0;
415 |
416 | try {
417 | xi = getXMin();
418 | yi = getYMin();
419 | xx = getXMax();
420 | yx = getYMax();
421 | if ((xi >= xx) || (yi >= yx))
422 | throw new NumberFormatException();
423 | } catch (NumberFormatException e) {
424 | setMessage("Error in ranges");
425 | return;
426 | }
427 |
428 | calcDivisions = getCalcDivisions();
429 | // func1calc = f1; func2calc = f2;
430 |
431 | stepx = (xx - xi) / calcDivisions;
432 | stepy = (yx - yi) / calcDivisions;
433 |
434 | total = (calcDivisions + 1) * (calcDivisions + 1);
435 | if (surfaceVertex == null)
436 | return;
437 |
438 | max = Float.NaN;
439 | min = Float.NaN;
440 |
441 | // canvas.destroyImage();
442 | i = 0;
443 | j = 0;
444 | k = 0;
445 | x = xi;
446 | y = yi;
447 |
448 | float xfactor = 20 / (xx - xi);
449 | float yfactor = 20 / (yx - yi);
450 |
451 | w.write("X\\Y->Z;");
452 | while (j <= calcDivisions) {
453 |
454 | w.write(Float.toString(y));
455 | if (j != calcDivisions)
456 | w.write(';');
457 | j++;
458 | y += stepy;
459 | k++;
460 | }
461 | w.write("\n");
462 | // first line written
463 | i = 0;
464 | j = 0;
465 | k = 0;
466 | x = xi;
467 | y = yi;
468 |
469 | while (i <= calcDivisions) {
470 | w.write(Float.toString(x));
471 | w.write(';');
472 | while (j <= calcDivisions) {
473 | w.write(Float.toString(surfaceVertex[0][k].z));
474 | if (j != calcDivisions)
475 | w.write(';');
476 | j++;
477 | y += stepy;
478 | k++;
479 | // setMessage("Calculating : " + k*100/total + "% completed");
480 | }
481 | w.write('\n');
482 | // first line written
483 | j = 0;
484 | y = yi;
485 | i++;
486 | x += stepx;
487 | }
488 | w.flush();
489 | w.close();
490 |
491 | }
492 |
493 | private void fireAllFunction(boolean oldHas1, boolean oldHas2) {
494 | property.firePropertyChange("firstFunctionOnly", (!oldHas2) && oldHas1, (!plotFunction2) && plotFunction1);
495 | property.firePropertyChange("secondFunctionOnly", (!oldHas1) && oldHas2, (!plotFunction1) && plotFunction2);
496 | property.firePropertyChange("bothFunction", oldHas1 && oldHas2, plotFunction1 && plotFunction2);
497 | autoScale();
498 |
499 | }
500 |
501 | private void fireAllMode(PlotColor oldValue, PlotColor newValue) {
502 | for (PlotColor c : PlotColor.values())
503 | property.firePropertyChange(c.getPropertyName(), oldValue == c, newValue == c);
504 | }
505 |
506 | private void fireAllType(PlotType oldValue, PlotType newValue) {
507 | for (PlotType c : PlotType.values())
508 | property.firePropertyChange(c.getPropertyName(), oldValue == c, newValue == c);
509 | }
510 |
511 | protected void fireStateChanged() {
512 | // Guaranteed to return a non-null array
513 | Object[] listeners = listenerList.getListenerList();
514 | // Process the listeners last to first, notifying
515 | // those that are interested in this event
516 | ChangeEvent e = null;
517 | for (int i = listeners.length - 2; i >= 0; i -= 2) {
518 | if (listeners[i] == ChangeListener.class) {
519 | // Lazily create the event:
520 | if (e == null)
521 | e = new ChangeEvent(this);
522 | ((ChangeListener) listeners[i + 1]).stateChanged(e);
523 | }
524 | }
525 | }
526 |
527 | public int getCalcDivisions() {
528 | return calcDivisions;
529 | }
530 |
531 | public SurfaceColor getColorModel() {
532 | return colorModel;
533 | }
534 |
535 | public int getContourLines() {
536 | return contourLines;
537 | }
538 |
539 | public int getDispDivisions() {
540 | if (dispDivisions > calcDivisions)
541 | dispDivisions = calcDivisions;
542 | while ((calcDivisions % dispDivisions) != 0)
543 | dispDivisions++;
544 | return dispDivisions;
545 | }
546 |
547 | public PlotColor getPlotColor() {
548 | return plotColor;
549 | }
550 |
551 | public PlotType getPlotType() {
552 | return plotType;
553 | }
554 |
555 | public Projector getProjector() {
556 | if (projector == null) {
557 | projector = new Projector();
558 | projector.setDistance(70);
559 | projector.set2DScaling(15);
560 | projector.setRotationAngle(125);
561 | projector.setElevationAngle(10);
562 | }
563 | return projector;
564 | }
565 |
566 | public PropertyChangeSupport getPropertyChangeSupport() {
567 | if (property == null)
568 | property = new SwingPropertyChangeSupport(this);
569 | return property;
570 | }
571 |
572 | public SurfaceVertex[][] getSurfaceVertex() {
573 | return surfaceVertex;
574 | }
575 |
576 | public float getXMax() {
577 | return xMax;
578 | }
579 |
580 | public float getXMin() {
581 | return xMin;
582 | }
583 |
584 | public float getYMax() {
585 | return yMax;
586 | }
587 |
588 | public float getYMin() {
589 | return yMin;
590 | }
591 |
592 | public float getZMax() {
593 | return zMax;
594 | }
595 |
596 | public float getZMin() {
597 | return zMin;
598 | }
599 |
600 | public boolean isAutoScaleZ() {
601 | return autoScaleZ;
602 | }
603 |
604 | public boolean isBothFunction() {
605 | return plotFunction1 && plotFunction2;
606 | }
607 |
608 | public boolean isBoxed() {
609 | return boxed;
610 | }
611 |
612 | public boolean isContourType() {
613 | return plotType == PlotType.CONTOUR;
614 | }
615 |
616 | public boolean isDataAvailable() {
617 | return dataAvailable;
618 | }
619 |
620 | public boolean isDensityType() {
621 | return plotType == PlotType.DENSITY;
622 | }
623 |
624 | public boolean isDisplayGrids() {
625 | return displayGrids;
626 | }
627 |
628 | public boolean isDisplayXY() {
629 | return displayXY;
630 | }
631 |
632 | public boolean isDisplayZ() {
633 | return displayZ;
634 | }
635 |
636 | public boolean isDualShadeMode() {
637 | return plotColor == PlotColor.DUALSHADE;
638 | }
639 |
640 | public boolean isExpectDelay() {
641 | return expectDelay;
642 | }
643 |
644 | public boolean isFirstFunctionOnly() {
645 | return plotFunction1 && !plotFunction2;
646 | }
647 |
648 | public boolean isFogMode() {
649 | return plotColor == PlotColor.FOG;
650 | }
651 |
652 | public boolean isGrayScaleMode() {
653 | return plotColor == PlotColor.GRAYSCALE;
654 | }
655 |
656 | public boolean isHiddenMode() {
657 | return plotColor == PlotColor.OPAQUE;
658 | }
659 |
660 | public boolean isMesh() {
661 | return mesh;
662 | }
663 |
664 | public boolean isPlotFunction1() {
665 | return plotFunction1;
666 | }
667 |
668 | public boolean isPlotFunction2() {
669 | return plotFunction2;
670 | }
671 |
672 | public boolean isScaleBox() {
673 | return scaleBox;
674 | }
675 |
676 | public boolean isSecondFunctionOnly() {
677 | return (!plotFunction1) && plotFunction2;
678 | }
679 |
680 | public boolean isSpectrumMode() {
681 | return plotColor == PlotColor.SPECTRUM;
682 | }
683 |
684 | public boolean isSurfaceType() {
685 | return plotType == PlotType.SURFACE;
686 | }
687 |
688 | public boolean isWireframeType() {
689 | return plotType == PlotType.WIREFRAME;
690 | }
691 |
692 | /**
693 | * factory to get a plotter, i.e. the best way to append data to this surface model
694 | *
695 | * @param calcDivisions
696 | * @return
697 | */
698 | public Plotter newPlotter(int calcDivisions) {
699 | setCalcDivisions(calcDivisions);
700 | return new PlotterImpl();
701 | }
702 |
703 | public void removeChangeListener(ChangeListener ol) {
704 | listenerList.remove(ChangeListener.class, ol);
705 | }
706 |
707 | public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) {
708 | property.removePropertyChangeListener(listener);
709 | }
710 |
711 | public void removePropertyChangeListener(String propertyName, java.beans.PropertyChangeListener listener) {
712 | property.removePropertyChangeListener(propertyName, listener);
713 | }
714 |
715 | /**
716 | * Called when automatic rotation stops
717 | */
718 |
719 | public void rotationStops() {
720 |
721 | // setting_panel.rotationStops();
722 | }
723 |
724 | public void setAutoScaleZ(boolean autoScaleZ) {
725 | getPropertyChangeSupport().firePropertyChange("this.autoScaleZ", this.autoScaleZ, this.autoScaleZ = autoScaleZ);
726 | autoScale();
727 | }
728 |
729 | public void setBothFunction(boolean val) {
730 | setPlotFunction12(val, val);
731 | }
732 |
733 | public void setBoxed(boolean boxed) {
734 | getPropertyChangeSupport().firePropertyChange("boxed", this.boxed, this.boxed = boxed);
735 | }
736 |
737 | protected void setColorModel(ColorModelSet colorModel) {
738 | getPropertyChangeSupport().firePropertyChange("colorModel", this.colorModel, this.colorModel = colorModel);
739 | if (colorModel != null) {
740 | colorModel.setPlotColor(plotColor); // this shouls be handled by the model itself, without any
741 | colorModel.setPlotType(plotType);
742 | }
743 | }
744 |
745 | public void setContourLines(int contourLines) {
746 | getPropertyChangeSupport().firePropertyChange("contourLines", this.contourLines, this.contourLines = contourLines);
747 | }
748 |
749 | public void setContourType(boolean val) {
750 | setPlotType(val ? PlotType.CONTOUR : PlotType.SURFACE);
751 | }
752 |
753 | public void setDataAvailable(boolean dataAvailable) {
754 | getPropertyChangeSupport().firePropertyChange("dataAvailable", this.dataAvailable, this.dataAvailable = dataAvailable);
755 | }
756 |
757 | public void setDensityType(boolean val) {
758 | setPlotType(val ? PlotType.DENSITY : PlotType.SURFACE);
759 | }
760 |
761 | public void setDispDivisions(int dispDivisions) {
762 | getPropertyChangeSupport().firePropertyChange("dispDivisions", this.dispDivisions, this.dispDivisions = dispDivisions);
763 | }
764 |
765 | public void setDualShadeMode(boolean val) {
766 | setPlotColor(val ? PlotColor.DUALSHADE : PlotColor.SPECTRUM);
767 | }
768 |
769 | public void setFirstFunctionOnly(boolean val) {
770 | setPlotFunction12(val, !val);
771 | }
772 |
773 | public void setFogMode(boolean val) {
774 | setPlotColor(val ? PlotColor.FOG : PlotColor.SPECTRUM);
775 | }
776 |
777 | public void setGrayScaleMode(boolean val) {
778 | setPlotColor(val ? PlotColor.GRAYSCALE : PlotColor.SPECTRUM);
779 | }
780 |
781 | public void setHiddenMode(boolean val) {
782 | setPlotColor(val ? PlotColor.OPAQUE : PlotColor.SPECTRUM);
783 | }
784 |
785 | /**
786 | * Sets the text of status line
787 | *
788 | * @param text
789 | * new text to be displayed
790 | */
791 |
792 | public void setMessage(String text) {
793 | // @todo
794 | // System.out.println("Message"+text);
795 | }
796 |
797 | public void setPlotFunction1(boolean plotFunction1) {
798 | setPlotFunction12(plotFunction1, plotFunction2);
799 | }
800 |
801 | public void setPlotColor(PlotColor plotColor) {
802 | PlotColor old = this.plotColor;
803 | getPropertyChangeSupport().firePropertyChange("plotColor", this.plotColor, this.plotColor = plotColor);
804 | fireAllMode(old, this.plotColor);
805 | if (colorModel != null)
806 | colorModel.setPlotColor(plotColor); // this should be handled by the model itself, without any
807 | }
808 |
809 | public void setPlotFunction12(boolean p1, boolean p2) {
810 | boolean o1 = this.plotFunction1;
811 | boolean o2 = this.plotFunction2;
812 |
813 | this.plotFunction1 = hasFunction1 && p1;
814 | property.firePropertyChange("plotFunction1", o1, p1);
815 |
816 | this.plotFunction2 = hasFunction2 && p2;
817 | property.firePropertyChange("plotFunction1", o2, p2);
818 | fireAllFunction(o1, o2);
819 | }
820 |
821 | public void setPlotFunction2(boolean v) {
822 | setPlotFunction12(plotFunction1, plotFunction2);
823 | }
824 |
825 | public void setPlotType(PlotType plotType) {
826 | PlotType o = this.plotType;
827 | this.plotType = plotType;
828 | if (colorModel != null)
829 | colorModel.setPlotType(plotType); // this should be handled by the model itself, without any
830 | property.firePropertyChange("plotType", o, this.plotType);
831 | fireAllType(o, this.plotType);
832 | }
833 |
834 | public void setSecondFunctionOnly(boolean val) {
835 | setPlotFunction12(!val, val);
836 | }
837 |
838 | public void setSpectrumMode(boolean val) {
839 | setPlotColor(val ? PlotColor.SPECTRUM : PlotColor.GRAYSCALE);
840 | }
841 |
842 | public void setSurfaceType(boolean val) {
843 | setPlotType(val ? PlotType.SURFACE : PlotType.WIREFRAME);
844 | }
845 |
846 | public void setSurfaceVertex(SurfaceVertex[][] surfaceVertex) {
847 | getPropertyChangeSupport().firePropertyChange("surfaceVertex", this.surfaceVertex, this.surfaceVertex = surfaceVertex);
848 | }
849 |
850 | public void setWireframeType(boolean val) {
851 | if (val)
852 | setPlotType(PlotType.WIREFRAME);
853 | else
854 | setPlotType(PlotType.SURFACE);
855 | }
856 |
857 | public void setXMax(float xMax) {
858 | getPropertyChangeSupport().firePropertyChange("xMax", this.xMax, this.xMax = xMax);
859 | }
860 |
861 | public void setXMin(float xMin) {
862 | getPropertyChangeSupport().firePropertyChange("xMin", this.xMin, this.xMin = xMin);
863 | }
864 |
865 | public void setYMax(float yMax) {
866 | getPropertyChangeSupport().firePropertyChange("yMax", this.yMax, this.yMax = yMax);
867 | }
868 |
869 | public void setYMin(float yMin) {
870 | getPropertyChangeSupport().firePropertyChange("yMin", this.yMin, this.yMin = yMin);
871 | }
872 |
873 | public void setZMax(float zMax) {
874 | if (zMax <= zMin)
875 | return;
876 | getPropertyChangeSupport().firePropertyChange("zMax", this.zMax, this.zMax = zMax);
877 | }
878 |
879 | public void setZMin(float zMin) {
880 | if (zMin >= zMax)
881 | return;
882 | getPropertyChangeSupport().firePropertyChange("zMin", this.zMin, this.zMin = zMin);
883 | }
884 |
885 | public void setDisplayGrids(boolean displayGrids) {
886 | getPropertyChangeSupport().firePropertyChange("displayGrids", this.displayGrids, this.displayGrids = displayGrids);
887 | }
888 |
889 | public void setDisplayXY(boolean displayXY) {
890 | getPropertyChangeSupport().firePropertyChange("displayXY", this.displayXY, this.displayXY = displayXY);
891 | }
892 |
893 | public void setDisplayZ(boolean displayZ) {
894 | getPropertyChangeSupport().firePropertyChange("displayZ", this.displayZ, this.displayZ = displayZ);
895 | }
896 |
897 | public void setExpectDelay(boolean expectDelay) {
898 | getPropertyChangeSupport().firePropertyChange("expectDelay", this.expectDelay, this.expectDelay = expectDelay);
899 | }
900 |
901 | public void setMesh(boolean mesh) {
902 | getPropertyChangeSupport().firePropertyChange("mesh", this.mesh, this.mesh = mesh);
903 | }
904 |
905 | public void setScaleBox(boolean scaleBox) {
906 | getPropertyChangeSupport().firePropertyChange("scaleBox", this.scaleBox, this.scaleBox = scaleBox);
907 | }
908 |
909 | public void toggleAutoScaleZ() {
910 | setAutoScaleZ(!isAutoScaleZ());
911 | }
912 |
913 | public void toggleBoxed() {
914 | setBoxed(!isBoxed());
915 | }
916 |
917 |
918 |
919 | public void setCalcDivisions(int calcDivisions) {
920 | getPropertyChangeSupport().firePropertyChange("calcDivisions", this.calcDivisions, this.calcDivisions = calcDivisions);
921 | }
922 |
923 | /**
924 | * Processes menu events
925 | *
926 | * @param item
927 | * the selected menu item
928 | */
929 |
930 | public void toggleDisplayGrids() {
931 | setDisplayGrids(!isDisplayGrids());
932 | }
933 |
934 | /**
935 | * Sets file name
936 | */
937 |
938 | public void toggleDisplayXY() {
939 | setDisplayXY(!isDisplayXY());
940 | }
941 |
942 | public void toggleDisplayZ() {
943 | setDisplayZ(!isDisplayZ());
944 | }
945 |
946 | public void toggleExpectDelay() {
947 | setExpectDelay(!isExpectDelay());
948 | }
949 |
950 | public void toggleMesh() {
951 | setMesh(!isMesh());
952 | }
953 |
954 | public void togglePlotFunction1() {
955 | setPlotFunction1(!isPlotFunction1());
956 |
957 | }
958 |
959 | public void togglePlotFunction2() {
960 | setPlotFunction2(!isPlotFunction2());
961 |
962 | }
963 |
964 | public void toggleScaleBox() {
965 | setScaleBox(!isScaleBox());
966 | }
967 |
968 | }// end of class
969 |
--------------------------------------------------------------------------------