// QuantumOsc3d.java (c) 2002 by Paul Falstad, www.falstad.com.
// Rendering algorithm in this applet is based on the description of
// the algorithm used in Atom in a Box by Dean Dauger (www.dauger.com).
// We raytrace through a 3-d dataset, sampling a number of points and
// integrating over them using Simpson's rule.
import java.io.InputStream;
import java.awt.*;
import java.awt.image.ImageProducer;
import java.applet.Applet;
import java.applet.AudioClip;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.File;
import java.util.Random;
import java.util.Arrays;
import java.awt.image.MemoryImageSource;
import java.lang.Math;
import java.awt.event.*;
class QuantumOsc3dCanvas extends Canvas {
QuantumOsc3dFrame pg;
QuantumOsc3dCanvas(QuantumOsc3dFrame p) {
pg = p;
}
public Dimension getPreferredSize() {
return new Dimension(300,400);
}
public void update(Graphics g) {
pg.updateQuantumOsc3d(g);
}
public void paint(Graphics g) {
pg.updateQuantumOsc3d(g);
}
};
class QuantumOsc3dLayout implements LayoutManager {
public QuantumOsc3dLayout() {}
public void addLayoutComponent(String name, Component c) {}
public void removeLayoutComponent(Component c) {}
public Dimension preferredLayoutSize(Container target) {
return new Dimension(500, 500);
}
public Dimension minimumLayoutSize(Container target) {
return new Dimension(100,100);
}
public void layoutContainer(Container target) {
int barwidth = 0;
int i;
for (i = 1; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
if (d.width > barwidth)
barwidth = d.width;
}
}
Insets insets = target.insets();
int targetw = target.size().width - insets.left - insets.right;
int cw = targetw-barwidth;
int targeth = target.size().height - (insets.top+insets.bottom);
target.getComponent(0).move(insets.left, insets.top);
target.getComponent(0).resize(cw, targeth);
cw += insets.left;
int h = insets.top;
for (i = 1; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
if (m instanceof Scrollbar)
d.width = barwidth;
if (m instanceof Label) {
h += d.height/5;
d.width = barwidth;
}
m.move(cw, h);
m.resize(d.width, d.height);
h += d.height;
}
}
}
};
public class QuantumOsc3d extends Applet {
static QuantumOsc3dFrame oc;
void destroyFrame() {
if (oc != null)
oc.dispose();
oc = null;
}
public static void main(String args[]) {
oc = new QuantumOsc3dFrame(null);
oc.init();
}
public void init() {
oc = new QuantumOsc3dFrame(this);
oc.init();
}
public void destroy() {
if (oc != null)
oc.dispose();
oc = null;
}
};
class QuantumOsc3dFrame extends Frame
implements ComponentListener, ActionListener, AdjustmentListener,
MouseMotionListener, MouseListener, ItemListener {
Thread engine = null;
Dimension winSize;
Image dbimage;
Random random;
int gridSizeX = 200;
int gridSizeY = 200;
public String getAppletInfo() {
return "QuantumOsc3d by Paul Falstad";
}
Button blankButton;
Button normalizeButton;
Button maximizeButton;
Checkbox memoryImageSourceCheck;
Checkbox stoppedCheck;
CheckboxMenuItem colorCheck;
CheckboxMenuItem eCheckItem;
CheckboxMenuItem xCheckItem;
CheckboxMenuItem lCheckItem;
CheckboxMenuItem alwaysNormItem;
CheckboxMenuItem axesItem;
CheckboxMenuItem autoZoomItem;
CheckboxMenuItem animatedZoomItem;
Menu measureMenu, presetsMenu;
MenuItem exitItem;
MenuItem measureEItem;
MenuItem measureLxItem;
MenuItem measureLyItem;
MenuItem measureLzItem;
MenuItem dispGaussItem;
MenuItem scaled1GaussItem;
MenuItem scaled2GaussItem;
MenuItem rotatingGaussItem;
MenuItem dispX110Item;
MenuItem dispZ110Item;
Choice modeChooser;
Choice viewChooser;
Choice sliceChooser, nChooser, lChooser, mChooser;
static final int SLICE_NONE = 0;
static final int SLICE_X = 1;
static final int SLICE_Y = 2;
static final int SLICE_Z = 3;
Scrollbar speedBar;
Scrollbar resolutionBar;
Scrollbar internalResBar;
Scrollbar brightnessBar;
Scrollbar scaleBar;
Scrollbar sampleBar;
View viewPotential, viewX, viewL, viewStates;
View viewList[];
int viewCount;
Orbital orbitals[];
int orbCount;
Phasor phasors[];
int phasorCount;
BasisState states[];
int stateCount;
AlternateBasis rectBasis, lxBasis, lyBasis;
AlternateBasis basisList[];
int basisCount;
TextBox textBoxes[];
int textCount;
boolean changingDerivedStates;
double dragZoomStart;
double zoom; // was 10
double rotmatrix[];
Rectangle viewAxes;
static final double pi = 3.14159265358979323846;
static final double pi2 = pi*2;
static final double root2 = 1.41421356237309504880;
static final double root2inv = .70710678118654752440;
static final double baseEnergy = 0;
int xpoints[];
int ypoints[];
int selectedPaneHandle;
double func[][][];
PhaseColor phaseColors[][];
double resadj;
boolean dragging = false;
MemoryImageSource imageSource;
int pixels[];
int sampleCount;
int dataSize;
static int maxModes = 10;
static int maxDispCoefs = 8;
static int viewDistance = 12;
int pause;
QuantumOsc3d applet;
State selectedState;
Phasor selectedPhasor;
int selection = -1;
static final int SEL_NONE = 0;
static final int SEL_POTENTIAL = 1;
static final int SEL_X = 2;
static final int SEL_STATES = 3;
static final int SEL_HANDLE = 4;
static final int MODE_ANGLE = 0;
static final int MODE_ROTATE_X = 1;
static final int MODE_ROTATE_Y = 2;
static final int MODE_ROTATE_Z = 3;
static final int MODE_SLICE = 5;
static final int VIEW_COMPLEX = 0;
static final int VIEW_COMBO_COMP = 1;
static final int VIEW_COMBO_RECT = 2;
static final int VIEW_COMBO_N1 = 3;
static final int VIEW_COMBO_N2 = 4;
static final int VIEW_COMBO_N3 = 5;
static final int VIEW_COMBO_N4 = 6;
int slicerPoints[][];
double sliceFaces[][];
double sliceFace[];
int sliceFaceCount;
double sliceval = 0;
int sampleMult[];
boolean selectedSlice;
boolean settingScale;
double magDragStart;
int dragX, dragY, dragStartX, dragStartY;
double t = 0;
public static final double epsilon = .01;
static final int panePad = 4;
static final int phaseColorCount = 50;
double funcr, funci;
int phiIndex, phiSector;
double bestBrightness, userBrightMult = 1;
boolean manualScale;
Color gray2;
FontMetrics fontMetrics;
int getrand(int x) {
int q = random.nextInt();
if (q < 0) q = -q;
return q % x;
}
QuantumOsc3dCanvas cv;
QuantumOsc3dFrame(QuantumOsc3d a) {
super("3-D Quantum Oscillator Viewer");
applet = a;
}
public void init() {
gray2 = new Color(127, 127, 127);
String os = System.getProperty("os.name");
String jv = System.getProperty("java.version");
boolean altRender = false;
int res = 100;
// change settings to speed things up where possible
if (os.indexOf("Windows") == 0) {
res = 100;
if (jv.indexOf("1.1") == 0)
altRender = true;
}
setLayout(new QuantumOsc3dLayout());
cv = new QuantumOsc3dCanvas(this);
cv.addComponentListener(this);
cv.addMouseMotionListener(this);
cv.addMouseListener(this);
add(cv);
MenuBar mb = new MenuBar();
Menu m = new Menu("File");
mb.add(m);
m.add(exitItem = getMenuItem("Exit"));
m = new Menu("View");
mb.add(m);
m.add(eCheckItem = getCheckItem("Energy"));
eCheckItem.setState(true);
m.add(xCheckItem = getCheckItem("Position"));
xCheckItem.setState(true);
xCheckItem.disable();
m.add(lCheckItem = getCheckItem("Angular Momentum"));
m.addSeparator();
m.add(colorCheck = getCheckItem("Phase as Color"));
colorCheck.setState(true);
measureMenu = m = new Menu("Measure");
mb.add(m);
m.add(measureEItem = getMenuItem("Measure Energy"));
m.add(measureLxItem = getMenuItem("Measure Lx"));
m.add(measureLyItem = getMenuItem("Measure Ly"));
m.add(measureLzItem = getMenuItem("Measure Lz"));
setMenuBar(mb);
m = new Menu("Options");
mb.add(m);
alwaysNormItem = getCheckItem("Always Normalize");
m.add(axesItem = getCheckItem("Show Axes"));
axesItem.setState(true);
m.add(autoZoomItem = getCheckItem("Auto Scale"));
autoZoomItem.setState(true);
m.add(animatedZoomItem = getCheckItem("Animated Scaling"));
animatedZoomItem.setState(true);
presetsMenu = m = new Menu("Presets");
mb.add(m);
m.add(dispGaussItem = getMenuItem("Displaced Gaussian"));
m.add(scaled1GaussItem = getMenuItem("Scaled Gaussian 1"));
m.add(scaled2GaussItem = getMenuItem("Scaled Gaussian 2"));
m.add(rotatingGaussItem = getMenuItem("Rotating Gaussian"));
m.add(dispX110Item = getMenuItem("1,0,1 Displaced X"));
m.add(dispZ110Item = getMenuItem("1,0,0 Displaced Z"));
setMenuBar(mb);
viewChooser = new Choice();
viewChooser.add("Single Wave Functions");
viewChooser.add("Combinations");
viewChooser.add("Rectangular Combos");
viewChooser.add("Multiple Bases (n=1)");
viewChooser.add("Multiple Bases (n=2)");
viewChooser.add("Multiple Bases (n=3)");
viewChooser.add("Multiple Bases (n=4)");
viewChooser.addItemListener(this);
add(viewChooser);
int i;
nChooser = new Choice();
for (i = 0; i <= maxnr; i++)
nChooser.add("nr = " + i);
nChooser.addItemListener(this);
add(nChooser);
nChooser.select(0);
lChooser = new Choice();
for (i = 0; i <= maxl; i++)
lChooser.add("l = " + i +
((i < 6) ? " (" + codeLetter[i] + ")" : ""));
lChooser.addItemListener(this);
add(lChooser);
mChooser = new Choice();
mChooser.addItemListener(this);
add(mChooser);
sliceChooser = new Choice();
sliceChooser.add("No Slicing");
sliceChooser.add("Show X Slice");
sliceChooser.add("Show Y Slice");
sliceChooser.add("Show Z Slice");
sliceChooser.addItemListener(this);
add(sliceChooser);
modeChooser = new Choice();
modeChooser.add("Mouse = Adjust View");
modeChooser.add("Mouse = Rotate X");
modeChooser.add("Mouse = Rotate Y");
modeChooser.add("Mouse = Rotate Z");
modeChooser.addItemListener(this);
add(modeChooser);
stoppedCheck = new Checkbox("Stopped");
stoppedCheck.addItemListener(this);
add(stoppedCheck);
add(blankButton = new Button("Clear"));
blankButton.addActionListener(this);
add(normalizeButton = new Button("Normalize"));
normalizeButton.addActionListener(this);
add(maximizeButton = new Button("Maximize"));
maximizeButton.addActionListener(this);
lChooser.select(3);
setLValue();
memoryImageSourceCheck = new Checkbox("Alternate Rendering",
altRender);
memoryImageSourceCheck.addItemListener(this);
add(memoryImageSourceCheck);
add(new Label("Simulation Speed", Label.CENTER));
add(speedBar = new Scrollbar(Scrollbar.HORIZONTAL, 20, 1, 1, 200));
speedBar.addAdjustmentListener(this);
add(new Label("Brightness", Label.CENTER));
add(brightnessBar = new Scrollbar(Scrollbar.HORIZONTAL, 240,
1, 1, 4000));
brightnessBar.addAdjustmentListener(this);
add(new Label("Image Resolution", Label.CENTER));
add(resolutionBar =
new Scrollbar(Scrollbar.HORIZONTAL, res, 2, 20, 500));
resolutionBar.addAdjustmentListener(this);
/*add(new Label("Internal Resolution", Label.CENTER));
add(internalResBar =
new Scrollbar(Scrollbar.HORIZONTAL, res, 2, 20, 200));
internalResBar.addAdjustmentListener(this);*/
add(new Label("Scale", Label.CENTER));
add(scaleBar = new Scrollbar(Scrollbar.HORIZONTAL, 75, 1, 5, 1620));
scaleBar.addAdjustmentListener(this);
/*add(new Label("Samples", Label.CENTER));
add(sampleBar = new Scrollbar(Scrollbar.HORIZONTAL, 7, 1, 0, 20));
sampleBar.addAdjustmentListener(this);*/
add(new Label("", Label.CENTER));
try {
String param = applet.getParameter("PAUSE");
if (param != null)
pause = Integer.parseInt(param);
} catch (Exception e) { }
int j;
phaseColors = new PhaseColor[8][phaseColorCount+1];
for (i = 0; i != 8; i++)
for (j = 0; j <= phaseColorCount; j++) {
double ang = java.lang.Math.atan(j/(double) phaseColorCount);
phaseColors[i][j] = genPhaseColor(i, ang);
}
slicerPoints = new int[2][5*2];
sliceFaces = new double[4][3];
rotmatrix = new double[9];
rotmatrix[0] = rotmatrix[4] = rotmatrix[8] = 1;
rotate(0, -pi/2);
xpoints = new int[4];
ypoints = new int[4];
setupSimpson();
setupStates();
random = new Random();
reinit();
orbitalChanged();
cv.setBackground(Color.black);
cv.setForeground(Color.white);
resize(680, 650);
handleResize();
show();
}
static final int maxnr = 11;
static final int maxl = 10;
void setupStates() {
stateCount = (maxnr+1) * ((maxl+1)*(maxl+1));
int i;
states = new BasisState[stateCount];
int nr = 0;
int l = 0;
int m = 0;
for (i = 0; i != stateCount; i++) {
BasisState bs = states[i] = new BasisState();
bs.elevel = 2*nr+l+1.5;
bs.nr = nr;
bs.l = l;
bs.m = m;
bs.n = 2*nr+l;
if (m < l)
m++;
else {
l++;
if (l <= maxl)
m = -l;
else {
nr++;
l = m = 0;
}
}
}
basisList = new AlternateBasis[17];
basisCount = 0;
rectBasis = setupRectBasis();
lxBasis = initBasis(35, true);
setupLBasis(lxBasis, 0, 0, true, l0Array);
setupLBasis(lxBasis, 0, 1, true, l1xArray);
setupLBasis(lxBasis, 0, 2, true, l2xArray);
setupLBasis(lxBasis, 0, 3, true, l3xArray);
setupLBasis(lxBasis, 0, 4, true, l4xArray);
setupLBasis(lxBasis, 1, 0, true, l0Array);
setupLBasis(lxBasis, 1, 1, true, l1xArray);
setupLBasis(lxBasis, 1, 2, true, l2xArray);
setupLBasis(lxBasis, 2, 0, true, l0Array);
lyBasis = initBasis(35, true);
setupLBasis(lyBasis, 0, 0, false, l0Array);
setupLBasis(lyBasis, 0, 1, false, l1yArray);
setupLBasis(lyBasis, 0, 2, false, l2yArray);
setupLBasis(lyBasis, 0, 3, false, l3yArray);
setupLBasis(lyBasis, 0, 4, false, l4yArray);
setupLBasis(lyBasis, 1, 0, false, l0Array);
setupLBasis(lyBasis, 1, 1, false, l1yArray);
setupLBasis(lyBasis, 1, 2, false, l2yArray);
setupLBasis(lyBasis, 2, 0, false, l0Array);
}
AlternateBasis initBasis(int sct, boolean xAxis) {
AlternateBasis basis = new AlternateBasis();
basis.xAxis = xAxis;
basis.altStates = new DerivedState[sct];
basis.altStateCount = 0;
return basis;
}
void setupLBasis(AlternateBasis basis,
int nr, int l, boolean xAxis, double arr[]) {
String mtext = (xAxis) ? "mx" : "my";
int i;
int lct = l*2+1;
int ap = 0;
for (i = 0; i != lct; i++) {
int sn = basis.altStateCount++;
DerivedState ds = basis.altStates[sn] = new DerivedState();
ds.basis = basis;
ds.count = lct;
ds.bstates = new BasisState[lct];
ds.coefs = new Complex[lct];
ds.m = i-l;
ds.l = l;
ds.nr = nr;
ds.n = 2*nr+l;
ds.elevel = 2*nr+l+1.5;
int j;
for (j = 0; j != lct; j++) {
ds.bstates[j] = getState(nr, l, j-l);
ds.coefs[j] = new Complex();
}
ds.text = "n = " + ds.n + ", nr = " + nr + ", l = " + l + ", " +
mtext + " = " + ds.m;
for (j = 0; j != lct; j++) {
ds.coefs[j].set(arr[ap], arr[ap+1]);
ap += 2;
}
}
}
AlternateBasis setupRectBasis() {
int sct = 35;
AlternateBasis basis = new AlternateBasis();
basis.altStates = new DerivedState[sct];
basis.altStateCount = sct;
int i;
int nx = 0, ny = 0, nz = 0;
int ap = 0;
for (i = 0; i != sct; i++) {
int n = nx+ny+nz;
int n21 = n/2+1;
int l = ((n & 1) == 0) ? 0 : 1;
int nr = n/2;
int m = -l;
DerivedState ds = basis.altStates[i] = new DerivedState();
ds.basis = basis;
ds.count = (l == 0) ? 2*n21*n21-n21 : 2*n21*n21+n21;
ds.bstates = new BasisState[sct];
ds.coefs = new Complex[sct];
ds.text = "nx = " + nx + ", ny = " + ny + ", nz = " + nz;
ds.nx = nx; ds.ny = ny; ds.nz = nz;
ds.n = n;
ds.elevel = 2*nr+l+1.5;
int j;
for (j = 0; j != ds.count; j++) {
ds.bstates[j] = getState(nr, l, m);
ds.coefs[j] =
new Complex(rectArrayR[ap], rectArrayI[ap]);
ap++;
if (m++ == l) {
l += 2;
nr--;
m = -l;
}
}
if (i == sct-1)
break;
do {
nz++;
if (nz > 4) {
nz = 0;
nx++;
if (nx > 4) {
nx = 0;
ny++;
}
}
} while (nx+ny+nz > 4);
}
return basis;
}
// Lx and Ly eigenvectors for various values of l, expressed in
// terms of Lz eigenvectors
double l0Array[] = {1, 0};
double l1xArray[] = { .5, 0, -root2inv, 0, .5, 0, root2inv, 0, 0, 0,
-root2inv, 0, .5, 0, root2inv, 0, .5, 0 };
double l1yArray[] = { .5, 0, 0, -root2inv, -.5, 0, 0, -root2inv,
0, 0, 0, -root2inv, .5, 0, 0, root2inv, -.5, 0 };
static final double root6by4 = .61237243569579452454;
double l2xArray[] = {
1/4., 0, -1/2., 0, root6by4, 0, -1/2., 0, 1/4., 0,
-.5, 0, .5, 0, 0, 0, -.5, 0, .5, 0,
root6by4, 0, 0, 0, -.5, 0, 0, 0, root6by4, 0,
-.5, 0, -.5, 0, 0, 0, .5, 0, .5, 0,
1/4., 0, 1/2., 0, root6by4, 0, 1/2., 0, 1/4., 0
};
double l2yArray[] = {
1/4., 0, 0, -1/2., -root6by4, 0, 0, 1/2., 1/4., 0,
-.5, 0, 0, .5, 0, 0, 0, .5, .5, 0,
-root6by4, 0, 0, 0, -.5, 0, 0, 0, -root6by4, 0,
-.5, 0, 0, -.5, 0, 0, 0, -.5, .5, 0,
1/4., 0, 0, 1/2., -root6by4, 0, 0, -1/2., 1/4., 0
};
double l3xArray[] = {
0.125,0, -0.306186,0, 0.484123,0, -0.559017,0,
0.484123,0, -0.306186,0, 0.125,0,
-0.306186,0, 0.5,0, -0.395285,0, 0.,0,
0.395285,0, -0.5,0, 0.306186,0,
0.484123,0, -0.395285,0, -0.125,0, 0.433013,0,
-0.125,0, -0.395285,0, 0.4841230,0,
0.559017,0, 0.,0, -0.433013,0, 0.,0,
0.433013,0, 0.,0, -0.559017,0,
0.484123,0, 0.395285,0, -0.125,0, -0.433013,0,
-0.125,0, 0.395285,0, 0.484123,0,
-0.306186,0, -0.5,0, -0.395285,0, 0.,0,
0.395285,0, 0.5,0, 0.306186,0,
0.125,0, 0.306186,0, 0.484123,0, 0.559017,0,
0.484123,0, 0.306186,0, 0.125,0
};
double l3yArray[] = {
-0.125,0, 0,0.306186, 0.484123,0, 0,-0.559017,
-0.484123,0, 0,0.306186, 0.125,0,
0.306186,0, 0,-0.5, -0.395285,0, 0.,0,
-0.395285,0, 0,0.5, 0.306186,0,
-0.484123,0, 0,0.395285, -0.125,0, 0,0.433013,
0.125,0, 0,0.395285, 0.484123,0,
0,0.559017, 0.,0, 0,0.433013, 0.,0,
0,0.433013, 0.,0, 0,0.559017,
-0.484123,0, 0,-0.395285, -0.125,0, 0,-0.433013,
0.125,0, 0,-0.395285, 0.484123,0,
0.306186,0, 0,+0.5, -0.395285,0, 0.,0, -0.395285,0,
0,-0.5, 0.306186,0,
-0.125,0, 0,-0.306186, 0.484123,0, 0,+0.559017,
-0.484123,0, 0,-0.306186, 0.125,0
};
double l4xArray[] = {
0.0625, 0., -0.176777, 0., 0.330719, 0., -0.467707,
0., 0.522913, 0., -0.467707, 0., 0.330719, 0., -0.176777,
0., 0.0625, 0., -0.176777, 0., 0.375, 0., -0.467707, 0.,
0.330719, 0., 0., 0., -0.330719, 0., 0.467707, 0., -0.375,
0., 0.176777, 0., 0.330719, 0., -0.467707, 0., 0.25,
0., 0.176777, 0., -0.395285, 0., 0.176777, 0., 0.25, 0.,
-0.467707, 0., 0.330719, 0., -0.467707, 0., 0.330719, 0.,
0.176777, 0., -0.375, 0., 0., 0., 0.375, 0., -0.176777,
0., -0.330719, 0., 0.467707, 0., 0.522913, 0., 0., 0.,
-0.395285, 0., 0., 0., 0.375, 0., 0., 0., -0.395285,
0., 0., 0., 0.522913, 0., -0.467707, 0., -0.330719, 0.,
0.176777, 0., 0.375, 0., 0., 0., -0.375, 0., -0.176777,
0., 0.330719, 0., 0.467707, 0., 0.330719, 0., 0.467707,
0., 0.25, 0., -0.176777, 0., -0.395285, 0., -0.176777,
0., 0.25, 0., 0.467707, 0., 0.330719, 0., -0.176777, 0.,
-0.375, 0., -0.467707, 0., -0.330719, 0., 0., 0., 0.330719,
0., 0.467707, 0., 0.375, 0., 0.176777, 0., 0.0625, 0.,
0.176777, 0., 0.330719, 0., 0.467707, 0., 0.522913, 0.,
0.467707, 0., 0.330719, 0., 0.176777, 0., 0.0625, 0.
};
double l4yArray[] = {
0.0625, 0., 0., -0.176777, -0.330719, 0., 0., 0.467707,
0.522913, 0., 0., -0.467707, -0.330719, 0., 0., 0.176777,
0.0625, 0., -0.176777, 0., 0., 0.375, 0.467707, 0., 0.,
-0.330719, 0., 0., 0., -0.330719, -0.467707, 0., 0.,
0.375, 0.176777, 0., 0.330719, 0., 0., -0.467707, -0.25,
0., 0., -0.176777, -0.395285, 0., 0., 0.176777, -0.25, 0.,
0., 0.467707, 0.330719, 0., -0.467707, 0., 0., 0.330719,
-0.176777, 0., 0., 0.375, 0., 0., 0., 0.375, 0.176777,
0., 0., 0.330719, 0.467707, 0., 0.522913, 0., 0., 0.,
0.395285, 0., 0., 0., 0.375, 0., 0., 0., 0.395285, 0., 0.,
0., 0.522913, 0., -0.467707, 0., 0., -0.330719, -0.176777,
0., 0., -0.375, 0., 0., 0., -0.375, 0.176777, 0., 0.,
-0.330719, 0.467707, 0., 0.330719, 0., 0., 0.467707,
-0.25, 0., 0., 0.176777, -0.395285, 0., 0., -0.176777,
-0.25, 0., 0., -0.467707, 0.330719, 0., -0.176777, 0., 0.,
-0.375, 0.467707, 0., 0., 0.330719, 0., 0., 0., 0.330719,
-0.467707, 0., 0., -0.375, 0.176777, 0., 0.0625, 0., 0.,
0.176777, -0.330719, 0., 0., -0.467707, 0.522913, 0., 0.,
0.467707, -0.330719, 0., 0., -0.176777, 0.0625, 0.
};
// precomputed using brute-force mathematica code
double rectArrayR[] = {
1.,0.,1.,0.,-0.57735,0.,0.,0.816497,0.,0.,0.,-0.774597,0.,0.,0.,
0.,0.632456,0.,0.,0.,0.447214,0.,0.,-0.755929,0.,0.,0.,0.,0.,0.,
0.478091,0.,0.,0.,0.,0.707107,0.,-0.707107,0.,0.,0.707107,0.,
-0.707107,0.,-0.316228,0.,0.316228,0.,0.,0.632456,0.,-0.632456,
0.,0.,0.,0.,-0.46291,0.,0.46291,0.,0.,0.,0.,0.534522,0.,
-0.534522,0.,0.,0.,-0.57735,0.5,0.,-0.408248,0.,0.5,0.,
-0.447214,0.,0.,0.5,0.,-0.547723,0.,0.5,0.,0.365148,-0.188982,0.,
-0.154303,0.,-0.188982,0.,0.,0.46291,0.,-0.58554,0.,0.46291,0.,0.,
-0.547723,0.,0.547723,0.353553,0.,-0.273861,0.,0.273861,0.,
-0.353553,0.,0.,-0.46291,0.,0.46291,0.,0.,0.353553,0.,-0.400892,
0.,0.400892,0.,-0.353553,0.,0.447214,-0.46291,0.,0.377964,0.,
-0.46291,0.25,0.,-0.188982,0.,0.179284,0.,-0.188982,0.,0.25,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.,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.,0.,0.,0.,0.,0.,
-0.57735,-0.5,0.,-0.408248,0.,-0.5,0.,-0.447214,0.,0.,-0.5,0.,
-0.547723,0.,-0.5,0.,0.365148,0.188982,0.,-0.154303,0.,0.188982,
0.,0.,-0.46291,0.,-0.58554,0.,-0.46291,0.,0.,-0.316228,0.,0.316228,
-0.612372,0.,-0.158114,0.,0.158114,0.,0.612372,0.,0.,
-0.267261,0.,0.267261,0.,0.,-0.612372,0.,-0.231455,0.,
0.231455,0.,0.612372,0.,0.365148,0.,0.,0.308607,0.,0.,
-0.612372,0.,0.,0.,0.146385,0.,0.,0.,-0.612372,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.447214,0.46291,0.,
0.377964,0.,0.46291,0.25,0.,0.188982,0.,0.179284,0.,0.188982,0.,0.25
};
double rectArrayI[] = {
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.,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.,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.707107,0.,-0.707107,0.,0.,-0.707107,0.,
-0.707107,0.,0.316228,0.,0.316228,0.,0.,-0.632456,0.,-0.632456,0.,
0.,0.,0.,0.46291,0.,0.46291,0.,0.,0.,0.,-0.534522,0.,-0.534522,0.,
0.,0.,0.,-0.707107,0.,0.,0.,0.707107,0.,0.,0.,0.,-0.707107,0.,0.,0.,
0.707107,0.,0.,0.267261,0.,0.,0.,-0.267261,0.,0.,-0.654654,0.,0.,0.,
0.654654,0.,0.,0.316228,0.,0.316228,-0.612372,0.,0.158114,0.,
0.158114,0.,-0.612372,0.,0.,0.267261,0.,0.267261,0.,0.,-0.612372,
0.,0.231455,0.,0.231455,0.,-0.612372,0.,0.,0.46291,0.,0.,0.,
-0.46291,-0.5,0.,0.188982,0.,0.,0.,-0.188982,0.,0.5,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.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
0.547723,0.,0.547723,0.353553,0.,0.273861,0.,0.273861,0.,0.353553,
0.,0.,0.46291,0.,0.46291,0.,0.,0.353553,0.,0.400892,0.,0.400892,0.,
0.353553,0.,0.,0.46291,0.,0.,0.,-0.46291,0.5,0.,0.188982,0.,0.,0.,
-0.188982,0.,-0.5,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.
};
MenuItem getMenuItem(String s) {
MenuItem mi = new MenuItem(s);
mi.addActionListener(this);
return mi;
}
CheckboxMenuItem getCheckItem(String s) {
CheckboxMenuItem mi = new CheckboxMenuItem(s);
mi.addItemListener(this);
return mi;
}
PhaseColor genPhaseColor(int sec, double ang) {
// convert to 0 .. 2*pi angle
ang += sec*pi/4;
// convert to 0 .. 6
ang *= 3/pi;
int hsec = (int) ang;
double a2 = ang % 1;
double a3 = 1.-a2;
PhaseColor c = null;
switch (hsec) {
case 6:
case 0: c = new PhaseColor(1, a2, 0); break;
case 1: c = new PhaseColor(a3, 1, 0); break;
case 2: c = new PhaseColor(0, 1, a2); break;
case 3: c = new PhaseColor(0, a3, 1); break;
case 4: c = new PhaseColor(a2, 0, 1); break;
case 5: c = new PhaseColor(1, 0, a3); break;
}
return c;
}
void setupSimpson() {
sampleCount = 9; // 15;
//sampleCount = sampleBar.getValue()*2+1;
//System.out.print("sampleCount = " + sampleCount + "\n");
// generate table of sample multipliers for efficient Simpson's rule
sampleMult = new int[sampleCount];
int i;
for (i = 1; i < sampleCount; i += 2) {
sampleMult[i ] = 4;
sampleMult[i+1] = 2;
}
sampleMult[0] = sampleMult[sampleCount-1] = 1;
}
void handleResize() {
reinit();
}
void reinit() {
setResolution();
Dimension d = winSize = cv.getSize();
if (winSize.width == 0)
return;
dbimage = createImage(d.width, d.height);
setupDisplay();
}
void setupMenus() {
switch (viewChooser.getSelectedIndex()) {
case VIEW_COMPLEX:
nChooser.show();
lChooser.show();
mChooser.show();
modeChooser.hide();
modeChooser.select(MODE_ANGLE);
blankButton.hide();
normalizeButton.hide();
maximizeButton.hide();
alwaysNormItem.disable();
measureMenu.disable();
break;
default:
nChooser.hide();
lChooser.hide();
mChooser.hide();
modeChooser.show();
blankButton.show();
normalizeButton.show();
maximizeButton.show();
alwaysNormItem.enable();
measureMenu.enable();
break;
}
switch (viewChooser.getSelectedIndex()) {
case VIEW_COMBO_COMP:
case VIEW_COMBO_RECT:
presetsMenu.enable();
break;
default:
presetsMenu.disable();
break;
}
validate();
}
void createPhasors() {
phasorCount = textCount = 0;
int i;
for (i = 0; i != basisCount; i++)
basisList[i].active = false;
if (viewStates == null)
return;
int sz = viewStates.height/4;
int x = 0;
int y = viewStates.y;
int y0 = y;
int nr = 0, l = 0, m = 0;
int sz2;
textBoxes = new TextBox[10];
switch (viewChooser.getSelectedIndex()) {
case VIEW_COMPLEX:
break;
case VIEW_COMBO_COMP:
phasorCount = 25*4;
phasors = new Phasor[phasorCount];
sz2 = viewStates.width / 25;
if (sz > sz2)
sz = sz2;
if (sz < 10)
sz = 10;
for (i = 0; i != phasorCount; i++) {
Phasor ph = phasors[i] = new Phasor(x, y, sz, sz);
ph.state = getState(nr, l, m);
x += sz;
if (++m > l) {
y += sz/2;
l++;
m = -l;
if (l >= 5) {
x = 0;
y0 += sz;
y = y0;
nr++;
l = m = 0;
}
}
}
break;
case VIEW_COMBO_RECT:
sz = viewStates.height/5;
phasorCount = rectBasis.altStateCount;
phasors = new Phasor[phasorCount];
i = 0;
for (m = 0; m != 5; m++) {
i = createRectPhasors(x, y, sz, i, 5-m);
x += (5-m)*sz + sz/2;
}
break;
case VIEW_COMBO_N1:
phasorCount = 12;
phasors = new Phasor[phasorCount];
i = 0;
i = createBasisPhasors(x, y, sz, i, 0, 1);
createText("Lz", x+sz*3, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lxBasis, 3, 1);
createText("Lx", x+sz*3, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lyBasis, 3, 1);
createText("Ly", x+sz*3, y, sz);
y += sz;
i = createRectPhasorsN(x, y, sz, i, rectBasis, 1);
createText("Rect", x+sz*3, y, sz);
break;
case VIEW_COMBO_N2:
phasorCount = 6*4;
phasors = new Phasor[phasorCount];
i = 0;
i = createBasisPhasors(x, y, sz, i, 1, 0);
i = createBasisPhasors(x+sz*2, y, sz, i, 0, 2);
createText("Lz", x+sz*7, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lxBasis, 1, 25);
i = createAltPhasors(x+sz*2, y, sz, i, lxBasis, 5, 4);
createText("Lx", x+sz*7, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lyBasis, 1, 25);
i = createAltPhasors(x+sz*2, y, sz, i, lyBasis, 5, 4);
createText("Ly", x+sz*7, y, sz);
y += sz;
i = createRectPhasorsN(x, y, sz, i, rectBasis, 2);
createText("Rect", x+sz*7, y, sz);
break;
case VIEW_COMBO_N3:
phasorCount = 10*4;
phasors = new Phasor[phasorCount];
i = 0;
i = createBasisPhasors(x, y, sz, i, 1, 1);
i = createBasisPhasors(x+sz*4, y, sz, i, 0, 3);
createText("Lz", x+sz*12, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lxBasis, 3, 26);
i = createAltPhasors(x+sz*4, y, sz, i, lxBasis, 7, 9);
createText("Lx", x+sz*12, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lyBasis, 3, 26);
i = createAltPhasors(x+sz*4, y, sz, i, lyBasis, 7, 9);
createText("Ly", x+sz*12, y, sz);
y += sz;
i = createRectPhasorsN(x, y, sz, i, rectBasis, 3);
createText("Rect", x+sz*12, y, sz);
break;
case VIEW_COMBO_N4:
phasorCount = 15*4;
phasors = new Phasor[phasorCount];
i = 0;
i = createBasisPhasors(x, y, sz, i, 2, 0);
i = createBasisPhasors(x+sz*2, y, sz, i, 1, 2);
i = createBasisPhasors(x+sz*8, y, sz, i, 0, 4);
createText("Lz", x+sz*17, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lxBasis, 1, 34);
i = createAltPhasors(x+sz*2, y, sz, i, lxBasis, 5, 29);
i = createAltPhasors(x+sz*8, y, sz, i, lxBasis, 9, 16);
createText("Lx", x+sz*17, y, sz);
y += sz;
i = createAltPhasors(x, y, sz, i, lyBasis, 1, 34);
i = createAltPhasors(x+sz*2, y, sz, i, lyBasis, 5, 29);
i = createAltPhasors(x+sz*8, y, sz, i, lyBasis, 9, 16);
createText("Ly", x+sz*17, y, sz);
y += sz;
i = createRectPhasorsN(x, y, sz, i, rectBasis, 4);
createText("Rect", x+sz*17, y, sz);
break;
}
for (i = 0; i != phasorCount; i++)
phasors[i].state.setBasisActive();
for (i = 0; i != basisCount; i++) {
if (basisList[i].active) {
// this clears out any states which do not have phasors present
basisList[i].convertBasisToDerived();
basisList[i].convertDerivedToBasis();
}
}
// and if we're viewing Complex Combos, we need an extra step
// to clear out any states with phasors not present. All other
// views are handled by the previous loop.
if (viewChooser.getSelectedIndex() == VIEW_COMBO_COMP)
for (i = 0; i != stateCount; i++)
if (states[i].nr >= 4 || states[i].l >= 5)
states[i].set(0);
// in case the states changed
createOrbitals();
}
boolean higherStatesPresent() {
int i;
for (i = 0; i != stateCount; i++)
if (states[i].n > 4 && states[i].mag > 0)
return true;
return false;
}
void setInitialOrbital() {
if (phasorCount == 0)
return;
int i;
for (i = 0; i != phasorCount; i++)
if (phasors[i].state.mag > 0)
return;
doClear();
// no states active, so pick a phasor and select it.
phasors[0].state.set(1);
createOrbitals();
}
int createBasisPhasors(int x, int y, int sz, int i, int nr, int l) {
int j;
for (j = 0; j != l*2+1; j++) {
Phasor ph = phasors[i] = new Phasor(x, y, sz, sz);
ph.state = getState(nr, l, j-l);
x += sz;
i++;
}
return i;
}
int createAltPhasors(int x, int y, int sz, int i, AlternateBasis basis,
int ct, int offset) {
int j;
for (j = 0; j != ct; j++) {
Phasor ph = phasors[i] = new Phasor(x, y, sz, sz);
ph.state = basis.altStates[j+offset];
x += sz;
i++;
}
return i;
}
int createRectPhasorsN(int x, int y, int sz, int i, AlternateBasis basis,
int n) {
int j;
for (j = 0; j != basis.altStateCount; j++) {
DerivedState ds = basis.altStates[j];
if (ds.nx+ds.ny+ds.nz != n)
continue;
Phasor ph = phasors[i] = new Phasor(x, y, sz, sz);
ph.state = basis.altStates[j];
x += sz;
i++;
}
return i;
}
int createRectPhasors(int x, int y, int sz, int i, int nz) {
while (nz > 0) {
i = createAltPhasors(x, y, sz, i, rectBasis, nz, i);
y += sz;
nz--;
}
return i;
}
void createText(String text, int x, int y, int sz) {
TextBox tb = new TextBox(x+10, y, winSize.width-x, sz, text);
textBoxes[textCount++] = tb;
}
void setupDisplay() {
if (winSize == null)
return;
int potsize = (viewPotential == null) ? 50 : viewPotential.height;
int statesize = (viewStates == null) ? 64 : viewStates.height;
viewX = viewPotential = viewL = viewStates = null;
viewList = new View[10];
int i = 0;
if (eCheckItem.getState())
viewList[i++] = viewPotential = new View();
if (xCheckItem.getState())
viewList[i++] = viewX = new View();
if (lCheckItem.getState())
viewList[i++] = viewL = new View();
if (viewChooser.getSelectedIndex() > VIEW_COMPLEX)
viewList[i++] = viewStates = new View();
viewCount = i;
int sizenum = viewCount;
int toth = winSize.height;
// preserve size of potential and state panes if possible
if (potsize > 0 && viewPotential != null) {
sizenum--;
toth -= potsize;
}
if (statesize > 0 && viewStates != null) {
sizenum--;
toth -= statesize;
}
toth -= panePad*2*(viewCount-1);
int cury = 0;
for (i = 0; i != viewCount; i++) {
View v = viewList[i];
int h = (sizenum == 0) ? toth : toth/sizenum;
if (v == viewPotential && potsize > 0)
h = potsize;
else if (v == viewStates && statesize > 0)
h = statesize;
v.paneY = cury;
if (cury > 0)
cury += panePad;
v.x = 0;
v.width = winSize.width;
v.y = cury;
v.height = h;
cury += h+panePad;
}
setSubViews();
}
void setSubViews() {
int i;
pixels = new int[viewX.width*viewX.height];
for (i = 0; i != viewX.width*viewX.height; i++)
pixels[i] = 0xFF000000;
imageSource = new MemoryImageSource(viewX.width, viewX.height,
pixels, 0, viewX.width);
int asize = (int) (min(viewX.width, viewX.height)/3);
viewAxes = new Rectangle(viewX.x+winSize.width-asize, viewX.y,
asize, asize);
setupMenus();
createPhasors();
}
int getTermWidth() {
return 8;
}
// multiply rotation matrix by rotations through angle1 and angle2
void rotate(double angle1, double angle2) {
double r1cos = java.lang.Math.cos(angle1);
double r1sin = java.lang.Math.sin(angle1);
double r2cos = java.lang.Math.cos(angle2);
double r2sin = java.lang.Math.sin(angle2);
double rotm2[] = new double[9];
// angle1 is angle about y axis, angle2 is angle about x axis
rotm2[0] = r1cos;
rotm2[1] = -r1sin*r2sin;
rotm2[2] = r2cos*r1sin;
rotm2[3] = 0;
rotm2[4] = r2cos;
rotm2[5] = r2sin;
rotm2[6] = -r1sin;
rotm2[7] = -r1cos*r2sin;
rotm2[8] = r1cos*r2cos;
double rotm1[] = rotmatrix;
rotmatrix = new double[9];
int i, j, k;
for (j = 0; j != 3; j++)
for (i = 0; i != 3; i++) {
double v = 0;
for (k = 0; k != 3; k++)
v += rotm1[k+j*3]*rotm2[i+k*3];
rotmatrix[i+j*3] = v;
}
}
double max(double a, double b) { return a > b ? a : b; }
double min(double a, double b) { return a < b ? a : b; }
void setResolution() {
int og = gridSizeX;
gridSizeX = gridSizeY = (resolutionBar.getValue() & ~1);
if (og == gridSizeX)
return;
dataSize = gridSizeX*4; // (internalResBar.getValue() & ~1);
System.out.print("setResolution " + dataSize + " " +
gridSizeX + "\n");
// was 50
resadj = 50./dataSize;
precomputeAll();
func = new double[gridSizeX][gridSizeY][3];
}
int getNR() { return nChooser.getSelectedIndex(); }
int getL() { return lChooser.getSelectedIndex(); }
int getM() { return mChooser.getSelectedIndex() - getL(); }
String codeLetter[] = {
"s", "p", "d", "f", "g", "h"
};
void setLValue() {
int l = getL();
int i;
mChooser.removeAll();
for (i = -l; i <= l; i++)
mChooser.add("m = " + i);
mChooser.select(l);
validate();
}
// compute func[][][] array (2-d view) by raytracing through a
// 3-d dataset (data[][][])
void computeView(double colorMult, double normmult) {
int i, j;
double q = 3.14159265/dataSize;
boolean color = colorCheck.getState();
for (i = 0; i != orbCount; i++)
orbitals[i].setupFrame(normmult);
double izoom = 1/zoom;
double rotm[] = rotmatrix;
double aratio = viewX.width/(double) viewX.height;
double xmult = dataSize/2.;
double ymult = dataSize/2.;
double zmult = dataSize/2.;
double aratiox = izoom, aratioy = izoom;
// preserve aspect ratio no matter what window dimensions
if (aratio < 1)
aratioy /= aratio;
else
aratiox *= aratio;
int slice = sliceChooser.getSelectedIndex();
double boundRadius2 = 0;
for (i = 0; i != orbCount; i++) {
Orbital oo = orbitals[i];
double br = oo.getBoundRadius(colorMult);
if (br > boundRadius2)
boundRadius2 = br;
}
boundRadius2 *= boundRadius2;
for (i = 0; i != gridSizeX; i++)
for (j = 0; j != gridSizeY; j++) {
// calculate camera direction
double camvx0 = (2*i/(double) gridSizeX - 1)*aratiox;
double camvy0 = -(2*j/(double) gridSizeY - 1)*aratioy;
// rotate camera with rotation matrix
double camx = rotm[2]*viewDistance;
double camy = rotm[5]*viewDistance;
double camz = rotm[8]*viewDistance;
double camvx = rotm[0]*camvx0+rotm[1]*camvy0-rotm[2];
double camvy = rotm[3]*camvx0+rotm[4]*camvy0-rotm[5];
double camvz = rotm[6]*camvx0+rotm[7]*camvy0-rotm[8];
double camnorm =
java.lang.Math.sqrt(camvx0*camvx0+camvy0*camvy0+1);
int n;
double simpr = 0;
double simpg = 0;
double simpb = 0;
// calculate intersections with bounding sphere
double a = camvx*camvx+camvy*camvy+camvz*camvz;
double b = 2*(camvx*camx+camvy*camy+camvz*camz);
double c = camx*camx+camy*camy+camz*camz-boundRadius2;
double discrim = b*b-4*a*c;
func[i][j][0] = func[i][j][1] = func[i][j][2] = 0;
if (discrim < 0) {
// doesn't hit it
continue;
}
discrim = java.lang.Math.sqrt(discrim);
double mint = (-b-discrim)/(2*a);
double maxt = (-b+discrim)/(2*a);
if (slice != SLICE_NONE) {
double t = -100;
switch (slice) {
case SLICE_X: t = (sliceval-camx)/camvx; break;
case SLICE_Y: t = (sliceval-camy)/camvy; break;
case SLICE_Z: t = (sliceval-camz)/camvz; break;
}
if (t < mint || t > maxt)
continue;
mint = maxt = t;
}
// sample evenly along intersecting portion
double tstep = (maxt-mint)/(sampleCount-1);
double pathlen = (maxt-mint)*camnorm;
int maxn = sampleCount;
double xx = (camx + camvx * mint) * xmult;
double yy = (camy + camvy * mint) * ymult;
double zz = (camz + camvz * mint) * zmult;
if (slice != SLICE_NONE) {
maxn = 1;
pathlen = 2;
if (xx > xmult || yy > ymult || zz > zmult ||
xx < -xmult || yy < -ymult || zz < -zmult)
continue;
}
camvx *= tstep*xmult;
camvy *= tstep*ymult;
camvz *= tstep*zmult;
int dshalf = dataSize/2;
int oi;
for (n = 0; n < maxn; n++) {
// find grid element that contains sampled point
double r = java.lang.Math.sqrt(xx*xx+yy*yy+zz*zz);
double costh = zz/r;
int ri = (int) r;
int costhi = (int) (costh*dshalf+dshalf);
double fr = 0, fi = 0;
calcPhiComponent(xx, yy);
for (oi = 0; oi != orbCount; oi++) {
Orbital oo = orbitals[oi];
oo.computePoint(ri, costhi);
fr += funcr;
fi += funci;
}
if (color) {
double fv = fr*fr+fi*fi;
fv *= sampleMult[n];
PhaseColor col = getPhaseColor(fr, fi);
simpr += col.r * fv;
simpg += col.g * fv;
simpb += col.b * fv;
} else {
double fv = (fr*fr+fi*fi) * sampleMult[n];
simpr = simpg = (simpb += fv);
}
xx += camvx;
yy += camvy;
zz += camvz;
}
simpr *= pathlen/n;
simpg *= pathlen/n;
simpb *= pathlen/n;
func[i][j][0] = simpr;
func[i][j][1] = simpg;
func[i][j][2] = simpb;
}
}
PhaseColor getPhaseColor(double x, double y) {
int sector = 0;
double val = 0;
if (x == 0 && y == 0)
return phaseColors[0][0];
if (y >= 0) {
if (x >= 0) {
if (x >= y) {
sector = 0;
val = y/x;
} else {
sector = 1;
val = 1-x/y;
}
} else {
if (-x <= y) {
sector = 2;
val = -x/y;
} else {
sector = 3;
val = 1+y/x;
}
}
} else {
if (x <= 0) {
if (y >= x) {
sector = 4;
val = y/x;
} else {
sector = 5;
val = 1-x/y;
}
} else {
if (-y >= x) {
sector = 6;
val = -x/y;
} else {
sector = 7;
val = 1+y/x;
}
}
}
return phaseColors[sector][(int) (val*phaseColorCount)];
}
void calcPhiComponent(double x, double y) {
phiSector = 0;
double val = 0;
if (x == 0 && y == 0) {
phiSector = 0;
phiIndex = 0;
return;
}
if (y >= 0) {
if (x >= 0) {
if (x >= y) {
phiSector = 0;
val = y/x;
} else {
phiSector = 1;
val = 1-x/y;
}
} else {
if (-x <= y) {
phiSector = 2;
val = -x/y;
} else {
phiSector = 3;
val = 1+y/x;
}
}
} else {
if (x <= 0) {
if (y >= x) {
phiSector = 4;
val = y/x;
} else {
phiSector = 5;
val = 1-x/y;
}
} else {
if (-y >= x) {
phiSector = 6;
val = -x/y;
} else {
phiSector = 7;
val = 1+y/x;
}
}
}
phiIndex = (int) (val*dataSize);
}
void setScale() {
if (manualScale || !autoZoomItem.getState())
return;
int i;
double outer = 0;
for (i = 0; i != orbCount; i++) {
Orbital orb = orbitals[i];
double r = orb.getScaleRadius();
if (r > outer)
outer = r;
}
// 148 is fudge factor determined by trial and error
int scaleValue = (int) (outer*148);
int oldScaleValue = scaleBar.getValue();
if (oldScaleValue != scaleValue) {
int diff = scaleValue - oldScaleValue;
if (diff < -5 || diff > 5) {
diff /= 3;
if (diff < -50)
diff = -50;
if (diff > 50)
diff = 50;
}
int nv = oldScaleValue+diff;
if (!animatedZoomItem.getState())
nv = scaleValue;
scaleBar.setValue(nv);
scaleValue = nv;
precomputeAll();
}
}
void precomputeAll() {
int i;
for (i = 0; i != orbCount; i++) {
Orbital orb = orbitals[i];
orb.precompute();
}
}
int sign(double x) {
return x < 0 ? -1 : 1;
}
public void paint(Graphics g) {
cv.repaint();
}
public void updateQuantumOsc3d(Graphics realg) {
Graphics g = null;
if (winSize == null || winSize.width == 0)
return;
boolean mis = memoryImageSourceCheck.getState();
g = dbimage.getGraphics();
g.setColor(cv.getBackground());
g.fillRect(0, 0, winSize.width, winSize.height);
g.setColor(cv.getForeground());
if (fontMetrics == null)
fontMetrics = g.getFontMetrics();
boolean allQuiet = false;
double tadd = 0;
if (!stoppedCheck.getState()) {
int val = speedBar.getValue();
tadd = val*(.1/16);
t += tadd;
} else
allQuiet = true;
double norm = 0;
double normmult = 0, normmult2 = 0;
if (alwaysNormItem.getState())
normalize();
// update phases
int i;
for (i = 0; i != stateCount; i++) {
State st = states[i];
if (st.mag < epsilon) {
st.set(0);
continue;
}
if (tadd != 0) {
allQuiet = false;
st.rotate(-(st.elevel+baseEnergy)*tadd);
}
norm += st.magSquared();
}
normmult2 = 1/norm;
if (norm == 0)
normmult2 = 0;
normmult = java.lang.Math.sqrt(normmult2);
AlternateBasis skipBasis = (changingDerivedStates) ?
((DerivedState) selectedState).basis : null;
for (i = 0; i != basisCount; i++) {
AlternateBasis basis = basisList[i];
if (basis != skipBasis && basis.active)
basis.convertBasisToDerived();
}
setScale();
setBrightness(normmult2);
boolean sliced = sliceChooser.getSelectedIndex() != SLICE_NONE;
zoom = (sliced) ? 8 : 16.55;
double colorMult = java.lang.Math.exp(brightnessBar.getValue()/100.);
//System.out.println(colorMult);
computeView(colorMult, normmult);
int j, k;
for (i = 1; i != viewCount; i++) {
g.setColor(i == selectedPaneHandle ? Color.yellow : Color.gray);
g.drawLine(0, viewList[i].paneY,
winSize.width, viewList[i].paneY);
}
if (viewPotential != null) {
double ymult = 10; // viewPotential.height * 1.9;
g.setColor(Color.darkGray);
int floory = viewPotential.y + viewPotential.height - 1;
for (i = 0; i != 50; i++) {
double e = (i + 1.5);
int y = floory - (int) (ymult * e);
if (y >= 0)
g.drawLine(0, y, winSize.width, y);
}
double xp = getScaler();
g.setColor(Color.white);
int ox = -1, oy = -1;
int x;
for (x = 0; x != winSize.width; x++) {
double xx = (x-winSize.width/2)*xp;
double dy = .5 * xx*xx;
int y = floory - (int) (ymult * dy);
if (y < 0) {
if (ox == -1)
continue;
g.drawLine(ox, oy, ox, 0);
ox = -1;
continue;
}
if (ox == -1 && x > 0) {
g.drawLine(x, 0, x, y);
ox = x;
oy = y;
continue;
}
if (ox != -1)
g.drawLine(ox, oy, x, y);
ox = x;
oy = y;
}
// calculate expectation value of E
if (norm != 0) {
double expecte = 0;
for (i = 0; i != stateCount; i++) {
State st = states[i];
double prob = st.magSquared()*normmult2;
expecte += prob*st.elevel;
}
int y = floory - (int) (ymult * expecte);
g.setColor(Color.red);
g.drawLine(0, y, winSize.width, y);
}
if (selectedState != null && !dragging) {
g.setColor(Color.yellow);
int y = floory - (int) (ymult * selectedState.elevel);
g.drawLine(0, y, winSize.width, y);
}
}
if (viewL != null) {
int maxm = 4;
int pad = 3;
int ct = (maxm*2+1)*pad;
double ldata[] = new double[ct];
if (!higherStatesPresent()) {
calcLxy(lxBasis, ldata, ct, maxm, pad, true, false);
drawFunction(g, viewL, 0, ldata, ct, pad, false);
calcLxy(lyBasis, ldata, ct, maxm, pad, false, false);
drawFunction(g, viewL, 1, ldata, ct, pad, false);
calcLz(ldata, ct, maxm, pad, false);
drawFunction(g, viewL, 2, ldata, ct, pad, false);
}
}
int winw = viewX.width;
int winh = viewX.height;
for (i = 0; i != gridSizeX; i++)
for (j = 0; j != gridSizeY; j++) {
int x = i*winw/gridSizeX;
int y = j*winh/gridSizeY;
int x2 = (i+1)*winw/gridSizeX;
int y2 = (j+1)*winh/gridSizeY;
double cr = func[i][j][0]*colorMult;
double cg = func[i][j][1]*colorMult;
double cb = func[i][j][2]*colorMult;
if (cr == 0 && cg == 0 && cb == 0) {
int l;
if (mis)
for (k = x; k < x2; k++)
for (l = y; l < y2; l++)
pixels[k+l*viewX.width] = 0xFF000000;
continue;
}
double fm = max(cr, max(cg, cb));
if (fm > 255) {
fm /= 255;
cr /= fm;
cg /= fm;
cb /= fm;
}
int colval = 0xFF000000 +
(((int) cr) << 16) |
(((int) cg) << 8) |
(((int) cb));
if (mis) {
int l;
for (k = x; k < x2; k++)
for (l = y; l < y2; l++)
pixels[k+l*viewX.width] = colval;
} else {
g.setColor(new Color(colval));
g.fillRect(x, y+viewX.y, x2-x, y2-y);
}
}
if (mis) {
Image dbimage2 = cv.createImage(imageSource);
g.drawImage(dbimage2, viewX.x, viewX.y, null);
}
g.setColor(Color.white);
if (sliced)
drawCube(g, false);
if (axesItem.getState())
drawAxes(g);
for (i = 0; i != textCount; i++) {
TextBox tb = textBoxes[i];
int h = (tb.height + fontMetrics.getAscent() -
fontMetrics.getDescent())/2;
g.drawString(tb.text, tb.x, tb.y + h);
}
g.setColor(Color.yellow);
if (selectedState != null)
centerString(g, selectedState.getText(),
viewX.y+viewX.height-5);
if (viewStates != null)
drawPhasors(g, viewStates);
realg.drawImage(dbimage, 0, 0, this);
if (!allQuiet)
cv.repaint(pause);
}
double getScaler() {
// XXX don't duplicate this
double scalex = viewX.width*zoom/2;
double scaley = viewX.height*zoom/2;
double aratio = viewX.width/(double) viewX.height;
// preserve aspect ratio regardless of window dimensions
if (aratio < 1)
scaley *= aratio;
else
scalex /= aratio;
double xp = 2*scalex/viewDistance;
double mult = scaleBar.getValue() / 2500.;
xp /= 50*mult;
xp = 1/xp;
return xp;
}
public void centerString(Graphics g, String str, int ypos) {
g.drawString(str, (winSize.width-fontMetrics.stringWidth(str))/2, ypos);
}
// see if the face containing (nx, ny, nz) is visible.
boolean visibleFace(int nx, int ny, int nz) {
double viewx = viewDistance*rotmatrix[2];
double viewy = viewDistance*rotmatrix[5];
double viewz = viewDistance*rotmatrix[8];
return (nx-viewx)*nx+(ny-viewy)*ny+(nz-viewz)*nz < 0;
}
void drawPhasors(Graphics g, View v) {
int i;
for (i = 0; i != phasorCount; i++) {
Phasor ph = phasors[i];
State st = ph.state;
int ss = ph.width;
int ss2 = ss/2;
int x = ph.x + ss2;
int y = ph.y + ss2;
boolean yel = (selectedState != null &&
selectedState.elevel == st.elevel);
if (viewChooser.getSelectedIndex() >= VIEW_COMBO_N1)
yel = (selectedState == st);
g.setColor(yel ? Color.yellow :
st.mag == 0 ? gray2 : Color.white);
g.drawOval(x-ss2, y-ss2, ss, ss);
int xa = (int) (st.re*ss2);
int ya = (int) (-st.im*ss2);
g.drawLine(x, y, x+xa, y+ya);
g.fillOval(x+xa-1, y+ya-1, 3, 3);
}
}
void drawFunction(Graphics g, View view, int pos,
double fr[], int count, int pad, boolean fromZero) {
int i;
double expectx = 0;
double expectx2 = 0;
double maxsq = 0;
double tot = 0;
int vw = winSize.width/3;
int vw2 = vw*4/5;
int mid_x = (fromZero) ? (vw2/(count-1)) : vw2 * (count/2) / (count-1);
int zero = mid_x;
mid_x += vw*pos;
for (i = 0; i != count; i++) {
int x = vw2 * i / (count-1);
int ii = i;
double dr = fr[ii];
double dy = dr*dr;
if (dy > maxsq)
maxsq = dy;
int dev = x-zero;
expectx += dy*dev;
expectx2 += dy*dev*dev;
tot += dy;
}
zero = mid_x;
expectx /= tot;
expectx2 /= tot;
double maxnm = java.lang.Math.sqrt(maxsq);
double uncert = java.lang.Math.sqrt(expectx2-expectx*expectx);
int ox = -1, oy = 0;
double bestscale = 1/maxnm;
view.scale = bestscale;
if (view.scale > 1e8)
view.scale = 1e8;
g.setColor(Color.gray);
g.drawLine(mid_x, view.y, mid_x, view.y+view.height);
double ymult2 = .90*view.height;
int mid_y = view.y+view.height/2+(int) ymult2/2;
double mult = ymult2*view.scale;
g.setColor(Color.white);
ox = -1;
for (i = 0; i != count; i++) {
int x = vw2 * i / (count-1) + vw*pos;
int ii = i;
int y = mid_y - (int) (mult * fr[ii]);
if ((i % pad) == 1) {
g.setColor(Color.gray);
g.drawLine(x, mid_y, x, mid_y+4);
g.setColor(Color.white);
}
if (ox != -1)
g.drawLine(ox, oy, x, y);
ox = x;
oy = y;
}
if (maxsq > 0) {
expectx += zero + .5;
g.setColor(Color.red);
g.drawLine((int) expectx, view.y,
(int) expectx, view.y+view.height);
}
}
// draw the cube containing the particles. if drawAll is false then
// we just draw faces that are facing the camera. This routine draws
// each edge twice which is unnecessary, but easier.
void drawCube(Graphics g, boolean drawAll) {
int i;
int slice = sliceChooser.getSelectedIndex();
int sp = 0;
for (i = 0; i != 6; i++) {
// calculate normal of ith face
int nx = (i == 0) ? -1 : (i == 1) ? 1 : 0;
int ny = (i == 2) ? -1 : (i == 3) ? 1 : 0;
int nz = (i == 4) ? -1 : (i == 5) ? 1 : 0;
// if face is not facing camera, don't draw it
if (!drawAll && !visibleFace(nx, ny, nz))
continue;
double pts[];
pts = new double[3];
int n;
for (n = 0; n != 4; n++) {
computeFace(i, n, pts);
map3d(pts[0], pts[1], pts[2], xpoints, ypoints, n, viewX);
}
g.setColor(Color.gray);
g.drawPolygon(xpoints, ypoints, 4);
if (slice != SLICE_NONE && i/2 != slice-SLICE_X) {
if (selectedSlice)
g.setColor(Color.yellow);
int coord1 = (slice == SLICE_X) ? 1 : 0;
int coord2 = (slice == SLICE_Z) ? 1 : 2;
computeFace(i, 0, pts);
pts[slice-SLICE_X] = sliceval;
map3d(pts[0], pts[1], pts[2],
slicerPoints[0], slicerPoints[1], sp, viewX);
computeFace(i, 2, pts);
pts[slice-SLICE_X] = sliceval;
map3d(pts[0], pts[1], pts[2],
slicerPoints[0], slicerPoints[1], sp+1, viewX);
g.drawLine(slicerPoints[0][sp ], slicerPoints[1][sp],
slicerPoints[0][sp+1], slicerPoints[1][sp+1]);
sliceFaces[sp/2][0] = nx;
sliceFaces[sp/2][1] = ny;
sliceFaces[sp/2][2] = nz;
sp += 2;
}
}
sliceFaceCount = sp;
}
// generate the nth vertex of the bth cube face
void computeFace(int b, int n, double pts[]) {
// One of the 3 coordinates (determined by a) is constant.
// When b=0, x=-1; b=1, x=+1; b=2, y=-1; b=3, y=+1; etc
int a = b >> 1;
pts[a] = ((b & 1) == 0) ? -1 : 1;
// fill in the other 2 coordinates with one of the following
// (depending on n): -1,-1; +1,-1; +1,+1; -1,+1
int i;
for (i = 0; i != 3; i++) {
if (i == a) continue;
pts[i] = (((n>>1)^(n&1)) == 0) ? -1 : 1;
n >>= 1;
}
}
void drawAxes(Graphics g) {
g.setColor(Color.white);
double d = .5;
map3d(0, 0, 0, xpoints, ypoints, 0, viewAxes);
map3d(d, 0, 0, xpoints, ypoints, 1, viewAxes);
drawArrow(g, "x", xpoints[0], ypoints[0], xpoints[1], ypoints[1]);
map3d(0, d, 0, xpoints, ypoints, 1, viewAxes);
drawArrow(g, "y", xpoints[0], ypoints[0], xpoints[1], ypoints[1]);
map3d(0, 0, d, xpoints, ypoints, 1, viewAxes);
drawArrow(g, "z", xpoints[0], ypoints[0], xpoints[1], ypoints[1]);
}
void drawArrow(Graphics g, String text, int x1, int y1, int x2, int y2) {
drawArrow(g, text, x1, y1, x2, y2, 5);
}
void drawArrow(Graphics g, String text,
int x1, int y1, int x2, int y2, int as) {
g.drawLine(x1, y1, x2, y2);
double l = java.lang.Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
if (l > as/2) { // was as
double hatx = (x2-x1)/l;
double haty = (y2-y1)/l;
g.drawLine(x2, y2,
(int) (haty*as-hatx*as+x2),
(int) (-hatx*as-haty*as+y2));
g.drawLine(x2, y2,
(int) (-haty*as-hatx*as+x2),
(int) (hatx*as-haty*as+y2));
if (text != null)
g.drawString(text, (int) (x2+hatx*10), (int) (y2+haty*10));
}
}
// map 3-d point (x,y,z) to screen, storing coordinates
// in xpoints[pt],ypoints[pt]
void map3d(double x, double y, double z,
int xpoints[], int ypoints[], int pt, Rectangle v) {
double rotm[] = rotmatrix;
double realx = x*rotm[0] + y*rotm[3] + z*rotm[6];
double realy = x*rotm[1] + y*rotm[4] + z*rotm[7];
double realz = viewDistance-(x*rotm[2] + y*rotm[5] + z*rotm[8]);
double scalex = v.width*zoom/2;
double scaley = v.height*zoom/2;
double aratio = v.width/(double) v.height;
// preserve aspect ratio regardless of window dimensions
if (aratio < 1)
scaley *= aratio;
else
scalex /= aratio;
xpoints[pt] = v.x + v.width /2 + (int) (scalex*realx/realz);
ypoints[pt] = v.y + v.height/2 - (int) (scaley*realy/realz);
}
// map point on screen to 3-d coordinates assuming it lies on a given plane
void unmap3d(double x3[], int x, int y, double pn[], double pp[]) {
// first, find all points which map to (x,y) on the screen.
// this is a line.
double scalex = viewX.width*zoom/2;
double scaley = viewX.height*zoom/2;
double aratio = viewX.width/(double) viewX.height;
// preserve aspect ratio regardless of window dimensions
if (aratio < 1)
scaley *= aratio;
else
scalex /= aratio;
double vx = (x-(viewX.x+viewX.width/2))/scalex;
double vy = -(y-(viewX.y+viewX.height/2))/scaley;
// vz = -1
// map the line vector to object space
double rotm[] = rotmatrix;
double mx = viewDistance*rotm[2];
double my = viewDistance*rotm[5];
double mz = viewDistance*rotm[8];
double mvx = (vx*rotm[0] + vy*rotm[1] - rotm[2]);
double mvy = (vx*rotm[3] + vy*rotm[4] - rotm[5]);
double mvz = (vx*rotm[6] + vy*rotm[7] - rotm[8]);
// calculate the intersection between the line and the given plane
double t = ((pp[0]-mx)*pn[0] +
(pp[1]-my)*pn[1] +
(pp[2]-mz)*pn[2]) /
(pn[0]*mvx+pn[1]*mvy+pn[2]*mvz);
x3[0] = mx+mvx*t;
x3[1] = my+mvy*t;
x3[2] = mz+mvz*t;
}
public void componentHidden(ComponentEvent e){}
public void componentMoved(ComponentEvent e){}
public void componentShown(ComponentEvent e) {
cv.repaint();
}
public void componentResized(ComponentEvent e) {
handleResize();
cv.repaint(pause);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == exitItem) {
applet.destroyFrame();
return;
}
cv.repaint();
if (e.getSource() == blankButton)
doClear();
if (e.getSource() == normalizeButton)
normalize();
if (e.getSource() == maximizeButton)
maximize();
if (e.getSource() == dispGaussItem)
doDispGaussian();
if (e.getSource() == scaled1GaussItem)
doScaled1Gaussian();
if (e.getSource() == scaled2GaussItem)
doScaled2Gaussian();
if (e.getSource() == rotatingGaussItem)
doRotatingGaussian();
if (e.getSource() == dispX110Item)
doDispX110();
if (e.getSource() == dispZ110Item)
doDispZ110();
if (e.getSource() == measureEItem)
measureE();
if (e.getSource() == measureLxItem)
measureL(0);
if (e.getSource() == measureLyItem)
measureL(1);
if (e.getSource() == measureLzItem)
measureL(2);
}
void doDispGaussian() {
doClear();
int i;
rectBasis.convertBasisToDerived();
for (i = 0; i != 5; i++)
rectBasis.altStates[i].set(movedGaussian[i], 0);
rectBasis.convertDerivedToBasis();
createOrbitals();
}
void doScaled1Gaussian() {
doClear();
int i;
for (i = 0; i != 8; i++)
getState(i, 0, 0).set(scaledGaussian[i]);
createOrbitals();
}
void doScaled2Gaussian() {
doClear();
int i;
for (i = 0; i != rectBasis.altStateCount; i++) {
DerivedState ds = rectBasis.altStates[i];
ds.set(0);
if ((ds.nx & 1) > 0 || ds.ny > 0 || (ds.nz & 1) > 0)
continue;
int s = (ds.nx/2)*3+ds.nz/2;
ds.set(scaled2Gaussian[s]);
}
rectBasis.convertDerivedToBasis();
createOrbitals();
}
void doRotatingGaussian() {
doClear();
int i;
for (i = 0; i != rectBasis.altStateCount; i++) {
DerivedState ds = rectBasis.altStates[i];
ds.set(0);
int s = ds.nx*3+ds.nz;
if (ds.ny > 0 || ds.nx > 2 || ds.nz > 2)
continue;
ds.set(rotGaussianR[s], rotGaussianI[s]);
}
rectBasis.convertDerivedToBasis();
createOrbitals();
}
void doDispX110() {
doClear();
int i;
for (i = 0; i != rectBasis.altStateCount; i++) {
DerivedState ds = rectBasis.altStates[i];
ds.set(0);
if (ds.nz != 1 || ds.ny != 0)
continue;
ds.set(dispX110Array[ds.nx]);
}
rectBasis.convertDerivedToBasis();
createOrbitals();
}
void doDispZ110() {
doClear();
int i;
for (i = 0; i != rectBasis.altStateCount; i++) {
DerivedState ds = rectBasis.altStates[i];
ds.set(0);
//if (ds.nx != 1 || ds.ny != 1)
if (ds.nx != 1 || ds.ny != 0)
continue;
ds.set(dispZ110Array[ds.nz]);
}
rectBasis.convertDerivedToBasis();
createOrbitals();
}
double movedGaussian[] = {
// 0.9394130628134758, 0.33213267352531645, 0.08303316838132911
.778801, .550695, .275348, .11241, .039743
};
double scaledGaussian[] = {
0.252982,0.185903,0.124708,
0.0808198,0.0514334,0.0323663,
0.0202127,0.0125533
};
double scaled2Gaussian[] = {
0.923077,0.251044,0.0836194,
-0.251044,-0.0682749,-0.0227415,
0.0836194,0.0227415,0.00757488
};
double rotGaussianR[] = {
0.75484,0.,-0.150118,0.400314,0.,-0.079612,0.150118,0.,0
};
double rotGaussianI[] = {
0,0.400314,0,0,0.212299,0,0,0.079612,0
};
double dispX110Array[] = {
// -.174036, .953731, .242278, 0, 0
-0.332133,0.821986,0.44035,0.137825, 0
// -0.460759,0.624461,0.559978,0.271215,0.0983688
};
double dispZ110Array[] = {
0.778801,0.550695,0.275348,0.11241,0.039743
};
int scaleValue = -1;
public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.print(((Scrollbar) e.getSource()).getValue() + "\n");
if (e.getSource() == scaleBar) {
if (scaleBar.getValue() == scaleValue)
return;
scaleValue = scaleBar.getValue();
precomputeAll();
manualScale = true;
}
if (e.getSource() == brightnessBar) {
double mult = java.lang.Math.exp(brightnessBar.getValue()/100.);
userBrightMult = mult/bestBrightness;
}
if (e.getSource() == resolutionBar)
setResolution();
setupSimpson();
cv.repaint(pause);
}
public void mouseDragged(MouseEvent e) {
dragging = true;
changingDerivedStates = false;
edit(e);
dragX = e.getX(); dragY = e.getY();
}
boolean csInRange(int x, int xa, int xb) {
if (xa < xb)
return x >= xa-5 && x <= xb+5;
return x >= xb-5 && x <= xa+5;
}
void checkSlice(int x, int y) {
if (sliceChooser.getSelectedIndex() == SLICE_NONE) {
selectedSlice = false;
return;
}
int n;
selectedSlice = false;
for (n = 0; n != sliceFaceCount; n += 2) {
int xa = slicerPoints[0][n];
int xb = slicerPoints[0][n+1];
int ya = slicerPoints[1][n];
int yb = slicerPoints[1][n+1];
if (!csInRange(x, xa, xb) || !csInRange(y, ya, yb))
continue;
double d;
if (xa == xb)
d = java.lang.Math.abs(x-xa);
else {
// write line as y=a+bx
double b = (yb-ya)/(double) (xb-xa);
double a = ya-b*xa;
// solve for distance
double d1 = y-(a+b*x);
if (d1 < 0)
d1 = -d1;
d = d1/java.lang.Math.sqrt(1+b*b);
}
if (d < 6) {
selectedSlice = true;
sliceFace = sliceFaces[n/2];
break;
}
}
}
public void mouseMoved(MouseEvent e) {
if (dragging)
return;
int x = e.getX();
int y = e.getY();
dragX = x; dragY = y;
int oldsph = selectedPaneHandle;
int olds = selection;
State oldss = selectedState;
selectedPaneHandle = -1;
selection = 0;
selectedState = null;
int i;
for (i = 1; i != viewCount; i++) {
int dy = y-viewList[i].paneY;
if (dy >= -3 && dy <= 3) {
selectedPaneHandle = i;
selection = SEL_HANDLE;
}
}
if (viewX != null && viewX.inside(x, y)) {
selection = SEL_X;
checkSlice(e.getX(), e.getY());
} else if (viewPotential.contains(x, y)) {
selection = SEL_POTENTIAL;
//findStateByEnergy(y);
} else if (viewStates != null && viewStates.inside(x, y))
findPhasor(viewStates, x, y);
if (oldsph != selectedPaneHandle || olds != selection ||
oldss != selectedState)
cv.repaint(pause);
}
void findPhasor(View v, int x, int y) {
int i;
for (i = 0; i != phasorCount; i++) {
if (!phasors[i].inside(x, y))
continue;
selectedPhasor = phasors[i];
selectedState = selectedPhasor.state;
selection = SEL_STATES;
break;
}
}
public void mouseClicked(MouseEvent e) {
if (selection == SEL_STATES)
editMagClick();
if (e.getClickCount() == 2 && selectedState != null)
enterSelectedState();
}
void enterSelectedState() {
int i;
for (i = 0; i != stateCount; i++)
if (states[i] != selectedState)
states[i].set(0);
selectedState.convertBasisToDerived();
selectedState.set(1);
selectedState.convertDerivedToBasis();
createOrbitals();
cv.repaint(pause);
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
if (!dragging && selection != 0) {
selectedPaneHandle = -1;
selectedState = null;
selectedPhasor = null;
selection = 0;
cv.repaint(pause);
}
}
public void mousePressed(MouseEvent e) {
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) == 0)
return;
dragX = dragStartX = e.getX();
dragY = dragStartY = e.getY();
dragZoomStart = zoom;
dragging = true;
edit(e);
}
public void mouseReleased(MouseEvent e) {
if (dragging)
cv.repaint();
dragging = changingDerivedStates = false;
}
public void itemStateChanged(ItemEvent e) {
if (e.getItemSelectable() instanceof CheckboxMenuItem) {
setupDisplay();
cv.repaint(pause);
return;
}
if (e.getItemSelectable() == nChooser) {
orbitalChanged();
} else if (e.getItemSelectable() == lChooser) {
setLValue();
orbitalChanged();
} else if (e.getItemSelectable() == mChooser) {
orbitalChanged();
} else if (e.getItemSelectable() == viewChooser) {
setLValue();
orbitalChanged();
setupDisplay();
setInitialOrbital();
}
cv.repaint(pause);
}
public boolean handleEvent(Event ev) {
if (ev.id == Event.WINDOW_DESTROY) {
destroyFrame();
return true;
}
return super.handleEvent(ev);
}
void destroyFrame() {
if (applet == null)
dispose();
else
applet.destroyFrame();
}
void edit(MouseEvent e) {
if (selection == SEL_NONE)
return;
int x = e.getX();
int y = e.getY();
switch (selection) {
case SEL_HANDLE: editHandle(y); break;
case SEL_STATES: editMag(x, y); break;
case SEL_POTENTIAL: break;
case SEL_X: editX(x, y); break;
}
}
void editHandle(int y) {
int dy = y-viewList[selectedPaneHandle].paneY;
View upper = viewList[selectedPaneHandle-1];
View lower = viewList[selectedPaneHandle];
int minheight = 10;
if (upper.height+dy < minheight || lower.height-dy < minheight)
return;
upper.height += dy;
lower.height -= dy;
lower.y += dy;
lower.paneY += dy;
cv.repaint(pause);
setSubViews();
}
void editX(int x, int y) {
int mode = modeChooser.getSelectedIndex();
if (selectedSlice)
mode = MODE_SLICE;
if (mode == MODE_ANGLE) {
int xo = dragX-x;
int yo = dragY-y;
rotate(xo/40., -yo/40.);
cv.repaint(pause);
} else if (mode == MODE_ROTATE_X) {
int xo = dragX-x + dragY-y;
rotateXY(xo/40., true);
} else if (mode == MODE_ROTATE_Y) {
int xo = dragX-x + dragY-y;
rotateXY(xo/40., false);
} else if (mode == MODE_ROTATE_Z) {
int xo = dragX-x + dragY-y;
rotateZ(xo/40.);
} else if (mode == MODE_SLICE) {
double x3[] = new double[3];
unmap3d(x3, x, y, sliceFace, sliceFace);
switch (sliceChooser.getSelectedIndex()) {
case SLICE_X: sliceval = x3[0]; break;
case SLICE_Y: sliceval = x3[1]; break;
case SLICE_Z: sliceval = x3[2]; break;
}
if (sliceval < -.99)
sliceval = -.99;
if (sliceval > .99)
sliceval = .99;
cv.repaint(pause);
}
}
void editMag(int x, int y) {
if (selectedPhasor == null)
return;
int stateSize = selectedPhasor.width;
int ss2 = stateSize/2;
int x0 = selectedPhasor.x + ss2;
int y0 = selectedPhasor.y + ss2;
x -= x0;
y -= y0;
double mag = java.lang.Math.sqrt(x*x+y*y)/ss2;
double ang = java.lang.Math.atan2(-y, x);
if (mag > 10)
mag = 0;
if (mag > 1)
mag = 1;
selectedState.setMagPhase(mag, ang);
if (selectedState instanceof DerivedState) {
selectedState.convertDerivedToBasis();
changingDerivedStates = true;
}
cv.repaint(pause);
createOrbitals();
}
void editMagClick() {
if (selectedState == null)
return;
if (magDragStart < .5)
selectedState.set(1, 0);
else
selectedState.set(0);
cv.repaint(pause);
createOrbitals();
}
void calcLxy(AlternateBasis ab,
double data[], int count, int maxm, int pad, boolean xAxis,
boolean square) {
int i;
int mid = count/2;
for (i = 0; i != count; i++)
data[i] = 0;
if (square)
mid = 1;
// convert to the basis
ab.convertBasisToDerived();
int j;
double qq = 0;
for (j = 0; j != ab.altStateCount; j++) {
DerivedState ds = ab.altStates[j];
if (square)
data[mid+ds.m*ds.m*pad] += ds.magSquared();
else
data[mid+ds.m*pad] += ds.magSquared();
}
for (i = 0; i != count; i++)
data[i] = java.lang.Math.sqrt(data[i]);
}
void calcLz(double data[], int count, int maxm, int pad, boolean square) {
int i;
int mid = count/2;
for (i = 0; i != count; i++)
data[i] = 0;
if (square)
mid = 1;
for (i = 0; i != stateCount; i++) {
BasisState bs = states[i];
if (bs.l <= maxm) {
if (square)
data[mid+bs.m*bs.m*pad] += bs.magSquared();
else
data[mid+bs.m*pad] += bs.magSquared();
}
}
for (i = 0; i != count; i++)
data[i] = java.lang.Math.sqrt(data[i]);
}
void rotateXY(double ang, boolean xAxis) {
AlternateBasis ab = (xAxis) ? lxBasis : lyBasis;
// convert to the basis
ab.convertBasisToDerived();
// rotate all the states in the basis around the axis
int j;
for (j = 0; j != ab.altStateCount; j++) {
DerivedState ds = ab.altStates[j];
ds.rotate(ang*ds.m);
}
ab.convertDerivedToBasis();
createOrbitals();
cv.repaint(pause);
}
void rotateZ(double ang) {
int i;
for (i = 0; i != stateCount; i++) {
BasisState bs = states[i];
bs.rotate(ang*bs.m);
}
cv.repaint(pause);
}
void createOrbitals() {
int i;
int newOrbCount = 0;
boolean newOrbitals = false;
for (i = 0; i != stateCount; i++) {
BasisState st = states[i];
if (st.m == 0) {
if (st.mag != 0) {
newOrbCount++;
if (st.orb == null)
newOrbitals = true;
} else if (st.orb != null)
newOrbitals = true;
} else if (st.m > 0) {
if (st.mag != 0 || getState(st.nr, st.l, -st.m).mag != 0) {
newOrbCount++;
if (st.orb == null)
newOrbitals = true;
} else if (st.orb != null)
newOrbitals = true;
}
}
if (!newOrbitals)
return;
orbCount = newOrbCount;
orbitals = new Orbital[orbCount];
int oi = 0;
for (i = 0; i != stateCount; i++) {
BasisState st = states[i];
if ((st.m == 0 && st.mag != 0) ||
(st.m > 0 && (st.mag != 0 ||
getState(st.nr, st.l, -st.m).mag != 0))) {
if (st.orb == null) {
Orbital orb;
if (st.l == 0)
orb = new SOrbital(st);
else if (st.m == 0)
orb = new MZeroOrbital(st);
else
orb = new PairedOrbital(st);
orb.precompute();
st.orb = orb;
}
orbitals[oi++] = st.orb;
} else
st.orb = null;
}
}
void doClear() {
int x;
for (x = 0; x != stateCount; x++)
states[x].set(0);
}
void normalize() {
double norm = 0;
int i;
for (i = 0; i != stateCount; i++)
norm += states[i].magSquared();
if (norm == 0)
return;
double normmult = 1/java.lang.Math.sqrt(norm);
for (i = 0; i != stateCount; i++)
states[i].mult(normmult);
cv.repaint(pause);
}
void maximize() {
int i;
double maxm = 0;
for (i = 0; i != stateCount; i++)
if (states[i].mag > maxm)
maxm = states[i].mag;
if (maxm == 0)
return;
for (i = 0; i != stateCount; i++)
states[i].mult(1/maxm);
cv.repaint(pause);
}
void measureE() {
normalize();
double n = random.nextDouble();
int i = 0;
int picki = -1;
for (i = 0; i != stateCount; i++) {
double m = states[i].magSquared();
n -= m;
if (n < 0) {
picki = i;
i = stateCount;
break;
}
}
if (picki == -1)
return;
for (i = 0; i != stateCount; i++) {
State st = states[i];
if (st.elevel != states[picki].elevel)
st.set(0);
}
normalize();
}
void measureL(int axis) {
if (higherStatesPresent())
return;
int maxm = 4;
int pad = 3;
int ct = (maxm*2+1)*pad;
double ldata[] = new double[ct];
int mid = ct/2;
normalize();
AlternateBasis ab = null;
switch (axis) {
case 0:
calcLxy(ab = lxBasis, ldata, ct, maxm, pad, true, false);
break;
case 1:
calcLxy(ab = lyBasis, ldata, ct, maxm, pad, false, false);
break;
case 2:
calcLz(ldata, ct, maxm, pad, false);
break;
}
double n = random.nextDouble();
int i = 0;
int pickm = -100;
for (i = -maxm; i <= maxm; i++) {
double m = ldata[mid+i*pad];
m *= m;
n -= m;
if (n < 0) {
pickm = i;
i = maxm;
break;
}
}
if (pickm == -100)
return;
switch (axis) {
case 2:
for (i = 0; i != stateCount; i++) {
BasisState bs = states[i];
if (bs.m != pickm)
bs.set(0);
}
break;
default:
for (i = 0; i != ab.altStateCount; i++) {
DerivedState ds = ab.altStates[i];
if (ds.m != pickm)
ds.set(0);
}
ab.convertDerivedToBasis();
}
maximize();
createOrbitals();
}
// this is when we are in single-orbital mode, and the user selects
// a different one
void orbitalChanged() {
if (viewChooser.getSelectedIndex() > VIEW_COMPLEX)
return;
doClear();
getState(getNR(), getL(), getM()).set(1, 0);
createOrbitals();
manualScale = false;
}
BasisState getState(int nr, int l, int m) {
int pre_n_add = nr*(maxl+1)*(maxl+1);
int pre_l_add = l*l;
/*System.out.println(nr + " " + l + " " + m + " " +
(pre_n_add+pre_l_add+l+m));*/
return states[pre_n_add+pre_l_add+l+m];
}
void setBrightness(double normmult) {
int i;
double avg = 0;
double totn = 0;
double minavg = 1e30;
for (i = 0; i != orbCount; i++) {
Orbital orb = orbitals[i];
double as = orb.getBrightness();
if (as < minavg)
minavg = as;
BasisState st = orb.state;
double n = st.magSquared()*normmult;
if (orb.state.m != 0)
n += getState(st.nr, st.l, -st.m).magSquared()*normmult;
totn += n;
avg += n*as;
}
bestBrightness = 113.9/(java.lang.Math.sqrt(minavg)*totn);
double mult = bestBrightness * userBrightMult;
int bvalue = (int) (java.lang.Math.log(mult)*100.);
brightnessBar.setValue(bvalue);
}
abstract class Orbital {
BasisState state;
int n, nr, l, m;
double reMult, imMult;
Orbital(BasisState bs) {
nr = bs.nr; l = bs.l; m = bs.m;
n = nr*2+l;
state = bs;
}
void setupFrame(double mult) {
reMult = state.re*mult;
imMult = state.im*mult;
}
double dataR[], dataTh[], dataPhiR[][], dataPhiI[][];
int dshalf;
double brightnessCache;
double getBoundRadius(double bright) {
int i;
int outer = 1;
/*
double maxThData = 0;
if (l == 0)
maxThData = 1;
else {
for (i = 0; i != dataSize; i++) {
if (dataTh[i] > maxThData)
maxThData = dataTh[i];
if (dataTh[i] < -maxThData)
maxThData = -dataTh[i];
}
}*/
// we need to divide the spherical harmonic norm out of
// dataR[] to get just the radial function. (The spherical
// norm gets multiplied into dataR[] for efficiency.)
int mpos = (m < 0) ? -m : m;
double norm1 = 1/sphericalNorm(l, mpos);
//norm1 *= maxThData;
norm1 *= norm1;
norm1 *= bright;
for (i = 0; i != dataSize; i++) { // XXX
double v = dataR[i]*dataR[i]*norm1;
if (v > 32)
outer = i;
}
//System.out.println(maxThData + " " + outer);
return outer / (dataSize/2.);
}
double getScaleRadius() {
// set scale by solving equation Veff(r) = E, assuming m=0
// r^2/2 = (n+3/2)
return java.lang.Math.sqrt(2*(n+1.5));
}
final int distmult = 4;
void precompute() {
int x, y, z;
dshalf = dataSize/2;
double mult = scaleBar.getValue() / 2500.;
int mpos = (m < 0) ? -m : m;
double lgcorrect = java.lang.Math.pow(-1, m);
double norm = radialNorm(nr, l)*sphericalNorm(l, mpos);
dataR = new double[dataSize];
for (x = 0; x != dataSize; x++) {
double r = x*resadj*mult + .00000001;
double rl = java.lang.Math.pow(r, l)*norm;
dataR[x] = java.lang.Math.exp(-r*r/2)*rl*
hypser(-nr,l+1.5,r*r);
}
if (l > 0) {
dataTh = new double[dataSize+1];
for (x = 0; x != dataSize+1; x++) {
double th = (x-dshalf)/(double) dshalf;
// we multiply in lgcorrect because plgndr() uses a
// different sign convention than Bransden
dataTh[x] = lgcorrect*plgndr(l, mpos, th);
}
}
if (m != 0) {
dataPhiR = new double[8][dataSize+1];
dataPhiI = new double[8][dataSize+1];
for (x = 0; x != 8; x++)
for (y = 0; y <= dataSize; y++) {
double phi = x*pi/4 + y*(pi/4)/dataSize;
dataPhiR[x][y] = java.lang.Math.cos(phi*mpos);
dataPhiI[x][y] = java.lang.Math.sin(phi*mpos);
}
}
brightnessCache = 0;
}
double getBrightness() {
if (brightnessCache != 0)
return brightnessCache;
int x;
double avgsq = 0;
double vol = 0;
// we need to divide the spherical harmonic norm out of
// dataR[] to get just the radial function. (The spherical
// norm gets multiplied into dataR[] for efficiency.)
int mpos = (m < 0) ? -m : m;
double norm1 = 1/sphericalNorm(l, mpos);
for (x = 0; x != dataSize; x++) {
double val = dataR[x]*norm1;
val *= val;
avgsq += val*val*x*x;
vol += x*x;
}
brightnessCache = avgsq / vol;
return brightnessCache;
}
double radialNorm(int nr, int l) {
return
java.lang.Math.sqrt(2*factorial(nr)/fracfactorial(l+nr+.5)) *
pochhammer(l+1.5, nr)/factorial(nr);
}
double sphericalNorm(int l, int m) {
return java.lang.Math.sqrt((2*l+1)*factorial(l-m)/
(4*pi*factorial(l+m)));
}
double factorial(int f) {
double res = 1;
while (f > 1)
res *= f--;
return res;
}
double fracfactorial(double f) {
double res = java.lang.Math.sqrt(pi);
while (f > 0)
res *= f--;
return res;
}
double pochhammer(double f, int n) {
double res = 1;
for (; n > 0; n--) {
res *= f;
f += 1;
}
return res;
}
abstract void computePoint(int r, int costh);
};
class SOrbital extends Orbital {
SOrbital(BasisState bs) {
super(bs);
}
void computePoint(int r, int costh) {
try {
double v = dataR[r];
funcr = reMult*v;
funci = imMult*v;
} catch (Exception e) {
funcr = funci = 0;
System.out.println("bad " + r + " " + costh);
}
}
};
class MZeroOrbital extends Orbital {
MZeroOrbital(BasisState bs) {
super(bs);
}
void computePoint(int r, int costh) {
try {
double v = dataR[r]*dataTh[costh];
funcr = v*reMult;
funci = v*imMult;
} catch (Exception e) {
funcr = funci = 0;
System.out.println("bad " + r + " " + costh);
}
}
};
class PairedOrbital extends Orbital {
BasisState negstate;
PairedOrbital(BasisState bs) {
super(bs);
negstate = getState(bs.nr, bs.l, -bs.m);
}
double f1, f2, f3, f4;
void setupFrame(double mult) {
double a = state.re*mult;
double b = state.im*mult;
double c = negstate.re*mult;
double d = negstate.im*mult;
double mphase = java.lang.Math.pow(-1, m);
a *= mphase;
b *= mphase;
f1 = (a+c);
f2 = (d-b);
f3 = (b+d);
f4 = (a-c);
}
void computePoint(int r, int costh) {
try {
double q = dataR[r]*dataTh[costh];
double phiValR = dataPhiR[phiSector][phiIndex];
double phiValI = dataPhiI[phiSector][phiIndex];
funcr = q*(f1*phiValR + f2*phiValI);
funci = q*(f3*phiValR + f4*phiValI);
} catch (Exception e) {
funcr = funci = 0;
System.out.println("bad " + r + " " + costh);
}
}
};
class Phasor extends Rectangle {
Phasor(int x, int y, int a, int b) {
super(x, y, a, b);
}
State state;
}
abstract class State extends Complex {
double elevel;
void convertDerivedToBasis() {}
void convertBasisToDerived() {}
void setBasisActive() {}
abstract String getText();
}
class BasisState extends State {
int nr, l, m, n;
Orbital orb;
String getText() {
return "n = " + n + ", nr = " + nr + ", l = " + l + ", m = " + m;
}
}
class DerivedState extends State {
int count, m, l, nr, n, nx, ny, nz;
AlternateBasis basis;
String text;
BasisState bstates[];
Complex coefs[];
void convertDerivedToBasis() { basis.convertDerivedToBasis(); }
void convertBasisToDerived() { basis.convertBasisToDerived(); }
void setBasisActive() { basis.active = true; }
String getText() { return text; }
}
class AlternateBasis {
DerivedState altStates[];
int altStateCount;
boolean active;
int n, l;
boolean xAxis;
AlternateBasis() {
basisList[basisCount++] = this;
}
void convertDerivedToBasis() { convertDerivedToBasis(true); }
void convertDerivedToBasis(boolean clear) {
int i, j;
if (clear)
for (i = 0; i != stateCount; i++)
states[i].set(0);
Complex c = new Complex();
for (i = 0; i != altStateCount; i++) {
DerivedState ds = altStates[i];
for (j = 0; j != ds.count; j++) {
c.set(ds.coefs[j]);
c.conjugate();
c.mult(ds);
ds.bstates[j].add(c);
}
}
double maxm = 0;
for (i = 0; i != stateCount; i++)
if (states[i].mag > maxm)
maxm = states[i].mag;
if (maxm > 1) {
double mult = 1/maxm;
for (i = 0; i != stateCount; i++)
states[i].mult(mult);
}
}
void convertBasisToDerived() {
int i, j;
Complex c1 = new Complex();
Complex c2 = new Complex();
double maxm = 0;
for (i = 0; i != altStateCount; i++) {
DerivedState ds = altStates[i];
c1.set(0);
try {
for (j = 0; j != ds.count; j++) {
c2.set(ds.coefs[j]);
c2.mult(ds.bstates[j]);
c1.add(c2);
}
} catch (Exception e) {
System.out.print("Exception at " + i + "\n");
}
if (c1.mag < epsilon)
c1.set(0);
ds.set(c1);
if (c1.mag > maxm)
maxm = ds.mag;
}
if (maxm > 1) {
double mult = 1/maxm;
for (i = 0; i != altStateCount; i++)
altStates[i].mult(mult);
}
}
}
class Complex {
public double re, im, mag, phase;
Complex() { re = im = mag = phase = 0; }
Complex(double r, double i) {
set(r, i);
}
double magSquared() { return mag*mag; }
void set(double aa, double bb) {
re = aa; im = bb;
setMagPhase();
}
void set(double aa) {
re = aa; im = 0;
setMagPhase();
}
void set(Complex c) {
re = c.re;
im = c.im;
mag = c.mag;
phase = c.phase;
}
void add(double r) {
re += r;
setMagPhase();
}
void add(double r, double i) {
re += r; im += i;
setMagPhase();
}
void add(Complex c) {
re += c.re;
im += c.im;
setMagPhase();
}
void square() {
set(re*re-im*im, 2*re*im);
}
void mult(double c, double d) {
set(re*c-im*d, re*d+im*c);
}
void mult(double c) {
re *= c; im *= c;
mag *= c;
}
void mult(Complex c) {
mult(c.re, c.im);
}
void setMagPhase() {
mag = java.lang.Math.sqrt(re*re+im*im);
phase = java.lang.Math.atan2(im, re);
}
void setMagPhase(double m, double ph) {
mag = m;
phase = ph;
re = m*java.lang.Math.cos(ph);
im = m*java.lang.Math.sin(ph);
}
void rotate(double a) {
setMagPhase(mag, (phase+a) % (2*pi));
}
void conjugate() {
im = -im;
phase = -phase;
}
};
class PhaseColor {
public double r, g, b;
PhaseColor(double rr, double gg, double bb) {
r = rr; g = gg; b = bb;
}
}
double plgndr(int l,int m,double x) {
double fact,pll = 0,pmm,pmmp1,somx2;
int i,ll;
if (m < 0 || m > l || java.lang.Math.abs(x) > 1.0) {
System.out.print("bad arguments in plgndr\n");
}
pmm=1.0;
if (m > 0) {
somx2=java.lang.Math.sqrt((1.0-x)*(1.0+x));
fact=1.0;
for (i=1;i<=m;i++) {
pmm *= -fact*somx2;
fact += 2.0;
}
}
if (l == m)
return pmm;
else {
pmmp1=x*(2*m+1)*pmm;
if (l == (m+1))
return pmmp1;
else {
for (ll=(m+2);ll<=l;ll++) {
pll=(x*(2*ll-1)*pmmp1-(ll+m-1)*pmm)/(ll-m);
pmm=pmmp1;
pmmp1=pll;
}
return pll;
}
}
}
double hypser(double a, double c, double z) {
int n;
double fac = 1;
double result = 1;
for (n=1;n<=1000;n++) {
fac *= a*z/((double) n*c);
//System.out.print("fac " + n + " " + fac + " " + z + "\n");
if (fac == 0)
return result;
result += fac;
a++;
c++;
}
System.out.print("convergence failure in hypser\n");
return 0;
}
class View extends Rectangle {
View() { }
View(View v) { super(v); }
double scale;
int paneY;
int pixels[];
}
class TextBox extends Rectangle {
TextBox(int x, int y, int a, int b, String s) {
super(x, y, a, b);
text = s;
}
String text;
}
}
A far higher place must be assigned to Judaism among the competitors for the allegiance of Europe. The cosmopolitan importance at one time assumed by this religion has been considerably obscured, owing to the subsequent devolution of its part to Christianity. It is, however, by no means impossible that, but for the diversion created by the Gospel, and the disastrous consequences of their revolt against Rome, the Jews might have won the world to a purified form of their own monotheism. A few significant circumstances are recorded showing how much influence they had acquired, even in Rome, before the first preaching of Christianity. The first of these is to be found in Cicero¡¯s defence of Flaccus. The latter was accused of appropriating part of the annual contributions sent to the temple at Jerusalem; and, in dealing with this charge, Cicero speaks of the Jews, who were naturally prejudiced against his client, as a powerful faction the hostility of which he is anxious not to provoke.330 Some twenty years later, a great advance has been made. Not only must the material interests of the Jews be respected, but a certain conformity to their religious prescriptions is considered a mark of good breeding, In one of his most amusing satires, Horace tells us how, being anxious to shake off a bore, he appeals for help to his friend Aristius Fuscus, and reminds him of217 some private business which they had to discuss together. Fuscus sees his object, and being mischievously determined to defeat it, answers: ¡®Yes, I remember perfectly, but we must wait for some better opportunity; this is the thirtieth Sabbath, do you wish to insult the circumcised Jews?¡¯ ¡®I have no scruples on that point,¡® replies the impatient poet. ¡®But I have,¡¯ rejoins Fuscus,¡ª¡®a little weak-minded, one of the many, you know¡ªexcuse me, another time.¡®331 Nor were the Jews content with the countenance thus freely accorded them. The same poet elsewhere intimates that whenever they found themselves in a majority, they took advantage of their superior strength to make proselytes by force.¡¯332 And they pursued the good work to such purpose that a couple of generations later we find Seneca bitterly complaining that the vanquished had given laws to the victors, and that the customs of this abominable race were established over the whole earth.333 Evidence to the same effect is given by Philo Judaeus and Josephus, who inform us that the Jewish laws and customs were admired, imitated, and obeyed over the whole earth.334 Such assertions might be suspected of exaggeration, were they not, to a certain extent, confirmed by the references already quoted, to which others of the same kind may be added from later writers showing that it was a common practice among the Romans to abstain from work on the Sabbath, and even to celebrate it by praying, fasting, and lighting lamps, to visit the synagogues, to study the law of Moses, and to pay the yearly contribution of two drachmas to the temple at Jerusalem.335 Jeff¡¯s hand was quietly coming down. ¡°What happened to you?¡± begged Sandy. ¡°Something new has come up, sir. I was waiting there by my ship a good while back, and I heard another one cruising and spiraling, shooting the field, I guess, because he came in and set down. My crate, just the way you ordered, was down by the grove, not in plain sight in the middle of the course. But Jeff set his ship down, left the engine running, and went off. I stayed hid to see what would happen, but when he didn¡¯t come back, I thought I¡¯d better go and find you¡ªand see if it meant anything to you.¡± She stood alone, with the sticky, wet knife in her hand, catching her breath, coming out of the madness. Then she stooped, and pushing the branches aside felt about for her pistol. It lay at the root of a tree, and[Pg 80] when she had picked it up and put it back in the holster, there occurred to her for the first time the thought that the shot in the dead stillness must have roused the camp. And now she was sincerely frightened. If she were found here, it would be more than disagreeable for Landor. They must not find her. She started at a swift, long-limbed run, making a wide detour, to avoid the sentries, bending low, and flying silently among the bushes and across the shadowy sands. The year 1756 opened with menaces to England of the most serious nature. The imbecility of the Ministry was beginning to tell in the neglect of its colonies and its defences. France threatened to invade us, and a navy of fifty thousand men was suddenly voted, and an army of thirty-four thousand two hundred and sixty-three of native troops; but as these were not ready, it was agreed to bring over eight thousand Hessians and Hanoverians. To pay for all this it was necessary to grant excessive supplies, and lay on new duties and taxes. In presenting the money bills in the month of May, Speaker Onslow could not avoid remarking that there were two circumstances which tended to create alarm¡ªforeign subsidies and foreign troops introduced, and nothing but their confidence in his Majesty could allay their fears, or give them confidence that their burdens would be soon reduced. There was, in fact, no chance for any such reduction, for wars, troubles, and disgraces were gathering around from various quarters. The first reverse came from the Mediterranean. MUCH to their amazement, the boys waked up the next morning in Nashville, and found that they had passed through the "dark and bloody ground" of Kentucky absolutely without adventure. After drawing and dividing the rations and cartridges. Si gave the boys the necessary instruction about having their things ready so that they could get them in the dark the next morning, and ordered them to disregard the bonfires and mirth-making, and lie down to get all the sleep they could, in preparation for the hard work of the next day. Then, like the rest of the experienced men, who saw that the campaign was at length really on, and this would be the last opportunity for an indefinite while to write, he sat down to write short letters to his mother and to Annabel. "Bully for the Wild Wanderers of the Wabash," Shorty joined in. "They're the boss regiment in the army o' the Cumberland, and the Army o' the Cumberland's the boss army on earth. Hooray for US Co. Le's have a speech. Where's Monty Scruggs?" "Bring a light, do¡ªI can't abide this dark." Albert suddenly began to look uneasy. After all he was not really drunk, only a little fuddled. He walked straight, and his roll was natural to him, while though he was exceedingly cheerful, and often burst into song, his words were not jumbled, and he generally seemed to have a fair idea of what he was saying. "But I heard what the doctor said to you." "A purty accident¡ªwud them stacks no more dry than a ditch. 'Twas a clear case of 'bustion¡ªfireman said so to me; as wicked and tedious a bit o' wark as ever I met in my life." Calverley stept from the shadow of the cliff, and beheld a meteor in the sky, brightening and expanding, as the clouds opened, until it assumed the appearance of a brilliant star, of astonishing magnitude, encircled by dazzling rays, which, in a singular manner, were all inclined in one direction, and pointing to that part of the horizon where lay the rival of England¡ªFrance. The foreman's face assumed a deeper hue than usual: he looked fiercely at the galleyman, but there was a determination in the weather-beaten face that made him pause ere he spoke. "Galleyman," he at length said, "you knew the business before you came: if you be so fond of saving old witches' lives, why didn't you say so, that I might not now be in this dilemma?" "No, no, not the boy," replied Merritt, rather impatiently. HoMEÁíÀàС˵ߣɫ
ENTER NUMBET 0017
ytfn.com.cn
timu3.net.cn
www.jxzzc.com.cn
www.baan7.com.cn
daoju0.net.cn
lewei7.net.cn
www.musuo7.com.cn
quexu0.com.cn
638576.org.cn
www.arttoto.com.cn