使用question about picking nice rule/marker interval中的代码我创建了一个代码,用于在图表上呈现规则。
它有0.1
的间隔。但我不想显示所有数字,相反,我想增加规则密度,但只标记每一条规则。像这样:
我创建了一个算法,通过将规则间隔乘以一个数字,然后突出显示可以除以结果的规则。我使用fmod
因为值当然可以是浮点数:
// 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
}
}
问题是fmod
相当不可靠。检查此日志输出,其中可以除以0.1
的值0.1
中返回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
我想我可以通过添加important_steps==remainder
来表达这一点,但如果它实际上返回分母,那么函数是否有缺陷,%
(模数)不应该发生?
如何充分肯定地克服这个问题? Testing snippet available.
顺便说一句,important_steps
大于或等于1
后,这是多么好用:
答案 0 :(得分:0)
也许最好的方法是舍入到整数,然后检查差异,如下所示:
float quotient = start / important_step;
int quot_int = round(quotient);
if (abs(quotient - quot_int) < 1e-10)
{
// Draw highlighted rule
}
else
{
// Draw normal rule
}
编辑:圆形功能
int round(double x){return floor(x + 0.5);}