-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAxisBuilder.java
More file actions
232 lines (199 loc) · 6.96 KB
/
Copy pathAxisBuilder.java
File metadata and controls
232 lines (199 loc) · 6.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//package org.freehep.j3d.plot;
import java.awt.Font;
import java.awt.Color;
import javax.media.j3d.*;
import javax.vecmath.*;
public class AxisBuilder
{
/**
* Constructs an axis
* @author Joy Kyriakopulos (joyk@fnal.gov)
* @version $Id: AxisBuilder.java 8584 2006-08-10 23:06:37Z duns $
*/
AxisBuilder()
{
// build all the major components of the Axis, keeping the important
// parts in member variables so we can modify them later.
label = new Text3D(); // The Axis label
label.setAlignment(label.ALIGN_CENTER);
Point3f pos = new Point3f(scale/2,-labelOffSet,0);
label.setPosition(pos);
label.setCapability(label.ALLOW_FONT3D_WRITE);
label.setCapability(label.ALLOW_STRING_WRITE);
axis = new Shape3D(); // The axis and tick marks.
axis.setCapability(axis.ALLOW_GEOMETRY_WRITE);
// We can create the tick labels yet, since we don't know how many there
// will be, but we can make a group to hold them.
ticks = new BranchGroup();
ticks.setCapability(ticks.ALLOW_CHILDREN_READ);
ticks.setCapability(ticks.ALLOW_CHILDREN_WRITE);
ticks.setCapability(ticks.ALLOW_DETACH);
// Group the components together
mainGroup = new TransformGroup();
mainGroup.setCapability(ticks.ALLOW_CHILDREN_WRITE);
mainGroup.setCapability(ticks.ALLOW_CHILDREN_EXTEND);
mainGroup.addChild(new Shape3D(label));
mainGroup.addChild(axis);
mainGroup.addChild(ticks);
// Set up a BulletinBoard behaviour to keep the axis oriented
// towards the user.
mainGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
mainGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
Billboard bboard = new Billboard( mainGroup );
mainGroup.addChild( bboard );
bboard.setSchedulingBounds( new BoundingSphere(new Point3d(0,0,0),10));
bboard.setAlignmentAxis( 1.0f, 0.0f, 0.0f);
// Color3f col = new Color3f(0,0,0);
// mainGroup.add(col);
}
public String getLabel()
{
return labelText;
}
public void setLabel(String label)
{
labelText = label;
}
public Font3D getLabelFont()
{
return labelFont;
}
public void setLabelFont(Font3D font)
{
labelFont = font;
}
public Font3D getTickFont()
{
return tickFont;
}
public void setTickFont(Font3D font)
{
tickFont = font;
}
/**
* Tick labels and locations (positions) can be set
* by the caller or calculated and set by the
* createLabelsNTicks method as a convenience.
*/
public double[] getTickLocations()
{
return tickLocations;
}
public void setTickLocations(double[] ticks)
{
tickLocations = ticks;
}
public String[] getTickLabels()
{
return tickLabels;
}
public void setTickLabels(String[] labels)
{
tickLabels = labels;
}
/**
* Call the createLabelsNTicks method if you would like the
* axisbuilder to create axis labels and tick positions for you.
*/
public void createLabelsNTicks(double min, double max)
{
AxisLabelCalculator axisCalc = new AxisLabelCalculator();
axisCalc.createNewLabels(min, max);
// System.out.println("in createLabelsNTicks: min = " + min + ", max = " + max);
// axisCalc.printLabels();
tickLabels = axisCalc.getLabels();
tickLocations = axisCalc.getPositions();
}
/**
* Call this method after setting the required axis properties, to actually
* setup/modify the axis appearance.
*/
public void apply()
{
/*
* Build an axis on the X axis from 0 to 256. Note the reason for the
* 256 is to compensate for the giant size of the Text3D characters.
* The axis is built in the XY plane.
* We will use suitable translation and rotation to position it later.
*
* Note we currently use Text3D to draw the labels. This is because Text3D
* seems somewhat easier to use. A better solution would
* probably involve using Text2D, but the com.sun.j3d.utils.geometry.Text2D
* class seems pretty brain dead. A better solution may be to get the source
* for the Text2D class and rewrite it for our own purposes.
*/
//System.out.println("in apply: tickLocations.length = " + tickLocations.length + ", tickLabels.length = " + tickLabels.length);
int tMajor = (tickLocations.length-1)/(tickLabels.length-1);
LineArray lines = new LineArray(2*tickLocations.length+2, LineArray.COORDINATES);
int coordIdx = 0; // coordinate index into Axis linearray
// Actual axis
lines.setCoordinate(coordIdx++, new Point3d(0, 0, 0));
lines.setCoordinate(coordIdx++, new Point3d(scale, 0, 0));
// Remove the old tick labels. Note a more efficient implementation
// we would keep as many as of the old labels as possible, adding/removing
// new tick marks only as the number of tick marks change, and changing the
// text only as necessary. For now we just do the easiest thing.
// TODO: More efficient implementation.
// while (ticks.numChildren() > 0)
// ticks.removeChild(0);
ticks.detach();
ticks = new BranchGroup();
ticks.setCapability(ticks.ALLOW_CHILDREN_READ);
ticks.setCapability(ticks.ALLOW_CHILDREN_WRITE);
ticks.setCapability(ticks.ALLOW_DETACH);
// Rendering Ticks on Axis
for(int i = 0; i < tickLocations.length; i++)
{
float x = (float) tickLocations[i]*scale;
if (i % tMajor == 0) // Major tick mark?
{
lines.setCoordinate(coordIdx++, new Point3d(x, 0, 0));
lines.setCoordinate(coordIdx++, new Point3d(x, -major, 0));
// Add the tick label
int nt = i/tMajor;
Point3f pos = new Point3f(x,-tickOffSet,0);
Text3D tickLabel = new Text3D(tickFont,tickLabels[nt],pos);
tickLabel.setAlignment(tickLabel.ALIGN_CENTER);
ticks.addChild(new Shape3D(tickLabel));
}
else // Minor tick mark
{
lines.setCoordinate(coordIdx++, new Point3d(x, 0, 0));
lines.setCoordinate(coordIdx++, new Point3d(x, -minor, 0));
}
}
// TODO: It would be more efficient to only update the label if something has changed.
mainGroup.addChild(ticks);
label.setFont3D(labelFont);
label.setString(labelText);
axis.setGeometry(lines);
}
/**
* Returns the node representing this Axis
* Subclasses can override this method to transform this axis
* to make it into an X,Y,Z axis.
*/
public Node getNode()
{
return mainGroup;
}
private String labelText;
private Font3D labelFont = defaultLabelFont;
private double[] tickLocations;
private String[] tickLabels;
private Font3D tickFont = defaultTickFont;
private TransformGroup mainGroup;
private Text3D label;
private Shape3D axis;
private BranchGroup ticks;
protected static float scale = 256f; // See comment on apply
protected static float major = 0.02f*scale;
protected static float minor = 0.01f*scale;
protected static float tickOffSet = 0.06f*scale;
protected static float labelOffSet = 0.12f*scale;
private static final Font3D defaultLabelFont = new Font3D(new Font("DIALOG",Font.BOLD,12),null);
private static final Font3D defaultTickFont = new Font3D(new Font("DIALOG",Font.BOLD,7),null);
private static Color3f white = new Color3f(1,1,1);
// private static Color3f black = new Color3f(255,255,255);
// private static Color3f white = new Color3f(255,255,255);
}