/*
* TracePoint2D, a tuned Point2D.Double for use with ITrace2D- implementations. Copyright (c) 2004 - 2011 Achim Westermann,
* Achim.Westermann@gmx.de
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* If you modify or optimize the code in a useful way please let me know. Achim.Westermann@gmx.de
*/
package info.monitorenter.gui.chart;
import java.awt.geom.Point2D;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* A specialized version of java.awt.Point2D.Double who carries two further values: double scaledX and
* double scaledY which allow the Chart2D to cache the scaled values (between 0.0 and 1.0) without having to keep
* a copy of the aggregators (ITrace2D) complete tracepoints.
*
* This avoids the necessity to care for the correct order of a set of scaled tracepoints copied for caching purposes. Especially in the
* case of new TracePoint2D instances added to a ITrace2D instance managed by a Chart2D there remains
* no responsibility for sorting the cached copy. This allows that the managing Chart2D may just rescale the newly added
* tracepoint instead of searching for the correct order of the new tracepoint by value - comparisons of x and y: The
* TracePoint2D passed to the method traceChanged(Chart2DDataChangeEvent e) coded in the argument is the original.
*
*
* Why caching of scaled values for the coordinates?
* This takes more RAM but else for every repaint() invocation of the Chart2D would force all tracepoints of all
* traces to be rescaled again.
*
* A TracePoint2D will inform it's listener of type ITrace on changes of the internal values.
*
*
* @author Achim Westermann Achim.Westermann@gmx.de
* @version $Revision: 1.34 $
*/
public class TracePoint2D extends Point2D.Double implements ITracePoint2D {
/**
* Generated serialVersionUID.
*/
private static final long serialVersionUID = 3618980079204512309L;
/**
* The list of additional point painters.
*/
private Set> m_additionalPointPainters = new LinkedHashSet>();
/**
* The reference to the listening ITrace who owns this point.
*
* A trace point should be contained only in one trace!
*
*/
private ITrace2D m_listener;
/**
* Scaled x value.
*/
private double m_scaledX;
/**
* Scaled y value.
*/
private double m_scaledY;
/**
* The x coordinate, re-declared as the super class member will not be serialized.
*/
private double m_x;
/**
* The y coordinate, re-declared as the super class member will not be serialized.
*/
private double m_y;
/**
* Intended for {@link TracePointProviderDefault} only.
*
*/
protected TracePoint2D() {
// nop
}
/**
* Construct a TracePoint2D whose coords are initalized to (x,y).
*
*
* @param xValue
* the x value to use.
* @param yValue
* the y value to use.
*/
public TracePoint2D(final double xValue, final double yValue) {
this.m_x = xValue;
this.m_y = yValue;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#addAdditionalPointPainter(info.monitorenter.gui.chart.IPointPainter)
*/
public final boolean addAdditionalPointPainter(final IPointPainter> additionalPointPainter) {
Boolean result;
result = this.doSynchronized(new ICodeBlock() {
@SuppressWarnings("synthetic-access")
public Boolean execute() {
final boolean res = TracePoint2D.this.m_additionalPointPainters.add(additionalPointPainter);
// for interpolated points listener may be null:
if (res && TracePoint2D.this.m_listener != null) {
TracePoint2D.this.m_listener.firePointChanged(TracePoint2D.this, ITracePoint2D.STATE_CHANGED);
}
return Boolean.valueOf(res);
}
});
return result.booleanValue();
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#clone()
*/
@Override
public Object clone() {
final TracePoint2D result = (TracePoint2D) super.clone();
result.m_x = this.m_x;
result.m_y = this.m_y;
result.m_scaledX = this.m_scaledX;
result.m_scaledY = this.m_scaledY;
result.m_additionalPointPainters = new LinkedHashSet>(this.m_additionalPointPainters);
return result;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#compareTo(info.monitorenter.gui.chart.ITracePoint2D)
*/
public int compareTo(final ITracePoint2D obj) {
int result;
final double othx = obj.getX();
if (this.m_x < othx) {
result = -1;
} else {
if (this.m_x == othx) {
result = 0;
} else {
result = 1;
}
}
return result;
}
/**
* @see java.awt.geom.Point2D#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final TracePoint2D other = (TracePoint2D) obj;
if (java.lang.Double.doubleToLongBits(this.m_x) != java.lang.Double.doubleToLongBits(other.m_x)) {
return false;
}
if (java.lang.Double.doubleToLongBits(this.m_y) != java.lang.Double.doubleToLongBits(other.m_y)) {
return false;
}
return true;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getAdditionalPointPainters()
*/
public final Set> getAdditionalPointPainters() {
return this.m_additionalPointPainters;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getEuclidDistance(double, double)
*/
public double getEuclidDistance(final double xNormalized, final double yNormalized) {
double result;
final double xdist = Math.abs(this.m_scaledX - xNormalized);
final double ydist = Math.abs(this.m_scaledY - yNormalized);
result = Math.sqrt(Math.pow(xdist, 2) + Math.pow(ydist, 2));
return result;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getListener()
*/
public ITrace2D getListener() {
return this.m_listener;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getManhattanDistance(double, double)
*/
public double getManhattanDistance(final double xNormalized, final double yNormalized) {
double result;
result = Math.abs(this.m_scaledX - xNormalized) + Math.abs(this.m_scaledY - yNormalized);
return result;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getManhattanDistance(info.monitorenter.gui.chart.ITracePoint2D)
*/
public double getManhattanDistance(final ITracePoint2D point) {
return this.getManhattanDistance(point.getX(), point.getY());
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getScaledX()
*/
public final double getScaledX() {
return this.m_scaledX;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getScaledY()
*/
public final double getScaledY() {
return this.m_scaledY;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getX()
*/
@Override
public double getX() {
return this.m_x;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#getY()
*/
@Override
public double getY() {
return this.m_y;
}
/**
* @see java.awt.geom.Point2D#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
long temp;
temp = java.lang.Double.doubleToLongBits(this.m_x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = java.lang.Double.doubleToLongBits(this.m_y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#setListener(info.monitorenter.gui.chart.ITrace2D)
*/
public void setListener(final ITrace2D listener) {
this.m_listener = listener;
}
/**
* @see info.monitorenter.gui.chart.ITracePoint2D#setLocation(double, double)
*/
@Override
public void setLocation(final double xValue, final double yValue) {
this.doSynchronized(new ICodeBlock
Ads help maintain this website.