Using code from question about picking nice rule/marker interval I created a code that renders rules on the graph.
It has nice intervals of 0.1
. But I don't like to display all the numbers, instead, I'd like to increase rule density but only mark every few rules. Like this:
I created an algorithm that does so by multiplying rule interval by a number, then highlighting rules that can be divided by the result. I use fmod
because the values can of course be float:
// See https://stackoverflow.com/q/361681/607407 for algorithms
double rule_spacing = tickSpacing(pixels_per_rule);
// These are the highlighted rules - currently it should be every 2nd rule
double important_steps = rule_spacing*2.0;
// Getting the stard draw offset which should be bellow bottom graph corner
double start = graph_math::roundTo(begin.y, rule_spacing);
LOGMTRTTIINFO("Legend from "<<start<<" to "<<values.maxYValue<<" by "<<rule_spacing<<", numbers: "<<important_steps<<'\n');
//Loop until on top
while(start<=values.maxYValue) {
int y = pixelForYValue(start);
// HERE: calculating whether this is the NTH rule!
float remainder = fmod(start, important_steps);
LOGMTRTTIINFO(" "<<" legend at px"<<y<<" with marker "<<start<<" Marker remainder:"<<remainder<<'\n');
if(remainder==0) {
// Draw highlighted rule
}
else {
// Draw normal rule
}
}
The problem is that fmod
is rather unreliable. Check this log output where values that can be divided by 0.1
return 0.1
in fmod
:
Legend from 95.9 to 96.3097 by 0.05, numbers (important_steps): 0.1
legend at px240 with marker 95.9 Marker remainder:3.60822e-16
legend at px211 with marker 95.95 Marker remainder:0.05
legend at px181 with marker 96 Marker remainder:0.1
legend at px152 with marker 96.05 Marker remainder:0.05
legend at px123 with marker 96.1 Marker remainder:0.1
legend at px93 with marker 96.15 Marker remainder:0.05
legend at px64 with marker 96.2 Marker remainder:0.1
legend at px35 with marker 96.25 Marker remainder:0.05
legend at px5 with marker 96.3 Marker remainder:0.1
I guess I could outsmart this by adding important_steps==remainder
, but isn't the function flawed if it actually returns the denominator, which should never happen for %
(modulo)?
How do I overcome this with sufficient certainty? Testing snippet available.
Btw, this is how nicely it works once the important_steps
is greater or equal to 1
: