📄 codaflag.java
字号:
package org.trinet.jiggle;
import org.trinet.jasi.*;
import org.trinet.jasi.coda.*;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Color;
import java.awt.Polygon;
import java.util.*;
/**
* Triangular graphical marker to show where an amplitude reading is.<p>
*
* Empty triangle means unassociate. Filled means associated.
*
* Colors are the same as for picks and are coded to the associated solution. <br>
*/
public class CodaFlag {
// Default size of symbol in pixels
final static int minWidth = 8;
final static int minHeight= 8;
int width = minWidth;
int height = minHeight;
/** Position of the flag in pixel space. Centered on the amplitude time and
slammed against the bottom of the WFPanel or viewport. */
Point pos1 = new Point();
Point pos2 = new Point();
// start/end of the coda window
TimeAmp timeAmp1, timeAmp2;
double winStart, winEnd;
/** Coda represented by this flag. */
Coda coda;
/** WFPanel where flag will be drawn. */
WFPanel wfp;
/** The waveform bias. */
double bias = 0.0;
/** Current color of the flag. */
Color color = Color.pink;
final static int Bar = 0;
final static int Free = 1;
final static int Fix = 2;
int flagType = Free;
boolean showExtrapolation = true;
/**
* Create an amplitude flag representing this Amplitude
* to be displayed in this WFPanel. Specify the flag type. Options are:
* CodaFlag.Bar, CodaFlag.Free, or CodaFlag.Fix. Default is Free.
*/
public CodaFlag (WFPanel wfp, Coda coda, int type) {
this(wfp, coda);
setType(type);
}
/**
* Create an amplitude flag representing this Amplitude
* to be displayed in this WFPanel.
*/
public CodaFlag (WFPanel wfp, Coda coda) {
this.wfp = wfp;
this.coda = coda;
// lookup origin's color code
color = wfp.wfv.mv.solList.getColorOf(coda.getAssociatedSolution());
/* Get the first and last time windows to define the total wf scanned
* CodaTN only saves the first and last so there will only be 2 in the dbase
*/
ArrayList list = (ArrayList) coda.getWindowTimeAmpPairs();
if (list.size() > 0) {
timeAmp1 = (TimeAmp) list.get(0) ;
winStart = coda.getTime() + timeAmp1.getTime();
// last window
timeAmp2 = (TimeAmp) list.get(list.size() - 1) ;
winEnd = coda.getTime() + timeAmp2.getTime() + coda.windowSize.doubleValue();
/*
System.out.println ("CodaFlag<: "+ coda.getTime() + " "+
timeAmp1.getTime() + " "+coda.windowSize.doubleValue());
System.out.println ("CodaFlag>: "+ coda.getTime() + " "+
timeAmp2.getTime() + " "+coda.windowSize.doubleValue());
*/
if (wfp.getWf() != null) bias = wfp.getWf().getBias();
}
}
/** Set the type of flag symbol to draw. Options are:
* CodaFlag.Bar, CodaFlag.Free, or CodaFlag.Fix. Default is Free. */
public void setType(int type) {
// check its a valid value
if (type > 0 && type <= Fix) flagType = type;
}
/** Get the type of flag symbol to draw. Options are:
* CodaFlag.Bar, CodaFlag.Free, or CodaFlag.Fix. Default is Free. */
public int getType() {
return flagType;
}
/** If set true, will show coda curve extrapolation before the first fit window. */
public void setShowExtrapolation(boolean tf) {
showExtrapolation = tf;
}
/** Returns true if flag will show coda curve extrapolation before the first fit window. */
public boolean setShowExtrapolation() {
return showExtrapolation;
}
/*
* Draw the CodaFlag in the Graphics window. Check the Viewport limits to insure
* that the flag is always in view in a zoomable WFPanel. If isDeleted()
* == true the flag will NOT be drawn. */
// TODO: handle case where flags overlap
public void draw (Graphics g) {
// don't draw a delete phase (later may want to add ability to show these)
if (coda.isDeleted()) return;
// System.out.println ("draw flag: "+ flagType);
if (flagType == Bar) {
drawBar(g);
} else if (flagType == Fix) {
drawFixCurve(g);
} else if (flagType == Free) {
drawFreeCurve(g);
}
}
/** Draw coda time window as a bar at the bottom of the WFPanel. */
void drawBar (Graphics g) {
// MUST RECALC. THIS EVERY TIME BECAUSE FRAME MIGHT HAVE RESCALED!
pos1.x = wfp.pixelOfTime(winStart);
pos2.x = wfp.pixelOfTime(winEnd);
// If the wfPanel is in a ViewPort, keep flag within viewport so we can see it
if (wfp.vport != null) {
pos1.y = wfp.vport.getViewPosition().y;
} else {
pos1.y = wfp.getHeight(); // bottom of panel
}
pos2.y = pos1.y;
g.setColor(color);
// System.out.println ("CodaFlag<<: "+ pos1.x + " "+pos1.y);
// System.out.println ("CodaFlag>>: "+ pos2.x + " "+pos2.y);
// this makes a point-down triangle at the bottom of the WFPanel
int wid = width/2;
Polygon triangle = new Polygon();
triangle.addPoint(pos1.x, pos1.y);
triangle.addPoint(pos1.x - wid, pos1.y - height);
triangle.addPoint(pos1.x + wid, pos1.y - height);
// this makes a point-up triangle at the bottom of the WFPanel
/* int wid = width/2;
Polygon triangle = new Polygon();
triangle.addPoint(pos.x, pos.y - height);
triangle.addPoint(pos.x - wid, pos.y);
triangle.addPoint(pos.x + wid, pos.y);
*/
// fill if it is "used"
if (coda.windowCount.longValue() > 1) {
g.fillPolygon(triangle);
} else {
g.drawPolygon(triangle);
}
g.drawLine(pos1.x, pos1.y - height, pos2.x, pos2.y - height);
}
/**
* Draw coda as a decay curve at the bottom of the WFPanel.
* NOTE: this won't work if there is no waveform. The waveform is needed to
* properly scale the amplitude dimension of the WFPanel.
*/
void drawFixCurve (Graphics g) {
drawCurve (g, coda.aFix.doubleValue(), coda.qFix.doubleValue());
}
/**
* Draw coda as a decay curve at the bottom of the WFPanel.
* NOTE: this won't work if there is no waveform. The waveform is needed to
* properly scale the amplitude dimension of the WFPanel.
*/
void drawFreeCurve (Graphics g) {
drawCurve (g, coda.aFree.doubleValue(), coda.qFree.doubleValue());
}
/**
* Draw coda as a decay curve at the bottom of the WFPanel.
* NOTE: this won't work if there is no waveform. The waveform is needed to
* properly scale the amplitude dimension of the WFPanel.
*/
void drawCurve (Graphics g, double Aval, double Qval) {
// if (coda.aFree.doubleValue() == 0 || coda.qFree.doubleValue() == 0) return;
if (Aval == 0.0 || Qval == 0.0) return;
// time base is seconds after P-wave
// one point per second for the length of the window
if (timeAmp1 == null || timeAmp2 == null) return;
int npts = (int) (timeAmp2.getTime() - timeAmp1.getTime() + coda.windowSize.doubleValue());
int x[] = new int[npts];
int y[] = new int[npts];
double amp;
// double mPlusA = coda.getMagnitude().value.doubleValue() + A;
double mPlusA = Aval;
double term1 = Math.pow(10.0, mPlusA);
double ptime = coda.getTime();
double tt0 = timeAmp1.getTime(); // start time, basically the s-time
/// winStart = coda.getTime() + timeAmp1.getTime();
for (int i = 0; i < npts; i++) {
//tt0 += (double) i; // seconds after P-wave
amp = term1 * Math.pow(tt0, -Qval) ;
amp += bias;
// System.out.println ( i +" "+tt0+" "+amp);
x[i] = wfp.pixelOfTime(ptime + tt0);
y[i] = wfp.pixelOfAmp(amp);
tt0++;
}
g.setColor(color);
g.drawPolyline(x, y, npts);
// do extrapolated part separately so we can plot in a different color
if (showExtrapolation) {
tt0 = 1.0;
npts = (int) timeAmp1.getTime();
x = new int[npts];
y = new int[npts];
for (int i = 0; i < npts; i++) {
amp = term1 * Math.pow(tt0, -Qval) ;
amp += bias;
// System.out.println ("x "+ i +" "+tt0+" "+amp);
x[i] = wfp.pixelOfTime(ptime + tt0);
y[i] = wfp.pixelOfAmp(amp);
tt0++;
}
g.setColor(Color.pink);
g.drawPolyline(x, y, npts);
}
}
} // end of CodaFlag
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -