File: numerictickset.h

package info (click to toggle)
aoflagger 3.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,000 kB
  • sloc: cpp: 67,891; python: 497; sh: 242; makefile: 22
file content (126 lines) | stat: -rw-r--r-- 3,260 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#ifndef NUMERIC_TICK_SET_H
#define NUMERIC_TICK_SET_H

#include "tickset.h"

#include <vector>
#include <cmath>
#include <sstream>

class NumericTickSet final : public TickSet {
 public:
  NumericTickSet(double min, double max, unsigned size_request, bool is_integer)
      : min_(min),
        max_(max),
        size_request_(size_request),
        is_integer_(is_integer) {
    set(size_request);
  }

  std::unique_ptr<TickSet> Clone() const override {
    return std::make_unique<NumericTickSet>(*this);
  }

  size_t Size() const override { return ticks_.size(); }

  Tick GetTick(size_t i) const override {
    std::stringstream tickStr;
    tickStr << ticks_[i];
    if (max_ - min_ == 0.0)
      return Tick(0.5, tickStr.str());
    else
      return Tick((ticks_[i] - min_) / (max_ - min_), tickStr.str());
  }

  void Reset() override {
    ticks_.clear();
    set(size_request_);
  }

  void Set(size_t maxSize) override {
    ticks_.clear();
    set(maxSize);
  }
  double UnitToAxis(double unitValue) const override {
    return (min_ == max_) ? 0.0 : (unitValue - min_) / (max_ - min_);
  }
  double AxisToUnit(double axisValue) const override {
    return axisValue * (max_ - min_) + min_;
  }

 private:
  friend std::unique_ptr<NumericTickSet> std::make_unique<NumericTickSet>(
      const NumericTickSet&);

  void set(size_t size_request) {
    if (std::isfinite(min_) && std::isfinite(max_)) {
      if (max_ == min_) {
        ticks_.push_back(min_);
      } else {
        if (size_request == 0) return;
        double tickWidth =
            RoundUpToNiceNumber(std::fabs(max_ - min_) / (double)size_request);
        if (is_integer_ && tickWidth < 1.0) tickWidth = 1.0;
        if (tickWidth == 0.0) tickWidth = 1.0;
        if (min_ < max_) {
          double pos = RoundUpToNiceNumber(min_, tickWidth);
          while (pos <= max_) {
            if (fabs(pos) < tickWidth / 100.0)
              ticks_.push_back(0.0);
            else
              ticks_.push_back(pos);
            pos += tickWidth;
          }
        } else {
          double pos = -RoundUpToNiceNumber(-min_, tickWidth);
          while (pos >= max_) {
            if (std::fabs(pos) < tickWidth / 100.0)
              ticks_.push_back(0.0);
            else
              ticks_.push_back(pos);
            pos -= tickWidth;
          }
        }
        while (ticks_.size() > size_request) ticks_.pop_back();
      }
    }
  }

  double RoundUpToNiceNumber(double number) {
    if (!std::isfinite(number)) return number;
    double roundedNumber = 1.0;
    if (number <= 0.0) {
      if (number == 0.0) {
        return 0.0;
      } else {
        roundedNumber = -1.0;
        number *= -1.0;
      }
    }
    while (number > 10) {
      number /= 10;
      roundedNumber *= 10;
    }
    while (number <= 1) {
      number *= 10;
      roundedNumber /= 10;
    }
    if (number <= 2)
      return roundedNumber * 2;
    else if (number <= 5)
      return roundedNumber * 5;
    else
      return roundedNumber * 10;
  }
  double RoundUpToNiceNumber(double number, double roundUnit) {
    return roundUnit * ceil(number / roundUnit);
  }

  double min_;
  double max_;
  size_t size_request_;
  bool is_integer_;
  std::vector<double> ticks_;
};

#endif