cgv
Loading...
Searching...
No Matches
axis_config.cxx
1#include "axis_config.h"
2
3namespace cgv {
4 namespace plot {
5
8{
9 return length == tc.length && step == tc.step && type == tc.type && label == tc.label && precision == tc.precision;
10}
11
14{
15 step = primary ? 5.0f : 1.0f;
16 type = primary ? TT_LINE : TT_DASH;
17 line_width = primary ? 1.5f : 1.0f;
18 length = primary ? 12.0f : 8.0f;
19 label = primary;
20 precision = -1;
21}
22
23void axis_config::update_tick_range()
24{
29}
30
31void axis_config::set_attribute_range(float _min, float _max)
32{
35 update_tick_range();
36}
37
40{
41 min_attribute_value_backup = min_attribute_value;
42 max_attribute_value_backup = max_attribute_value;
43}
44
46void axis_config::put_backup_attribute_range(float& min_val, float& max_val) const
47{
48 min_val = min_attribute_value_backup;
49 max_val = max_attribute_value_backup;
50}
51
54{
55 set_attribute_range(min_attribute_value_backup, max_attribute_value_backup);
56}
57
59{
61 update_tick_range();
62}
64{
66 update_tick_range();
67}
69{
70 log_scale = enabled;
71 update_tick_range();
72}
74{
75 log_minimum = _min;
76 update_tick_range();
77}
78
80void axis_config::set_log_config(bool enabled, float _min)
81{
82 log_scale = enabled;
83 log_minimum = _min;
84 update_tick_range();
85}
86
88{
89 if (!log_scale)
90 return value;
91 if (value > log_minimum)
92 return log10(value);
93 if (value < -log_minimum)
94 return 2 * log10(log_minimum) - 2 - log10(-value);
95 return log10(log_minimum) + value / log_minimum - 1;
96}
97float axis_config::attribute_space_from_tick_space(float value) const
98{
99 if (!log_scale)
100 return value;
101 if (value > log10(log_minimum))
102 return pow(10.0f, value);
103 if (value < log10(log_minimum) - 2)
104 return -pow(10.0f, 2 * log10(log_minimum) - 2 - value);
105 return log_minimum * (value + 1 - log10(log_minimum));
106}
107float axis_config::window_space_from_tick_space(float value) const
108{
109 float min_value = min_attribute_value;
110 float max_value = max_attribute_value;
111 if (log_scale) {
112 min_value = tick_space_from_attribute_space(min_value);
113 max_value = tick_space_from_attribute_space(max_value);
114 }
115 return (value - min_value) / (max_value - min_value);
116}
117float axis_config::tick_space_from_window_space(float value) const
118{
119 float min_value = min_attribute_value;
120 float max_value = max_attribute_value;
121 if (log_scale) {
122 min_value = tick_space_from_attribute_space(min_value);
123 max_value = tick_space_from_attribute_space(max_value);
124 }
125 return value* (max_value - min_value) + min_value;
126}
128{
129 return extent * (value - 0.5f);
130}
132{
133 return value / extent + 0.5f;
134}
136{
137 return plot_space_from_window_space(window_space_from_tick_space(tick_space_from_attribute_space(value)));
138}
140{
141 return attribute_space_from_tick_space(tick_space_from_window_space(window_space_from_plot_space(value)));
142}
143
144void test_axis_config()
145{
146 axis_config ac;
147 ac.set_attribute_range(-2,10);
148 ac.set_log_config(true, 0.01f);
149 float l, v = 10;
150 int i;
151 for (i = 0; i < 16; ++i) {
153 std::cout << v << " -> " << l << " -> " << ac.attribute_space_from_tick_space(l) << std::endl;
154 v *= 0.5;
155 }
156 v = 0;
158 std::cout << v << " -> " << l << " -> " << ac.attribute_space_from_tick_space(l) << std::endl;
159 v = -2;
160 for (i = 0; i < 16; ++i) {
162 std::cout << v << " -> " << l << " -> " << ac.attribute_space_from_tick_space(l) << std::endl;
163 v *= 0.5;
164 }
165}
167{
168 return log_scale == ac.log_scale && log_minimum == ac.log_minimum &&
170}
171
172axis_config::axis_config() : primary_ticks(true), secondary_ticks(false), color(0.3f,0.3f,0.3f)
173{
174 min_attribute_value = 0.0f;
175 max_attribute_value = 1.0f;
176 log_scale = false;
177 log_minimum = 1e-10f;
178 update_tick_range();
179 extent = 1.0f;
180 extent_scaling = 0.0f;
181 line_width = 3.0f;
183 multi_axis_ticks = true;
184}
186void axis_config::adjust_tick_marks_to_range(unsigned max_nr_secondary_ticks)
187{
190 float de = mx - mn;
191 float reference_step = de / max_nr_secondary_ticks;
192 float scale = (float)pow(10, -floor(log10(reference_step)));
193 primary_ticks.step = 50.0f / scale;
194 secondary_ticks.step = 10.0f / scale;
195 static float magic_numbers[9] = {
196 1.5f, 5.0f, 1.0f,
197 3.5f, 10.0f, 2.0f,
198 7.5f, 20.0f, 5.0f
199 };
200 for (unsigned i = 0; i < 9; i += 3)
201 if (scale * reference_step < magic_numbers[i]) {
202 primary_ticks.step = magic_numbers[i + 1] / scale;
203 secondary_ticks.step = magic_numbers[i + 2] / scale;
204 break;
205 }
206}
207
209{
210 bool show = p.begin_tree_node(name, color, false, "level=3;options='w=148';align=' '");
211 connect_copy(p.add_member_control(bp, "Log", log_scale, "toggle", "w=40")->value_change,
212 cgv::signal::rebind(this, &axis_config::update_tick_range));
213 if (show) {
214 p.align("\a");
215 p.add_member_control(bp, "Extent", extent, "value_slider", "min=0.1;max=10;log=true;ticks=true");
216 p.add_member_control(bp, "Extent Scaling", extent_scaling, "value_slider", "min=0;max=10;log=true;ticks=true");
217 connect_copy(p.add_member_control(bp, "Attribute Min", min_attribute_value, "value_slider", "min=-10;max=10;log=true;ticks=true")->value_change,
218 cgv::signal::rebind(this, &axis_config::update_tick_range));
219 connect_copy(p.add_member_control(bp, "Attribute Max", max_attribute_value, "value_slider", "min=-10;max=10;log=true;ticks=true")->value_change,
220 cgv::signal::rebind(this, &axis_config::update_tick_range));
221 connect_copy(p.add_member_control(bp, "Log Minimum", log_minimum, "value")->value_change,
222 cgv::signal::rebind(this, &axis_config::update_tick_range));
223 p.add_member_control(bp, "Width", line_width, "value_slider", "min=1;max=20;log=true;ticks=true");
224 p.add_member_control(bp, "Color", color);
225 connect_copy(p.add_member_control(bp, "Max 2nd Ticks", auto_adjust_max_snd_ticks, "value_slider", "min=0;max=50;log=true;ticks=true")->value_change,
226 cgv::signal::rebind(this, &axis_config::update_tick_range));
227
228 p.add_member_control(bp, "Multi Axis Ticks", multi_axis_ticks, "check");
229
230 const char* tn[2] = { "Primary Tick", "Secondary Tick" };
232 for (unsigned ti = 0; ti < 2; ++ti) {
233 bool vis = p.begin_tree_node(tn[ti], tc[ti]->label, false, "level=3;options='w=132';align=' '");
234 p.add_member_control(bp, "Label", tc[ti]->label, "toggle", "w=60");
235 if (vis) {
236 p.align("\a");
237 p.add_member_control(bp, "Type", tc[ti]->type, "dropdown", "enums='None,Dash,Line,Plane'");
238 p.add_member_control(bp, "Step", tc[ti]->step, "value");
239 p.add_member_control(bp, "Width", tc[ti]->line_width, "value_slider", "min=1;max=20;log=true;ticks=true");
240 p.add_member_control(bp, "Length", tc[ti]->length, "value_slider", "min=1;max=20;log=true;ticks=true");
241 p.add_member_control(bp, "Precision", tc[ti]->precision, "value_slider", "min=-1;max=5;ticks=true");
242 p.align("\b");
243 p.end_tree_node(tc[ti]->label);
244 }
245 }
246 p.align("\b");
248 }
249}
250
251 }
252}
base class for all classes that can be registered with support for dynamic properties (see also secti...
Definition base.h:75
derive from this class to provide a gui to the current viewer
Definition provider.h:64
void align(const std::string &_align)
send pure alignment information
Definition provider.cxx:36
bool begin_tree_node(const std::string &label, const T &value, bool initial_visibility=false, const std::string &options="", gui_group_ptr ggp=gui_group_ptr())
Begin a sub tree of a tree structured gui.
Definition provider.h:212
data::ref_ptr< control< T > > add_member_control(cgv::base::base *base_ptr, const std::string &label, T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
add control with callback to cgv::base::on_set method on cgv::gui::control::value_change
Definition provider.h:137
void end_tree_node(const T &value)
template specialization that allows to specify value reference plus node_instance by using the result...
Definition provider.h:222
configuration information stored per domain axis
Definition axis_config.h:45
unsigned auto_adjust_max_snd_ticks
maximum number of secondary ticks for auto adjustment of ticks on changes to attribute range
Definition axis_config.h:65
tick_config primary_ticks
configuration of primary tickmarks
void set_attribute_range(float _min, float _max)
write access to attribute range
void create_gui(cgv::base::base *bp, cgv::gui::provider &p)
create gui for axis
float extent
extent in world space
Definition axis_config.h:98
float log_minimum
minimum of logarithmic value in case that 0 is included in attribute range
Definition axis_config.h:63
void restore_attribute_range()
store current range from backup members
float attribute_space_from_plot_space(float value) const
convenience function
axis_config()
set default values
float extent_scaling
potential constraint for scaling of plot extent in world space
void set_log_minimum(float _min)
write access to minimum attribute value for robust log transformation
bool operator==(const axis_config &ac) const
compare members relevant for drawing geometry precomputation for equality
bool log_scale
whether axis is drawn with logarithmic scale
Definition axis_config.h:61
void set_attribute_minimum(float _min)
write access to attribute minimum value
void set_attribute_maximum(float _max)
write access to attribute maximum value
void set_log_config(bool enabled, float _min)
write access to log scale flag and minimum
float line_width
line width
float max_attribute_value
maximum attribute value
Definition axis_config.h:59
float window_space_from_plot_space(float value) const
convert from plot to window space
void backup_attribute_range()
store current range in backup members
float plot_space_from_attribute_space(float value) const
convenience function
std::string name
name of axis
Definition axis_config.h:68
float get_attribute_max() const
read access to attrbribute maximum value
Definition axis_config.h:72
float min_attribute_value
minimum attribute value
Definition axis_config.h:57
float tick_space_from_attribute_space(float value) const
perform transformation from attribute space to tick mark space by applying log transformation if acti...
void put_backup_attribute_range(float &min_val, float &max_val) const
read access to backup attribute range
rgb color
color of axis
float plot_space_from_window_space(float value) const
convert from window to plot space
void adjust_tick_marks_to_range(unsigned max_nr_secondary_ticks)
adjust tick marks to attribute range based on given maximum number of secondary ticks
void set_log_scale(bool enabled)
write access to log scale flag
tick_config secondary_ticks
configuration of secondary tickmarks
float get_attribute_min() const
read access to attrbribute minimum value
Definition axis_config.h:70
bool multi_axis_ticks
whether to show tick marks on both axes boundaries
the cgv namespace
Definition print.h:11
tickmark configuration of one tickmark type
Definition axis_config.h:24
float line_width
line width
Definition axis_config.h:30
bool label
whether to show text labels at tick
Definition axis_config.h:34
bool operator==(const tick_config &tc) const
implement equality check
tick_config(bool primary)
set tick config defaults
int precision
number of digits after decimal point, defaults to -1 which gives adaptive precision
Definition axis_config.h:36
float step
step width between two ticks along axis
Definition axis_config.h:28
float length
tick length relative to domain extent
Definition axis_config.h:32
TickType type
type of tick
Definition axis_config.h:26