Changeset 5478
- Timestamp:
- May 9, 2015 2:56:07 AM (9 years ago)
- Location:
- nanovis/trunk
- Files:
-
- 2 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
nanovis/trunk/Axis.cpp
r3611 r5478 3 3 * Copyright (c) 2004-2013 HUBzero Foundation, LLC 4 4 * 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 7 11 #include <stdlib.h> 8 12 #include <stdio.h> … … 12 16 13 17 #include "Axis.h" 18 #include "Trace.h" 14 19 15 20 using namespace nv; 16 17 inline bool DEFINED(double x) {18 return !isnan(x);19 }20 21 21 22 inline double EXP10(double x) { … … 85 86 _numTicks = 0; 86 87 _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); 115 93 } 116 94 _numTicks = _nSteps; 117 95 } 118 96 119 Axis::Axis(const char * axisName) :120 _ name(strdup(axisName)),121 _ flags(AUTOSCALE),122 _ti tle(NULL),123 _ units(NULL),97 Axis::Axis(const char *title) : 98 _title(title), 99 _tightMin(false), 100 _tightMax(false), 101 _reqStep(0.0), 124 102 _valueMin(DBL_MAX), 125 103 _valueMax(-DBL_MAX), 126 _reqMin(NAN),127 _reqMax(NAN),128 104 _min(DBL_MAX), 129 105 _max(-DBL_MAX), 130 _range(0.0),131 _scale(0.0),132 _reqStep(0.0),133 106 _major(5), 134 107 _minor(2) … … 140 113 * 141 114 * 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 compared115 * value is between [0.0,1.0] then it's in range. The value is compared 143 116 * to 0 and 1., where 0.0 is the minimum and 1.0 is the maximum. 144 117 * DBL_EPSILON is the smallest number that can be represented on the host … … 147 120 * Please note, *max* can't equal *min*. 148 121 * 149 * \return If the value is within the interval [min ..max], 1 is returned; 0122 * \return If the value is within the interval [min,max], 1 is returned; 0 150 123 * otherwise. 151 124 */ … … 153 126 Axis::inRange(double x) 154 127 { 155 if ( _range< DBL_EPSILON) {128 if ((_max - _min) < DBL_EPSILON) { 156 129 return (fabs(_max - x) >= DBL_EPSILON); 157 130 } else { 158 x = (x - _min) * _scale;131 x = map(x); 159 132 return ((x >= -DBL_EPSILON) && ((x - 1.0) < DBL_EPSILON)); 160 133 } … … 165 138 { 166 139 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; 172 141 } 173 142 if (max == -DBL_MAX) { 174 if (DEFINED(_reqMax)) { 175 max = _reqMax; 176 } else { 177 max = 1.0; 178 } 143 max = 1.0; 179 144 } 180 145 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 185 147 if (min == 0.0) { 186 148 min = 0.0, max = 1.0; … … 190 152 } 191 153 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 * 247 179 * <pre> 248 180 * maxY … … 268 200 * minY 269 201 * 270 * numTicks = Number of ticks271 * min = Minimum value of axis272 * max = Maximum value of axis273 * range = Range of values (max - min)274 *275 * </pre>276 *277 * If the number of decades is greater than ten, it is assumed278 * that the full set of log-style ticks can't be drawn properly.279 */280 void281 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 every304 * 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 pass324 * information to the SetTicks325 * method. An interval of 0.0 indicates326 * 1) this is a minor sweep and327 * 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 mapped351 * to the axis (autoscaled), or the values specified by the -min352 * and -max options (manual).353 *354 * If autoscaled, the smallest and largest major ticks will355 * encompass the range of data values. If the -loose option is356 * selected, the next outer ticks are choosen. If tight, the357 * ticks are at or inside of the data limits are used.358 *359 * If manually set, the ticks are at or inside the data limits360 * are used. This makes sense for zooming. You want the361 * selected range to represent the next limit, not something a362 * bit bigger.363 *364 * Note: I added an "always" value to the -loose option to force365 * the manually selected axes to be loose. It's probably366 * not a good idea.367 *368 * <pre>369 * maxY370 * | units = magnitude (of least significant digit)371 * | high = largest unit tick < max axis value372 * high _| low = smallest unit tick > min axis value373 * |374 * | range = high - low375 * | # ticks = greatest factor of range/units376 * _|377 * U |378 * n |379 * i |380 * t _|381 * |382 * |383 * |384 * low _|385 * |386 * |_minX________________maxX__387 * | | | | |388 * minY low high389 * minY390 *391 202 * numTicks = Number of ticks 392 203 * min = Minimum value of axis … … 403 214 Axis::linearScale() 404 215 { 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 413 220 if (_valueMin < _valueMax) { 414 double range; 415 416 range = _valueMax - _valueMin; 221 double range = _valueMax - _valueMin; 417 222 /* Calculate the major tick stepping. */ 418 223 if (_reqStep > 0.0) { … … 439 244 * The limits of the axis are either the range of the data ("tight") or at 440 245 * 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. 445 247 */ 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; 450 250 451 251 /* Now calculate the minor tick step and number. */ 452 252 453 if ( (_minor.reqNumTicks > 0) && (_minor.autoscale())) {253 if (_minor.reqNumTicks > 0) { 454 254 nTicks = _minor.reqNumTicks - 1; 455 255 step = 1.0 / (nTicks + 1); … … 463 263 } 464 264 465 265 /** 266 * \brief This sets the data range of the axis. 267 */ 466 268 void 467 Axis::setScale(double min, double max) 468 { 269 Axis::setRange(double min, double max) 270 { 271 // set valueMin/Max (overridden by requested min/max if present) 469 272 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 475 276 _major.sweepTicks(); 476 277 _minor.sweepTicks(); 278 // Copy to linked lists 477 279 makeTicks(); 478 280 } 479 281 282 /** 283 * \brief Copy tick values to major/minor linked lists, skipping duplicate values 284 */ 480 285 void 481 286 Axis::makeTicks() … … 483 288 _major.reset(); 484 289 _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); 491 292 /* 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)); 494 295 if (!inRange(t2)) { 495 296 continue; … … 507 308 } 508 309 310 /** 311 * \brief Map world coordinate [_min,_max] to normalized coordinate [0,1] 312 */ 509 313 double 510 314 Axis::map(double x) 511 315 { 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); 520 317 return x; 521 318 } 522 319 320 /** 321 * \brief Map normalized coordinate [0,1] to world coordinate [_min,_max] 322 */ 523 323 double 524 324 Axis::invMap(double x) 525 325 { 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; 533 327 return x; 534 328 } -
nanovis/trunk/Axis.h
r3630 r5478 3 3 * Copyright (c) 2004-2013 HUBzero Foundation, LLC 4 4 * 5 * Authors: George A. Howlett <gah@purdue.edu> 5 * Authors: 6 * George A. Howlett <gah@purdue.edu> 7 * Leif Delgass <ldelgass@purdue.edu> 6 8 */ 7 9 #ifndef NV_AXIS_H 8 10 #define NV_AXIS_H 9 11 10 #include <stdlib.h>11 #include <string.h>12 13 12 #include <cmath> 14 13 #include <limits> 15 16 #include "Chain.h" 14 #include <list> 15 #include <string> 16 #include <cstdlib> 17 #include <cstring> 17 18 18 19 #ifndef NAN … … 23 24 24 25 class Axis; 25 26 class TickIter27 {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 };56 26 57 27 /** … … 62 32 { 63 33 public: 34 typedef std::list<double>::iterator Iterator; 35 typedef std::list<double>::const_iterator ConstIterator; 36 64 37 Ticks(int numTicks) : 65 38 reqNumTicks(numTicks), 66 _autoscale(true),67 39 _numTicks(0), 68 40 _ticks(NULL) … … 75 47 delete [] _ticks; 76 48 } 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 86 52 { 87 53 return _numTicks; … … 98 64 void reset() 99 65 { 100 _chain. reset();101 } 102 103 float step() 66 _chain.clear(); 67 } 68 69 float step() const 104 70 { 105 71 return _step; 106 72 } 107 73 108 void append 109 { 110 _chain. append(getClientData(x));74 void append(float x) 75 { 76 _chain.push_back(x); 111 77 } 112 78 … … 116 82 } 117 83 118 bool autoscale()119 {120 return _autoscale;121 }122 123 84 void sweepTicks() 124 85 { 125 if (_autoscale) { 126 if (_ticks != NULL) { 127 delete [] _ticks; 128 } 129 setTicks(); 86 if (_ticks != NULL) { 87 delete [] _ticks; 130 88 } 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(); 140 100 } 141 101 … … 144 104 private: 145 105 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. */ 156 107 157 108 bool _autoscale; /**< Indicates if the ticks are autoscaled. */ … … 182 133 * the chain. 183 134 */ 184 Chain_chain;135 std::list<double> _chain; 185 136 }; 186 137 … … 192 143 { 193 144 public: 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); 204 146 205 147 ~Axis() 206 148 { 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 245 private: 228 246 void resetRange(); 229 247 230 248 void fixRange(double min, double max); 231 249 232 void setScale(double min, double max);233 234 double scale() const235 {236 return _scale;237 }238 239 double range() const240 {241 return _range;242 }243 244 double dataMin() const245 {246 return _valueMin;247 }248 249 double dataMax() const250 {251 return _valueMax;252 }253 254 double min() const255 {256 return _min;257 }258 259 double max() const260 {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 371 250 void linearScale(); 372 251 … … 375 254 void makeTicks(); 376 255 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 */ 395 268 double _min, _max; /**< Smallest and largest major tick values for 396 269 * the axis. If loose, the tick values lie … … 399 272 * the data. */ 400 273 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 tick405 * interval. Otherwise a stepsize is406 * automatically calculated, based upon the407 * range of elements mapped to the axis. The408 * default value is 0.0. */409 410 274 Ticks _major, _minor; 411 275 }; -
nanovis/trunk/Command.cpp
r5303 r5478 2107 2107 } 2108 2108 if (NanoVis::grid != NULL) { 2109 Axis *axisPtr; 2110 2111 axisPtr = NULL; /* Suppress compiler warning. */ 2109 Axis *axisPtr = NULL; 2112 2110 switch (axis) { 2113 2111 case 0: axisPtr = &NanoVis::grid->xAxis; break; … … 2115 2113 case 2: axisPtr = &NanoVis::grid->zAxis; break; 2116 2114 } 2117 axisPtr-> name(Tcl_GetString(objv[3]));2115 axisPtr->title(Tcl_GetString(objv[3])); 2118 2116 axisPtr->units(Tcl_GetString(objv[4])); 2119 2117 } -
nanovis/trunk/Grid.cpp
r4902 r5478 43 43 { 44 44 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()); 48 46 } 49 47 … … 67 65 glPushMatrix(); 68 66 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(); 72 70 double avgLen = 0.; 73 71 double denom = 0.; … … 123 121 glBegin(GL_LINES); 124 122 { 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); 131 126 glVertex3f(x, 0.0f, 0.0f); 132 127 glVertex3f(x, 1.0f, 0.0f); … … 134 129 glVertex3f(x, 0.0f, 1.0f + zTickLen); 135 130 } 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); 139 133 glVertex3f(0.0f, y, 0.0f); 140 134 glVertex3f(1.0f + xTickLen, y, 0.0f); … … 142 136 glVertex3f(0.0f, y, 1.0f); 143 137 } 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); 147 140 glVertex3f(0.0f, 0.0f, z); 148 141 glVertex3f(0.0f, 1.0f, z); … … 159 152 glBegin(GL_LINES); 160 153 { 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); 167 157 glVertex3f(x, 0.0f, 0.0f); 168 158 glVertex3f(x, 1.0f, 0.0f); … … 170 160 glVertex3f(x, 0.0f, 1.0f); 171 161 } 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); 175 164 glVertex3f(0.0f, y, 0.0f); 176 165 glVertex3f(1.0f, y, 0.0f); … … 178 167 glVertex3f(0.0f, y, 1.0f); 179 168 } 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); 183 171 glVertex3f(0.0f, 0.0f, z); 184 172 glVertex3f(0.0f, 1.0f, z); … … 193 181 int viewport[4]; 194 182 double wx, wy, wz; 195 bool result;196 TickIter iter;197 183 198 184 glGetDoublev(GL_MODELVIEW_MATRIX, mv); … … 211 197 glLoadIdentity(); 212 198 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); 218 204 } 219 205 … … 224 210 glLoadIdentity(); 225 211 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); 231 217 } 232 218 … … 237 223 glLoadIdentity(); 238 224 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); 244 230 } 245 231 … … 247 233 _majorColor.a); 248 234 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); 252 238 if (gluProject(x, 0.0f, 1.0 + zLabelOfs, 253 239 mv, prjm, viewport, … … 257 243 glLoadIdentity(); 258 244 glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f); 259 sprintf(buff, "%.*g", NUMDIGITS, iter.getValue());245 sprintf(buff, "%.*g", NUMDIGITS, *itr); 260 246 _font->draw(buff); 261 247 } 262 248 } 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); 266 251 if (gluProject(1.0 + xLabelOfs, y, 0.0f, 267 252 mv, prjm, viewport, … … 271 256 glLoadIdentity(); 272 257 glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f); 273 sprintf(buff, "%.*g", NUMDIGITS, iter.getValue());258 sprintf(buff, "%.*g", NUMDIGITS, *itr); 274 259 _font->draw(buff); 275 260 } 276 261 } 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); 280 264 if (gluProject(1.0 + xLabelOfs, 0.0f, z, 281 265 mv, prjm, viewport, … … 285 269 glLoadIdentity(); 286 270 glTranslatef((int) wx, (int) viewport[3] - (int)wy, 0.0f); 287 sprintf(buff, "%.*g", NUMDIGITS, iter.getValue());271 sprintf(buff, "%.*g", NUMDIGITS, *itr); 288 272 _font->draw(buff); 289 273 } -
nanovis/trunk/HeightMap.cpp
r3630 r5478 8 8 #include <GL/glew.h> 9 9 10 #include <vrmath/BBox.h> 10 11 #include <graphics/RenderContext.h> 11 12 … … 432 433 reset(); 433 434 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 434 442 // The range of the grid's y-axis 0..1 represents the distance between the 435 443 // smallest and largest major ticks for all surfaces plotted. Translate 436 444 // this surface's y-values (heights) into the grid's axis coordinates. 437 445 438 float yScale = 1.0 / (grid->yAxis.max() - grid->yAxis.min());439 446 float *p, *q, *pend; 440 447 float *normHeights = new float[count]; 441 448 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; 443 450 } 444 451 Vector3f *t, *texcoord; … … 450 457 // Normalize the mesh coordinates (x and z min/max) the range of the major 451 458 // ticks for the x and z grid axes as well. 452 453 float xScale, zScale;454 459 float xMin, xMax, zMin, zMax; 455 460 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; 462 465 463 466 Vector3f* vertices; -
nanovis/trunk/Makefile.in
r5048 r5478 158 158 BMPWriter.o \ 159 159 Camera.o \ 160 Chain.o \161 160 CmdProc.o \ 162 161 ColorTableShader.o \ … … 335 334 $(RM) Makefile nvconf.h *~ 336 335 337 Axis.o: Axis.cpp Axis.h Chain.h336 Axis.o: Axis.cpp Axis.h 338 337 BMPWriter.o: BMPWriter.cpp BMPWriter.h nanovis.h 339 338 BucketSort.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 340 339 Camera.o: Camera.cpp Camera.h config.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h 341 Chain.o: Chain.cpp Chain.h342 340 CmdProc.o: CmdProc.cpp CmdProc.h 343 341 ColorTableShader.o: ColorTableShader.cpp ColorTableShader.h Shader.h … … 351 349 FlowParticles.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 352 350 GradientFilter.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.h351 Grid.o: Grid.cpp Grid.h Axis.h $(UTIL_DIR)/Fonts.h $(VRMATH_DIR)/include/vrmath/Color4f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h 354 352 HeightMap.o: HeightMap.cpp HeightMap.h Shader.h 355 353 LIC.o: LIC.cpp LIC.h FlowTypes.h Shader.h define.h … … 394 392 dxReader.o: dxReader.cpp ReaderCommon.h config.h nanovis.h Unirect.h ZincBlendeVolume.h ZincBlendeReconstructor.h 395 393 md5.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.h394 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 $(UTIL_DIR)/Fonts.h 397 395 nanovisServer.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 709 709 710 710 if (!sceneBounds.isEmptyX()) { 711 grid->xAxis.set Scale(sceneBounds.min.x, sceneBounds.max.x);711 grid->xAxis.setRange(sceneBounds.min.x, sceneBounds.max.x); 712 712 } 713 713 if (!sceneBounds.isEmptyY()) { 714 grid->yAxis.set Scale(sceneBounds.min.y, sceneBounds.max.y);714 grid->yAxis.setRange(sceneBounds.min.y, sceneBounds.max.y); 715 715 } 716 716 if (!sceneBounds.isEmptyZ()) { 717 grid->zAxis.set Scale(sceneBounds.min.z, sceneBounds.max.z);717 grid->zAxis.setRange(sceneBounds.min.z, sceneBounds.max.z); 718 718 } 719 719
Note: See TracChangeset
for help on using the changeset viewer.