org.gwoptics.graphics.graph2D.traces
Class Line2DTrace

java.lang.Object
  extended by org.gwoptics.graphics.graph2D.traces.Line2DTrace
All Implemented Interfaces:
IGraph2DTrace, IRenderable
Direct Known Subclasses:
RollingLine2DTrace, UpdatingLine2DTrace

public class Line2DTrace
extends java.lang.Object
implements IGraph2DTrace

The Line2DTrace is the default implementation of the IGraphTrace interface. It can be used for a variety of plotting tasks and for 9/10 times will be useful for whatever is needed.

The Line2DTrace object requires that an IGraph2DCallback object is provided for it to plot a trace. To plot the trace, the generate() method is first called. This populates an internal array that stores the points of the trace. If the callback object changes, the trace will not change until the generate() method is called again. If you have a trace that changes regularly, ie a non-static standing wave, then call the generate method in each draw() call. Note: Make sure the callback object is optimised as much as possible for non static graphs, complicated graphs that are regenerated each draw call will grind the system to a halt, contemplate using the TrigLookup object for faster sinusoidal functions.

This trace object also accepts trace effects defined by the ITraceColourEffect interface. Use this to visually enhance a graph trace.

Custom 2D Traces
If the need arises to create a custom trace object for the graph2D control two options are open. Implement the IGraphTrace interface from scratch or inherit the Line2DTrace object, the later being the simplest. To do that though understanding of the class is necessary and its members.

Most of the public members are properties such as setAxis and setTraceColour, these simple apply a value to the relevant member and most likely will not need overriding. The most likely candidates for overriding are the generate and draw methods. Generate simply goes about deducing the graph value for each pixel on the x-axis and then passing this to the ILineEquation object to produce a y value. This is converted into a point that is represented on the Y-axis and then stored in the _pointData and _eqData arrays. The generate function therefore only needs to be called on if the trace is changing values or shape.

The draw method is the one who goes about plotting the values using the _pointData array. No heavy calculations should be going on in the draw method, to give the best framerates. Draw loops through each _pointData value and limits it to the max and min values of the y-axis and then draws the points using connected lines. At this point any trace colour effect is also applied to the trace. One important note is that if you want to display no point at a place on your trace, simply put Float.NaN into the _pointData array. The draw method then ignores this point.

The recommended approach to producing a new trace is to override the generate method and populate the relevant arrays as needed. Then let the draw method do its job, this is recommended if what you are looking for in the end is a line. If for example an area graph, bar-graph, histogram or scatter plot is required then the draw method would be need to be altered to produce the correct effect. For future use if no source is present the generate and draw method code is included below, all the other methods can be left not overridden.

 
        protected Axis2D _ax, _ay; //Reference to the 2 axis objects of the graph2D control
        protected PApplet _parent; //Parent PApplet
        protected ILineEquation _cb; //The ILineEquation used to implemnt the data to plot
        protected double[] _eqData; //This array stores for each pixel along the X-Axis a Y value in graph space
        protected float[] _pointData; //This array stores the Y pixel value of each pixel along the X-Axis. 
        protected boolean _yAutoRange; //determines whether to auto range the y axis
        protected PVector _pos; //position of the trace on the graph
        protected Colour _traceColour; // solid colour of the trace if no effect applied
        protected ITraceColourEffect _effect; //Colour effect applied to the trace

        public void generate() {
                if(_ax == null || _ay == null)
                        throw new RuntimeException("One of the axis objects are null, set them using setAxes().");

                if(_cb != null){
                        float dRes = (_ax.getMaxValue() - _ax.getMinValue()) / (_ax.getLength() - 1);
                        double highestValue = 0;
                        double lowestValue = 0;

                        for (int i = 0; i < _eqData.length; i++) {
                                double val = _cb.computePoint(_ax.getMinValue() + i * dRes);

                                _eqData[i] = val;

                                if(_yAutoRange){
                                        if(val > highestValue)
                                                highestValue = val;
                                        else if(val < lowestValue)
                                                val = lowestValue;

                                }else
                                        _pointData[i] = _ay.valueToPosition((float) val); 
                        }

                        if(_yAutoRange){
                                _ay.setMinValue((float) lowestValue);
                                _ay.setMaxValue((float) highestValue);

                                for (int i = 0; i < _eqData.length; i++) {
                                        _pointData[i] = _ay.valueToPosition((float)_eqData[i]); 
                                }
                        }
                }
        }

        public void draw() {
                if(_parent == null)
                        throw new NullPointerException("Set parent object before plotting.");

                float y1,y2;
                boolean b1,b2;
                float dRes = (_ax.getMaxValue() - _ax.getMinValue()) / (_ax.getLength() - 1);
                Colour cTrace;

                _parent.pushMatrix();
                _parent.pushStyle();
                _parent.translate(_pos.x, _pos.y);

                for (int i = 1; i < _pointData.length; i++) {
                        b1 = true;
                        b2 = true;
                        y1 = _pointData[i-1];
                        y2 = _pointData[i];

                        if(!(Float.isNaN(y1) || Float.isNaN(y2))){

                                if(y1 > _ay.getLength()){
                                        y1 = _ay.getLength();
                                }else if(y1 < 0){
                                        y1 = 0;
                                }else
                                        b1 = false;

                                if(y2 > _ay.getLength()){
                                        y2 = _ay.getLength();
                                }else if(y2 < 0){
                                        y2 = 0;
                                }else
                                        b2 = false;

                                if(!(b1 && b2)){
                                        if(_effect != null)
                                                cTrace = _effect.getPixelColour(i-1, (int) y1,_ax.getMinValue() + i * dRes,(float)_eqData[i-1]);
                                        else
                                                cTrace = _traceColour;

                                        _parent.stroke(cTrace.R * 255,cTrace.G * 255,cTrace.B * 255,cTrace.A * 255);
                                        //_parent.stroke(cTrace.toInt());
                                        _parent.strokeWeight(1);
                                        _parent.line(i-1, -y1, i, -y2);
                                }
                        }
                }

                _parent.popStyle();
                _parent.popMatrix();
        }
 
 

Since:
0.4.0
Author:
Daniel Brown 13/7/09

Constructor Summary
Line2DTrace(ILine2DEquation eq)
          Default constructor accepting a callback object implementing the ILineEquation interface.
 
Method Summary
 void draw()
          Uses the data that generate produced beforehand to plot the final trace line.
 void generate()
          Uses the ILineEquation object provided to fill the internal arrays.
 void onAddTrace(java.lang.Object[] traces)
           Before the trace is added to the graph control this method is called.
 void onRemoveTrace()
           Before the trace is officially removed from the trace list of a Graph2D object, the onRemove method is called.
 void removeEffect()
           
 void setEquationCallback(ILine2DEquation equation)
          Sets the callback object implementing the ILineEquation interface.
 void setGraph(IGraph2D grp)
          Sets an internal variable to store a reference to the graph object the trace is being plotted on
 void setLineWidth(int width)
           
 void setParent(processing.core.PApplet parent)
          Sets the parent PApplet object
 void setPosition(int x, int y)
          Sets the position of the trace
 void setTraceColour(int R, int G, int B)
           
 void setTraceEffect(ITraceColourEffect effect)
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Line2DTrace

public Line2DTrace(ILine2DEquation eq)
Default constructor accepting a callback object implementing the ILineEquation interface. The object should then accept an x value and return a y.

Method Detail

setGraph

public void setGraph(IGraph2D grp)
Description copied from interface: IGraph2DTrace
Sets an internal variable to store a reference to the graph object the trace is being plotted on

Specified by:
setGraph in interface IGraph2DTrace

setParent

public void setParent(processing.core.PApplet parent)
Sets the parent PApplet object

Specified by:
setParent in interface IRenderable

setPosition

public void setPosition(int x,
                        int y)
Sets the position of the trace

Specified by:
setPosition in interface IGraph2DTrace

setEquationCallback

public void setEquationCallback(ILine2DEquation equation)
Sets the callback object implementing the ILineEquation interface. The object should then accept an x value and return a y.


generate

public void generate()
Uses the ILineEquation object provided to fill the internal arrays. The arrays are then used to plot the data in the draw method.

Specified by:
generate in interface IGraph2DTrace

draw

public void draw()
Uses the data that generate produced beforehand to plot the final trace line. Also applies any colour of effect to the trace.

Specified by:
draw in interface IRenderable

onAddTrace

public void onAddTrace(java.lang.Object[] traces)
Description copied from interface: IGraph2DTrace

Before the trace is added to the graph control this method is called. It allows a trace to check the settings of other traces that have previously been added for in Compatibilities. Leave method empty in implementation if no checks are necessary.

w onAddTrace is called from with a synchronised lock so the traces object won't be modified whilst reading it. Therefore it is not necessary to provide custom thread locks.

Specified by:
onAddTrace in interface IGraph2DTrace

onRemoveTrace

public void onRemoveTrace()
Description copied from interface: IGraph2DTrace

Before the trace is officially removed from the trace list of a Graph2D object, the onRemove method is called. This allows the trace object to provide any cleanup needed, if at all needed. Leave blank if nothing is needed.

Specified by:
onRemoveTrace in interface IGraph2DTrace

setTraceColour

public void setTraceColour(int R,
                           int G,
                           int B)

setLineWidth

public void setLineWidth(int width)

removeEffect

public void removeEffect()

setTraceEffect

public void setTraceEffect(ITraceColourEffect effect)


processing library gwoptics by Daniel Brown and Andreas Freise. (c) 2009 onwards