Changeset 5478


Ignore:
Timestamp:
May 9, 2015 2:56:07 AM (9 years ago)
Author:
ldelgass
Message:

Begin refactoring axis/grid in nanovis: remove unused features, make the style
more C++

Location:
nanovis/trunk
Files:
2 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • nanovis/trunk/Axis.cpp

    r3611 r5478  
    33 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
    44 *
    5  * Authors: George A. Howlett <gah@purdue.edu>
    6  */
     5 * Authors:
     6 *   George A. Howlett <gah@purdue.edu>
     7 *   Leif Delgass <ldelgass@purdue.edu>
     8 */
     9#include <string>
     10
    711#include <stdlib.h>
    812#include <stdio.h>
     
    1216
    1317#include "Axis.h"
     18#include "Trace.h"
    1419
    1520using namespace nv;
    16 
    17 inline bool DEFINED(double x) {
    18     return !isnan(x);
    19 }
    2021
    2122inline double EXP10(double x) {
     
    8586    _numTicks = 0;
    8687    _ticks = new float[_nSteps];
    87     if (_step == 0.0) {
    88         /* Hack: A zero step indicates to use log values. */
    89         unsigned int i;
    90         /* Precomputed log10 values [1..10] */
    91         static double logTable[] = {
    92             0.0,
    93             0.301029995663981,
    94             0.477121254719662,
    95             0.602059991327962,
    96             0.698970004336019,
    97             0.778151250383644,
    98             0.845098040014257,
    99             0.903089986991944,
    100             0.954242509439325,
    101             1.0
    102         };
    103         for (i = 0; i < _nSteps; i++) {
    104             _ticks[i] = logTable[i];
    105         }
    106     } else {
    107         double value;
    108         unsigned int i;
    109    
    110         value = _initial;        /* Start from smallest axis tick */
    111         for (i = 0; i < _nSteps; i++) {
    112             value = _initial + (_step * i);
    113             _ticks[i] = UROUND(value, _step);
    114         }
     88    // Start from smallest axis tick
     89    double value = _initial;
     90    for (unsigned int i = 0; i < _nSteps; i++) {
     91        value = _initial + (_step * i);
     92        _ticks[i] = UROUND(value, _step);
    11593    }
    11694    _numTicks = _nSteps;
    11795}
    11896
    119 Axis::Axis(const char *axisName) :
    120     _name(strdup(axisName)),
    121     _flags(AUTOSCALE),
    122     _title(NULL),
    123     _units(NULL),
     97Axis::Axis(const char *title) :
     98    _title(title),
     99    _tightMin(false),
     100    _tightMax(false),
     101    _reqStep(0.0),
    124102    _valueMin(DBL_MAX),
    125103    _valueMax(-DBL_MAX),
    126     _reqMin(NAN),
    127     _reqMax(NAN),
    128104    _min(DBL_MAX),
    129105    _max(-DBL_MAX),
    130     _range(0.0),
    131     _scale(0.0),
    132     _reqStep(0.0),
    133106    _major(5),
    134107    _minor(2)
     
    140113 *
    141114 * The value is normalized by the current axis range. If the normalized
    142  * value is between [0.0..1.0] then it's in range.  The value is compared
     115 * value is between [0.0,1.0] then it's in range.  The value is compared
    143116 * to 0 and 1., where 0.0 is the minimum and 1.0 is the maximum.
    144117 * DBL_EPSILON is the smallest number that can be represented on the host
     
    147120 * Please note, *max* can't equal *min*.
    148121 *
    149  * \return If the value is within the interval [min..max], 1 is returned; 0
     122 * \return If the value is within the interval [min,max], 1 is returned; 0
    150123 * otherwise.
    151124 */
     
    153126Axis::inRange(double x)
    154127{
    155     if (_range < DBL_EPSILON) {
     128    if ((_max - _min) < DBL_EPSILON) {
    156129        return (fabs(_max - x) >= DBL_EPSILON);
    157130    } else {
    158         x = (x - _min) * _scale;
     131        x = map(x);
    159132        return ((x >= -DBL_EPSILON) && ((x - 1.0) < DBL_EPSILON));
    160133    }
     
    165138{
    166139    if (min == DBL_MAX) {
    167         if (DEFINED(_reqMin)) {
    168             min = _reqMin;
    169         } else {
    170             min = (_flags & LOGSCALE) ? 0.001 : 0.0;
    171         }
     140        min = 0.0;
    172141    }
    173142    if (max == -DBL_MAX) {
    174         if (DEFINED(_reqMax)) {
    175             max = _reqMax;
    176         } else {
    177             max = 1.0;
    178         }
     143        max = 1.0;
    179144    }
    180145    if (min >= max) {
    181         /*
    182          * There is no range of data (i.e. min is not less than max), so
    183          * manufacture one.
    184          */
     146        // No range, so pick a default
    185147        if (min == 0.0) {
    186148            min = 0.0, max = 1.0;
     
    190152    }
    191153
    192     /*   
    193      * The axis limits are either the current data range or overridden by the
    194      * values selected by the user with the -min or -max options.
    195      */
    196     _valueMin = (DEFINED(_reqMin)) ? _reqMin : min;
    197     _valueMax = (DEFINED(_reqMax)) ? _reqMax : max;
    198     if (_valueMax < _valueMin) {
    199         /*   
    200          * If the limits still don't make sense, it's because one limit
    201          * configuration option (-min or -max) was set and the other default
    202          * (based upon the data) is too small or large.  Remedy this by making
    203          * up a new min or max from the user-defined limit.
    204          */
    205         if (!DEFINED(_reqMin)) {
    206             _valueMin = _valueMax - (fabs(_valueMax) * 0.1);
    207         }
    208         if (!DEFINED(_reqMax)) {
    209             _valueMax = _valueMin + (fabs(_valueMax) * 0.1);
    210         }
    211     }
    212 }
    213 
    214 /**
    215  * \brief Determine the range and units of a log scaled axis.
    216  *
    217  * Unless the axis limits are specified, the axis is scaled
    218  * automatically, where the smallest and largest major ticks encompass
    219  * the range of actual data values.  When an axis limit is specified,
    220  * that value represents the smallest(min)/largest(max) value in the
    221  * displayed range of values.
    222  *
    223  * Both manual and automatic scaling are affected by the step used.  By
    224  * default, the step is the largest power of ten to divide the range in
    225  * more than one piece.
    226  *
    227  * Automatic scaling:
    228  * Find the smallest number of units which contain the range of values.
    229  * The minimum and maximum major tick values will be represent the
    230  * range of values for the axis. This greatest number of major ticks
    231  * possible is 10.
    232  *
    233  * Manual scaling:
    234  * Make the minimum and maximum data values the represent the range of
    235  * the values for the axis.  The minimum and maximum major ticks will be
    236  * inclusive of this range.  This provides the largest area for plotting
    237  * and the expected results when the axis min and max values have be set
    238  * by the user (.e.g zooming).  The maximum number of major ticks is 20.
    239  *
    240  * For log scale, there's the possibility that the minimum and
    241  * maximum data values are the same magnitude.  To represent the
    242  * points properly, at least one full decade should be shown.
    243  * However, if you zoom a log scale plot, the results should be
    244  * predictable. Therefore, in that case, show only minor ticks.
    245  * Lastly, there should be an appropriate way to handle numbers
    246  * <=0.
     154    _valueMin = min;
     155    _valueMax = max;
     156}
     157
     158/**
     159 * \brief Determine the units of a linear scaled axis.
     160 *
     161 * The axis limits are either the range of the data values mapped
     162 * to the axis (autoscaled), or the values specified by the -min
     163 * and -max options (manual).
     164 *
     165 * If autoscaled, the smallest and largest major ticks will
     166 * encompass the range of data values.  If the -loose option is
     167 * selected, the next outer ticks are choosen.  If tight, the
     168 * ticks are at or inside of the data limits are used.
     169 *
     170 * If manually set, the ticks are at or inside the data limits
     171 * are used.  This makes sense for zooming.  You want the
     172 * selected range to represent the next limit, not something a
     173 * bit bigger.
     174 *
     175 * Note: I added an "always" value to the -loose option to force
     176 * the manually selected axes to be loose. It's probably
     177 * not a good idea.
     178 *
    247179 * <pre>
    248180 *          maxY
     
    268200 *           minY
    269201 *
    270  *      numTicks = Number of ticks
    271  *      min = Minimum value of axis
    272  *      max = Maximum value of axis
    273  *      range = Range of values (max - min)
    274  *
    275  * </pre>
    276  *
    277  *      If the number of decades is greater than ten, it is assumed
    278  *      that the full set of log-style ticks can't be drawn properly.
    279  */
    280 void
    281 Axis::logScale()
    282 {
    283     double range;
    284     double tickMin, tickMax;
    285     double majorStep, minorStep;
    286     int nMajor, nMinor;
    287     double min, max;
    288 
    289     nMajor = nMinor = 0;
    290     /* Suppress compiler warnings. */
    291     majorStep = minorStep = 0.0;
    292     tickMin = tickMax = NAN;
    293     min = _valueMin, max = _valueMax;
    294     if (min < max) {
    295         min = (min != 0.0) ? log10(fabs(min)) : 0.0;
    296         max = (max != 0.0) ? log10(fabs(max)) : 1.0;
    297 
    298         tickMin = floor(min);
    299         tickMax = ceil(max);
    300         range = tickMax - tickMin;
    301        
    302         if (range > 10) {
    303             /* There are too many decades to display a major tick at every
    304              * decade.  Instead, treat the axis as a linear scale.  */
    305             range = niceNum(range, 0);
    306             majorStep = niceNum(range / _major.reqNumTicks, 1);
    307             tickMin = UFLOOR(tickMin, majorStep);
    308             tickMax = UCEIL(tickMax, majorStep);
    309             nMajor = (int)((tickMax - tickMin) / majorStep) + 1;
    310             minorStep = EXP10(floor(log10(majorStep)));
    311             if (minorStep == majorStep) {
    312                 nMinor = 4, minorStep = 0.2;
    313             } else {
    314                 nMinor = ROUND(majorStep / minorStep) - 1;
    315             }
    316         } else {
    317             if (tickMin == tickMax) {
    318                 tickMax++;
    319             }
    320             majorStep = 1.0;
    321             nMajor = (int)(tickMax - tickMin + 1); /* FIXME: Check this. */
    322            
    323             minorStep = 0.0;    /* This is a special hack to pass
    324                                  * information to the SetTicks
    325                                  * method. An interval of 0.0 indicates
    326                                  *   1) this is a minor sweep and
    327                                  *   2) the axis is log scale. 
    328                                  */
    329             nMinor = 10;
    330         }
    331         if ((_flags & TIGHT_MIN) || (DEFINED(_reqMin))) {
    332             tickMin = min;
    333             nMajor++;
    334         }
    335         if ((_flags & TIGHT_MAX) || (DEFINED(_reqMax))) {
    336             tickMax = max;
    337         }
    338     }
    339     _major.setValues(floor(tickMin), majorStep, nMajor);
    340     _minor.setValues(minorStep, minorStep, nMinor);
    341     _min = tickMin;
    342     _max = tickMax;
    343     _range = _max - _min;
    344     _scale = 1.0 / _range;
    345 }
    346 
    347 /**
    348  * \brief Determine the units of a linear scaled axis.
    349  *
    350  * The axis limits are either the range of the data values mapped
    351  * to the axis (autoscaled), or the values specified by the -min
    352  * and -max options (manual).
    353  *
    354  * If autoscaled, the smallest and largest major ticks will
    355  * encompass the range of data values.  If the -loose option is
    356  * selected, the next outer ticks are choosen.  If tight, the
    357  * ticks are at or inside of the data limits are used.
    358  *
    359  * If manually set, the ticks are at or inside the data limits
    360  * are used.  This makes sense for zooming.  You want the
    361  * selected range to represent the next limit, not something a
    362  * bit bigger.
    363  *
    364  * Note: I added an "always" value to the -loose option to force
    365  * the manually selected axes to be loose. It's probably
    366  * not a good idea.
    367  *
    368  * <pre>
    369  *          maxY
    370  *            |    units = magnitude (of least significant digit)
    371  *            |    high  = largest unit tick < max axis value
    372  *      high _|    low   = smallest unit tick > min axis value
    373  *            |
    374  *            |    range = high - low
    375  *            |    # ticks = greatest factor of range/units
    376  *           _|
    377  *        U   |
    378  *        n   |
    379  *        i   |
    380  *        t  _|
    381  *            |
    382  *            |
    383  *            |
    384  *       low _|
    385  *            |
    386  *            |_minX________________maxX__
    387  *            |   |       |      |       |
    388  *     minY  low                        high
    389  *           minY
    390  *
    391202 *      numTicks = Number of ticks
    392203 *      min = Minimum value of axis
     
    403214Axis::linearScale()
    404215{
    405     double step;
    406     double tickMin, tickMax;
    407     unsigned int nTicks;
    408 
    409     nTicks = 0;
    410     step = 1.0;
    411     /* Suppress compiler warning. */
    412     tickMin = tickMax = 0.0;
     216    double tickMin = 0., tickMax = 0.;
     217    double step = 1.0;
     218    unsigned int nTicks = 0;
     219
    413220    if (_valueMin < _valueMax) {
    414         double range;
    415 
    416         range = _valueMax - _valueMin;
     221        double range = _valueMax - _valueMin;
    417222        /* Calculate the major tick stepping. */
    418223        if (_reqStep > 0.0) {
     
    439244     * The limits of the axis are either the range of the data ("tight") or at
    440245     * the next outer tick interval ("loose").  The looseness or tightness has
    441      * to do with how the axis fits the range of data values.  This option is
    442      * overridden when the user sets an axis limit (by either -min or -max
    443      * option).  The axis limit is always at the selected limit (otherwise we
    444      * assume that user would have picked a different number).
     246     * to do with how the axis fits the range of data values.
    445247     */
    446     _min = ((_flags & TIGHT_MIN)||(DEFINED(_reqMin))) ? _valueMin : tickMin;
    447     _max = ((_flags & TIGHT_MAX)||(DEFINED(_reqMax))) ? _valueMax : tickMax;
    448     _range = _max - _min;
    449     _scale = 1.0 / _range;
     248    _min = _tightMin ? _valueMin : tickMin;
     249    _max = _tightMax ? _valueMax : tickMax;
    450250
    451251    /* Now calculate the minor tick step and number. */
    452252
    453     if ((_minor.reqNumTicks > 0) && (_minor.autoscale())) {
     253    if (_minor.reqNumTicks > 0) {
    454254        nTicks = _minor.reqNumTicks - 1;
    455255        step = 1.0 / (nTicks + 1);
     
    463263}
    464264
    465 
     265/**
     266 * \brief This sets the data range of the axis.
     267 */
    466268void
    467 Axis::setScale(double min, double max)
    468 {
     269Axis::setRange(double min, double max)
     270{
     271    // set valueMin/Max (overridden by requested min/max if present)
    469272    fixRange(min, max);
    470     if (_flags & LOGSCALE) {
    471         logScale();
    472     } else {
    473         linearScale();
    474     }
     273    // Set steps
     274    linearScale();
     275    // Fill ticks float arrays based on spacing
    475276    _major.sweepTicks();
    476277    _minor.sweepTicks();
     278    // Copy to linked lists
    477279    makeTicks();
    478280}
    479281
     282/**
     283 * \brief Copy tick values to major/minor linked lists, skipping duplicate values
     284 */
    480285void
    481286Axis::makeTicks()
     
    483288    _major.reset();
    484289    _minor.reset();
    485     int i;
    486     for (i = 0; i < _major.numTicks(); i++) {
    487         double t1, t2;
    488         int j;
    489        
    490         t1 = _major.tick(i);
     290    for (int i = 0; i < _major.numTicks(); i++) {
     291        double t1 = _major.tick(i);
    491292        /* Minor ticks */
    492         for (j = 0; j < _minor.numTicks(); j++) {
    493             t2 = t1 + (_major.step() * _minor.tick(j));
     293        for (int j = 0; j < _minor.numTicks(); j++) {
     294            double t2 = t1 + (_major.step() * _minor.tick(j));
    494295            if (!inRange(t2)) {
    495296                continue;
     
    507308}
    508309
     310/**
     311 * \brief Map world coordinate [_min,_max] to normalized coordinate [0,1]
     312 */
    509313double
    510314Axis::map(double x)
    511315{
    512     if ((_flags & LOGSCALE) && (x != 0.0)) {
    513         x = log10(fabs(x));
    514     }
    515     /* Map graph coordinate to normalized coordinates [0..1] */
    516     x = (x - _min) * _scale;
    517     if (_flags & DESCENDING) {
    518         x = 1.0 - x;
    519     }
     316    x = (x - _min) / (_max - _min);
    520317    return x;
    521318}
    522319
     320/**
     321 * \brief Map normalized coordinate [0,1] to world coordinate [_min,_max]
     322 */
    523323double
    524324Axis::invMap(double x)
    525325{
    526     if (_flags & DESCENDING) {
    527         x = 1.0 - x;
    528     }
    529     x = (x * _range) + _min;
    530     if (_flags & LOGSCALE) {
    531         x = EXP10(x);
    532     }
     326    x = (x * (_max - _min)) + _min;
    533327    return x;
    534328}
  • nanovis/trunk/Axis.h

    r3630 r5478  
    33 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
    44 *
    5  * Authors: George A. Howlett <gah@purdue.edu>
     5 * Authors:
     6 *   George A. Howlett <gah@purdue.edu>
     7 *   Leif Delgass <ldelgass@purdue.edu>
    68 */
    79#ifndef NV_AXIS_H
    810#define NV_AXIS_H
    911
    10 #include <stdlib.h>
    11 #include <string.h>
    12 
    1312#include <cmath>
    1413#include <limits>
    15 
    16 #include "Chain.h"
     14#include <list>
     15#include <string>
     16#include <cstdlib>
     17#include <cstring>
    1718
    1819#ifndef NAN
     
    2324
    2425class Axis;
    25 
    26 class TickIter
    27 {
    28 public:
    29     void setStartingLink(ChainLink *linkPtr)
    30     {
    31         _linkPtr = linkPtr;
    32     }
    33 
    34     bool next()
    35     {
    36         if (_linkPtr == NULL) {
    37             return false;
    38         }
    39         _linkPtr = _linkPtr->next();
    40         return (_linkPtr != NULL);
    41     }
    42 
    43     float getValue()
    44     {
    45         union {
    46             float x;
    47             void *clientData;
    48         } value;
    49         value.clientData = _linkPtr->getValue();
    50         return value.x;
    51     }
    52 
    53 private:
    54     ChainLink *_linkPtr;
    55 };
    5626
    5727/**
     
    6232{
    6333public:
     34    typedef std::list<double>::iterator Iterator;
     35    typedef std::list<double>::const_iterator ConstIterator;
     36
    6437    Ticks(int numTicks) :
    6538        reqNumTicks(numTicks),
    66         _autoscale(true),
    6739        _numTicks(0),
    6840        _ticks(NULL)
     
    7547            delete [] _ticks;
    7648        }
    77         _chain.reset();
    78     }
    79 
    80     void setTicks(float *ticks, int nTicks)
    81     {
    82         _ticks = ticks, _numTicks = nTicks;
    83     }
    84 
    85     int numTicks()
     49    }
     50
     51    int numTicks() const
    8652    {
    8753        return _numTicks;
     
    9864    void reset()
    9965    {
    100         _chain.reset();
    101     }
    102 
    103     float step()
     66        _chain.clear();
     67    }
     68
     69    float step() const
    10470    {
    10571        return _step;
    10672    }
    10773
    108     void append (float x)
    109     {
    110         _chain.append(getClientData(x));
     74    void append(float x)
     75    {
     76        _chain.push_back(x);
    11177    }
    11278
     
    11682    }
    11783
    118     bool autoscale()
    119     {
    120         return _autoscale;
    121     }
    122 
    12384    void sweepTicks()
    12485    {
    125         if (_autoscale) {
    126             if (_ticks != NULL) {
    127                 delete [] _ticks;
    128             }
    129             setTicks();
     86        if (_ticks != NULL) {
     87            delete [] _ticks;
    13088        }
    131     }
    132 
    133     bool firstTick(TickIter &iter)
    134     {
    135         ChainLink *linkPtr;
    136 
    137         linkPtr = _chain.firstLink();
    138         iter.setStartingLink(linkPtr);
    139         return (linkPtr != NULL);
     89        setTicks();
     90    }
     91
     92    ConstIterator begin() const
     93    {
     94        return _chain.begin();
     95    }
     96
     97    ConstIterator end() const
     98    {
     99        return _chain.end();
    140100    }
    141101
     
    144104private:
    145105    void setTicks();    /**< Routine used internally to create the array
    146                                  * of ticks as defined by a given sweep. */
    147     void *getClientData(float x)
    148     {
    149         union {
    150             float x;
    151             void *clientData;
    152         } value;
    153         value.x = x;
    154         return value.clientData;
    155     }
     106                         * of ticks as defined by a given sweep. */
    156107
    157108    bool _autoscale;            /**< Indicates if the ticks are autoscaled. */
     
    182133     * the chain.
    183134     */
    184     Chain _chain;
     135    std::list<double> _chain;
    185136};
    186137
     
    192143{
    193144public:
    194     /// Flags associated with the axis.
    195     enum AxisFlags {
    196         AUTOSCALE  = (1<<0),
    197         DESCENDING = (1<<1),
    198         LOGSCALE   = (1<<2),
    199         TIGHT_MIN  = (1<<3),
    200         TIGHT_MAX  = (1<<4)
    201     };
    202 
    203     Axis(const char *name);
     145    Axis(const char *title);
    204146
    205147    ~Axis()
    206148    {
    207         if (_name != NULL) {
    208             free((void *)_name);
    209         }
    210         if (_units != NULL) {
    211             free((void *)_units);
    212         }
    213         if (_title != NULL) {
    214             free((void *)_title);
    215         }
    216     }
    217 
    218     bool firstMajor(TickIter& iter)
    219     {
    220         return _major.firstTick(iter);
    221     }
    222 
    223     bool firstMinor(TickIter& iter)
    224     {
    225         return _minor.firstTick(iter);
    226     }
    227 
     149    }
     150
     151    Ticks::ConstIterator firstMajor() const
     152    {
     153        return _major.begin();
     154    }
     155    Ticks::ConstIterator lastMajor() const
     156    {
     157        return _major.end();
     158    }
     159    Ticks::ConstIterator firstMinor() const
     160    {
     161        return _minor.begin();
     162    }
     163    Ticks::ConstIterator lastMinor() const
     164    {
     165        return _minor.end();
     166    }
     167
     168    double dataMin() const
     169    {
     170        return _valueMin;
     171    }
     172
     173    double dataMax() const
     174    {
     175        return _valueMax;
     176    }
     177
     178    double min() const
     179    {
     180        return _min;
     181    }
     182
     183    double max() const
     184    {
     185        return _max;
     186    }
     187
     188    double length() const
     189    {
     190        return (_max - _min);
     191    }
     192
     193    void setRange(double min, double max);
     194
     195    double map(double x);
     196
     197    double invMap(double x);
     198
     199    const char *title() const
     200    {
     201        return _title.c_str();
     202    }
     203
     204    void title(const char *title)
     205    {
     206        _title = title;
     207    }
     208
     209    const char *units() const
     210    {
     211        return _units.c_str();
     212    }
     213
     214    void units(const char *units)
     215    {
     216        _units = units;
     217    }
     218
     219    void setTightMin(bool value)
     220    {
     221        _tightMin = value;
     222    }
     223
     224    void setTightMax(bool value)
     225    {
     226        _tightMax = value;
     227    }
     228
     229    void setMajorStep(double value)
     230    {
     231        // Setting to 0.0 resets step to "auto"
     232        _reqStep = value;
     233    }
     234
     235    void setNumMajorTicks(int n)
     236    {
     237        _major.reqNumTicks = n;
     238    }
     239
     240    void setNumMinorTicks(int n)
     241    {
     242        _minor.reqNumTicks = n;
     243    }
     244
     245private:
    228246    void resetRange();
    229247
    230248    void fixRange(double min, double max);
    231249
    232     void setScale(double min, double max);
    233 
    234     double scale() const
    235     {
    236         return _scale;
    237     }
    238 
    239     double range() const
    240     {
    241         return _range;
    242     }
    243 
    244     double dataMin() const
    245     {
    246         return _valueMin;
    247     }
    248 
    249     double dataMax() const
    250     {
    251         return _valueMax;
    252     }
    253 
    254     double min() const
    255     {
    256         return _min;
    257     }
    258 
    259     double max() const
    260     {
    261         return _max;
    262     }
    263 
    264     void setLimits(double min, double max)
    265     {
    266         _reqMin = min, _reqMax = max;
    267     }
    268 
    269     void unsetLimits()
    270     {
    271         setLimits(NAN, NAN);
    272     }
    273 
    274     double map(double x);
    275 
    276     double invMap(double x);
    277 
    278     const char *name()
    279     {
    280         return _name;
    281     }
    282 
    283     void name(const char *name)
    284     {
    285         if (_name != NULL) {
    286             free((void *)_name);
    287         }
    288         _name = strdup(name);
    289     }
    290 
    291     const char *units()
    292     {
    293         return _units;
    294     }
    295 
    296     void units(const char *units)
    297     {
    298         if (_units != NULL) {
    299             free((void *)_units);
    300         }
    301         _units = strdup(units);
    302     }
    303 
    304     const char *title()
    305     {
    306         return _title;
    307     }
    308 
    309     void title(const char *title)
    310     {
    311         if (_title != NULL) {
    312             free((void *)_title);
    313         }
    314         _title = strdup(title);
    315     }
    316 
    317     void setDescendingOption(bool value)
    318     {
    319         if (value) {
    320             _flags |= DESCENDING;
    321         } else {
    322             _flags &= ~DESCENDING;
    323         }
    324     }
    325 
    326     void setTightMinOption(bool value)
    327     {
    328         if (value) {
    329             _flags |= TIGHT_MIN;
    330         } else {
    331             _flags &= ~TIGHT_MIN;
    332         }
    333     }
    334 
    335     void setTightMaxOption(bool value)
    336     {
    337         if (value) {
    338             _flags |= TIGHT_MAX;
    339         } else {
    340             _flags &= ~TIGHT_MAX;
    341         }
    342     }
    343 
    344     void setLogScaleOption(bool value)
    345     {
    346         if (value) {
    347             _flags |= LOGSCALE;
    348         } else {
    349             _flags &= ~LOGSCALE;
    350         }
    351     }
    352 
    353     void setMajorStepOption(double value)
    354     {
    355         _reqStep = value;       // Setting to 0.0 resets step to "auto"
    356     }
    357 
    358     void setNumMinorTicksOption(int n)
    359     {
    360         _minor.reqNumTicks = n;
    361     }
    362 
    363     void setNumMajorTicksOption(int n)
    364     {
    365         _major.reqNumTicks = n;
    366     }
    367 
    368 private:
    369     void logScale();
    370 
    371250    void linearScale();
    372251
     
    375254    void makeTicks();
    376255
    377     const char *_name;          /**< Name of the axis. Malloc-ed */
    378 
    379     unsigned int _flags;
    380 
    381     const char *_title;         /**< Title of the axis. */
    382 
    383     const char *_units;         /**< Units of the axis. */
    384 
    385     double _valueMin, _valueMax; /**< The limits of the data. */
    386 
    387     double _reqMin, _reqMax;    /**< Requested axis bounds. Consult the
    388                                  * axisPtr->flags field for
    389                                  * Axis::CONFIG_MIN and Axis::CONFIG_MAX
    390                                  * to see if the requested bound have
    391                                  * been set.  They override the
    392                                  * computed range of the axis
    393                                  * (determined by auto-scaling). */
    394 
     256    std::string _title;         /**< Title of the axis */
     257    std::string _units;         /**< Units of the axis */
     258
     259    bool _tightMin, _tightMax;  /**< Tight bounds option flags */
     260
     261    double _reqStep;            /**< If > 0.0, overrides the computed major tick
     262                                 * interval.  Otherwise a stepsize is
     263                                 * automatically calculated, based upon the
     264                                 * range of elements mapped to the axis. The
     265                                 * default value is 0.0. */
     266
     267    double _valueMin, _valueMax; /**< The limits of the data */
    395268    double _min, _max;          /**< Smallest and largest major tick values for
    396269                                 * the axis.  If loose, the tick values lie
     
    399272                                 * the data. */
    400273
    401     double _range;              /**< Range of values on axis (_max - _min) */
    402     double _scale;              /**< Scale factor for axis (1.0/_range) */
    403 
    404     double _reqStep;            /**< If > 0.0, overrides the computed major tick
    405                                  * interval.  Otherwise a stepsize is
    406                                  * automatically calculated, based upon the
    407                                  * range of elements mapped to the axis. The
    408                                  * default value is 0.0. */
    409 
    410274    Ticks _major, _minor;
    411275};
  • nanovis/trunk/Command.cpp

    r5303 r5478  
    21072107    }
    21082108    if (NanoVis::grid != NULL) {
    2109         Axis *axisPtr;
    2110 
    2111         axisPtr = NULL;     /* Suppress compiler warning. */
     2109        Axis *axisPtr = NULL;
    21122110        switch (axis) {
    21132111        case 0: axisPtr = &NanoVis::grid->xAxis; break;
     
    21152113        case 2: axisPtr = &NanoVis::grid->zAxis; break;
    21162114        }
    2117         axisPtr->name(Tcl_GetString(objv[3]));
     2115        axisPtr->title(Tcl_GetString(objv[3]));
    21182116        axisPtr->units(Tcl_GetString(objv[4]));
    21192117    }
  • nanovis/trunk/Grid.cpp

    r4902 r5478  
    4343{
    4444    bboxMin.set(xAxis.min(), yAxis.min(), zAxis.min());
    45     bboxMax.set(xAxis.min() + xAxis.range(),
    46                 yAxis.min() + yAxis.range(),
    47                 zAxis.min() + zAxis.range());
     45    bboxMax.set(xAxis.max(), yAxis.max(), zAxis.max());
    4846}
    4947
     
    6765    glPushMatrix();
    6866
    69     double xLen = xAxis.range();
    70     double yLen = yAxis.range();
    71     double zLen = zAxis.range();
     67    double xLen = xAxis.length();
     68    double yLen = yAxis.length();
     69    double zLen = zAxis.length();
    7270    double avgLen = 0.;
    7371    double denom = 0.;
     
    123121    glBegin(GL_LINES);
    124122    {
    125         bool result;
    126         TickIter iter;
    127 
    128         for (result = xAxis.firstMajor(iter); result; result = iter.next()) {
    129             float x;
    130             x = xAxis.map(iter.getValue());
     123        Ticks::ConstIterator itr;
     124        for (itr = xAxis.firstMajor(); itr != xAxis.lastMajor(); ++itr) {
     125            float x = (float)xAxis.map(*itr);
    131126            glVertex3f(x, 0.0f, 0.0f);
    132127            glVertex3f(x, 1.0f, 0.0f);
     
    134129            glVertex3f(x, 0.0f, 1.0f + zTickLen);
    135130        }
    136         for (result = yAxis.firstMajor(iter); result; result = iter.next()) {
    137             float y;
    138             y = yAxis.map(iter.getValue());
     131        for (itr = yAxis.firstMajor(); itr != yAxis.lastMajor(); ++itr) {
     132            float y = (float)yAxis.map(*itr);
    139133            glVertex3f(0.0f, y, 0.0f);
    140134            glVertex3f(1.0f + xTickLen, y, 0.0f);
     
    142136            glVertex3f(0.0f, y, 1.0f);
    143137        }
    144         for (result = zAxis.firstMajor(iter); result; result = iter.next()) {
    145             float z;
    146             z = zAxis.map(iter.getValue());
     138        for (itr = zAxis.firstMajor(); itr != zAxis.lastMajor(); ++itr) {
     139            float z = (float)zAxis.map(*itr);
    147140            glVertex3f(0.0f, 0.0f, z);
    148141            glVertex3f(0.0f, 1.0f, z);
     
    159152    glBegin(GL_LINES);
    160153    {
    161         bool result;
    162         TickIter iter;
    163 
    164         for (result = xAxis.firstMinor(iter); result; result = iter.next()) {
    165             float x;
    166             x = xAxis.map(iter.getValue());
     154        Ticks::ConstIterator itr;
     155        for (itr = xAxis.firstMinor(); itr != xAxis.lastMinor(); ++itr) {
     156            float x = (float)xAxis.map(*itr);
    167157            glVertex3f(x, 0.0f, 0.0f);
    168158            glVertex3f(x, 1.0f, 0.0f);
     
    170160            glVertex3f(x, 0.0f, 1.0f);
    171161        }
    172         for (result = yAxis.firstMinor(iter); result; result = iter.next()) {
    173             float y;
    174             y = yAxis.map(iter.getValue());
     162        for (itr = yAxis.firstMinor(); itr != yAxis.lastMinor(); ++itr) {
     163            float y = (float)yAxis.map(*itr);
    175164            glVertex3f(0.0f, y, 0.0f);
    176165            glVertex3f(1.0f, y, 0.0f);
     
    178167            glVertex3f(0.0f, y, 1.0f);
    179168        }
    180         for (result = zAxis.firstMinor(iter); result; result = iter.next()) {
    181             float z;
    182             z = zAxis.map(iter.getValue());
     169        for (itr = zAxis.firstMinor(); itr != zAxis.lastMinor(); ++itr) {
     170            float z = (float)zAxis.map(*itr);
    183171            glVertex3f(0.0f, 0.0f, z);
    184172            glVertex3f(0.0f, 1.0f, z);
     
    193181        int viewport[4];
    194182        double wx, wy, wz;
    195         bool result;
    196         TickIter iter;
    197183
    198184        glGetDoublev(GL_MODELVIEW_MATRIX, mv);
     
    211197            glLoadIdentity();
    212198            glTranslatef((int) wx, viewport[3] - (int) wy, 0);
    213             const char *name = xAxis.name();
    214             if (name == NULL) {
    215                 name = "???";
    216             }
    217             _font->draw(name);
     199            const char *title = xAxis.title();
     200            if (title == NULL) {
     201                title = "???";
     202            }
     203            _font->draw(title);
    218204        }
    219205       
     
    224210            glLoadIdentity();
    225211            glTranslatef((int) wx, viewport[3] - (int)wy, 0);
    226             const char *name = yAxis.name();
    227             if (name == NULL) {
    228                 name = "???";
    229             }
    230             _font->draw(name);
     212            const char *title = yAxis.title();
     213            if (title == NULL) {
     214                title = "???";
     215            }
     216            _font->draw(title);
    231217        }
    232218       
     
    237223            glLoadIdentity();
    238224            glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f);
    239             const char *name = zAxis.name();
    240             if (name == NULL) {
    241                 name = "???";
    242             }
    243             _font->draw(name);
     225            const char *title = zAxis.title();
     226            if (title == NULL) {
     227                title = "???";
     228            }
     229            _font->draw(title);
    244230        }
    245231
     
    247233                  _majorColor.a);
    248234
    249         for (result = xAxis.firstMajor(iter); result; result = iter.next()) {
    250             float x;
    251             x = xAxis.map(iter.getValue());
     235        Ticks::ConstIterator itr;
     236        for (itr = xAxis.firstMajor(); itr != xAxis.lastMajor(); ++itr) {
     237            float x = (float)xAxis.map(*itr);
    252238            if (gluProject(x, 0.0f, 1.0 + zLabelOfs,
    253239                           mv, prjm, viewport,
     
    257243                glLoadIdentity();
    258244                glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f);
    259                 sprintf(buff, "%.*g", NUMDIGITS, iter.getValue());
     245                sprintf(buff, "%.*g", NUMDIGITS, *itr);
    260246                _font->draw(buff);
    261247            }
    262248        }
    263         for (result = yAxis.firstMajor(iter); result; result = iter.next()) {
    264             float y;
    265             y = yAxis.map(iter.getValue());
     249        for (itr = yAxis.firstMajor(); itr != yAxis.lastMajor(); ++itr) {
     250            float y = (float)yAxis.map(*itr);
    266251            if (gluProject(1.0 + xLabelOfs, y, 0.0f,
    267252                           mv, prjm, viewport,
     
    271256                glLoadIdentity();
    272257                glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f);
    273                 sprintf(buff, "%.*g", NUMDIGITS, iter.getValue());
     258                sprintf(buff, "%.*g", NUMDIGITS, *itr);
    274259                _font->draw(buff);
    275260            }
    276261        }
    277         for (result = zAxis.firstMajor(iter); result; result = iter.next()) {
    278             float z;
    279             z = zAxis.map(iter.getValue());
     262        for (itr = zAxis.firstMajor(); itr != zAxis.lastMajor(); ++itr) {
     263            float z = (float)zAxis.map(*itr);
    280264            if (gluProject(1.0 + xLabelOfs, 0.0f, z,
    281265                           mv, prjm, viewport,
     
    285269                glLoadIdentity();
    286270                glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f);
    287                 sprintf(buff, "%.*g", NUMDIGITS, iter.getValue());
     271                sprintf(buff, "%.*g", NUMDIGITS, *itr);
    288272                _font->draw(buff);
    289273            }
  • nanovis/trunk/HeightMap.cpp

    r3630 r5478  
    88#include <GL/glew.h>
    99
     10#include <vrmath/BBox.h>
    1011#include <graphics/RenderContext.h>
    1112
     
    432433    reset();
    433434
     435    BBox bbox;
     436    grid->getBounds(bbox.min, bbox.max);
     437
     438    float xScale = 1.0 / (bbox.max.x - bbox.min.x);
     439    float yScale = 1.0 / (bbox.max.y - bbox.min.y);
     440    float zScale = 1.0 / (bbox.max.z - bbox.min.z);
     441
    434442    // The range of the grid's y-axis 0..1 represents the distance between the
    435443    // smallest and largest major ticks for all surfaces plotted.  Translate
    436444    // this surface's y-values (heights) into the grid's axis coordinates.
    437445
    438     float yScale = 1.0 / (grid->yAxis.max() - grid->yAxis.min());
    439446    float *p, *q, *pend;
    440447    float *normHeights = new float[count];
    441448    for (p = _heights, pend = p + count, q = normHeights; p < pend; p++, q++) {
    442         *q = (*p - grid->yAxis.min()) * yScale;
     449        *q = (*p - bbox.min.y) * yScale;
    443450    }
    444451    Vector3f *t, *texcoord;
     
    450457    // Normalize the mesh coordinates (x and z min/max) the range of the major
    451458    // ticks for the x and z grid axes as well.
    452 
    453     float xScale, zScale;
    454459    float xMin, xMax, zMin, zMax;
    455460
    456     xScale = 1.0 / (grid->xAxis.max() - grid->xAxis.min());
    457     xMin = (xAxis.min() - grid->xAxis.min()) * xScale;
    458     xMax = (xAxis.max() - grid->xAxis.min()) * xScale;
    459     zScale = 1.0 / (grid->zAxis.max() - grid->zAxis.min());
    460     zMin = (zAxis.min() - grid->zAxis.min()) * zScale;
    461     zMax = (zAxis.max() - grid->zAxis.min()) * zScale;
     461    xMin = (xAxis.min() - bbox.min.x) * xScale;
     462    xMax = (xAxis.max() - bbox.min.x) * xScale;
     463    zMin = (zAxis.min() - bbox.min.z) * zScale;
     464    zMax = (zAxis.max() - bbox.min.z) * zScale;
    462465
    463466    Vector3f* vertices;
  • nanovis/trunk/Makefile.in

    r5048 r5478  
    158158                BMPWriter.o \
    159159                Camera.o \
    160                 Chain.o \
    161160                CmdProc.o \
    162161                ColorTableShader.o \
     
    335334        $(RM) Makefile nvconf.h *~
    336335
    337 Axis.o: Axis.cpp Axis.h Chain.h
     336Axis.o: Axis.cpp Axis.h
    338337BMPWriter.o: BMPWriter.cpp BMPWriter.h nanovis.h
    339338BucketSort.o: BucketSort.cpp BucketSort.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h PCASplit.h
    340339Camera.o: Camera.cpp Camera.h config.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h
    341 Chain.o: Chain.cpp Chain.h
    342340CmdProc.o: CmdProc.cpp CmdProc.h
    343341ColorTableShader.o: ColorTableShader.cpp ColorTableShader.h Shader.h
     
    351349FlowParticles.o: FlowParticles.cpp FlowParticles.h FlowTypes.h FlowCmd.h Switch.h Trace.h ParticleRenderer.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h
    352350GradientFilter.o: GradientFilter.cpp GradientFilter.h
    353 Grid.o: Grid.cpp Grid.h Axis.h Chain.h $(UTIL_DIR)/Fonts.h $(VRMATH_DIR)/include/vrmath/Color4f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h
     351Grid.o: Grid.cpp Grid.h Axis.h $(UTIL_DIR)/Fonts.h $(VRMATH_DIR)/include/vrmath/Color4f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h
    354352HeightMap.o: HeightMap.cpp HeightMap.h Shader.h
    355353LIC.o: LIC.cpp LIC.h FlowTypes.h Shader.h define.h
     
    394392dxReader.o: dxReader.cpp ReaderCommon.h config.h nanovis.h Unirect.h ZincBlendeVolume.h ZincBlendeReconstructor.h
    395393md5.o: md5.h
    396 nanovis.o: nanovis.cpp nanovis.h nanovisServer.h config.h define.h Command.h Flow.h Grid.h HeightMap.h Camera.h LIC.h ZincBlendeReconstructor.h OrientationIndicator.h PerfQuery.h PlaneRenderer.h PointSetRenderer.h PointSet.h Switch.h Trace.h Unirect.h VelocityArrowsSlice.h VolumeInterpolator.h VolumeRenderer.h ZincBlendeVolume.h Axis.h Chain.h $(UTIL_DIR)/Fonts.h
     394nanovis.o: nanovis.cpp nanovis.h nanovisServer.h config.h define.h Command.h Flow.h Grid.h HeightMap.h Camera.h LIC.h ZincBlendeReconstructor.h OrientationIndicator.h PerfQuery.h PlaneRenderer.h PointSetRenderer.h PointSet.h Switch.h Trace.h Unirect.h VelocityArrowsSlice.h VolumeInterpolator.h VolumeRenderer.h ZincBlendeVolume.h Axis.h $(UTIL_DIR)/Fonts.h
    397395nanovisServer.o: nanovisServer.cpp nanovisServer.h config.h nanovis.h define.h Command.h PPMWriter.h ReadBuffer.h Shader.h ResponseQueue.h Trace.h
  • nanovis/trunk/nanovis.cpp

    r4949 r5478  
    709709
    710710    if (!sceneBounds.isEmptyX()) {
    711         grid->xAxis.setScale(sceneBounds.min.x, sceneBounds.max.x);
     711        grid->xAxis.setRange(sceneBounds.min.x, sceneBounds.max.x);
    712712    }
    713713    if (!sceneBounds.isEmptyY()) {
    714         grid->yAxis.setScale(sceneBounds.min.y, sceneBounds.max.y);
     714        grid->yAxis.setRange(sceneBounds.min.y, sceneBounds.max.y);
    715715    }
    716716    if (!sceneBounds.isEmptyZ()) {
    717         grid->zAxis.setScale(sceneBounds.min.z, sceneBounds.max.z);
     717        grid->zAxis.setRange(sceneBounds.min.z, sceneBounds.max.z);
    718718    }
    719719
Note: See TracChangeset for help on using the changeset viewer.