这是如此简单,我简直不敢相信我有这么多麻烦。
打个比方,我想象一个两只手的钟面,而不是12个小时,时间在0到1之间。
如果值是0到1,则两只手可以指向任何方向,例如,一只指向上,另一只指向对角向下,向左指向0和0.625。
我需要一个c++ \ C#函数,该函数给出了两只手的位置,并且一个bool表示了是否希望用两只手之间的更大或更小部分来返回两只手中间位置的位置。
例如,“0.2、0.8,false”将指两只手之间的较小部分,答案将为0。
float func(float a, float b, bool side)
{
return 0f;
}
在许多情况下,计算将简单地是“(a + b)* 0.5”,但是,如上例所示,在越过0时不是这样。它也没有像“if”那样放入单个分支那么简单。似乎应该有一个比我尝试过的解决方案优雅得多的解决方案。
编辑:我终于自己解决了这个问题,请参见下面的代码,此外,在其他各种人尝试使用Peoblem之后,找到了一个更为优雅的解决方案。
float segment_size(float a, float b, bool side)
{
float larger, smaller, c, d_smaller, d_larger;
if (a > b)
{
smaller = b;
larger = a;
}
else
{
smaller = a;
larger = b;
}
c = larger - smaller;
if (c > 0.5) {d_larger = c; d_smaller = 1 - c;} else {d_larger = 1 - c; d_smaller = c;}
return side ? d_larger : d_smaller;
}
float func(float a, float b, bool side)
{
float larger, smaller, c;
if(a > b)
{
smaller = b;
larger = a;
}
else
{
smaller = a;
larger = b;
}
c = larger - smaller;
float outf = 0, out1 = (float)((a + b) * 0.5),
out3 = (float)(smaller - (segment_size(a, b, false) * 0.5)),
out4 = (float)((smaller + larger) * 0.5);
if(out4 > 0.5) {out4 -= 0.5f;} else {out4 += 0.5f;}
if ((side == false && c <= 0.5) || (side == true && c > 0.5)) {outf = out1;}
if (side == false && c > 0.5) {outf = out3;}
if (side == true && c <= 0.5) {outf = out4;}
if(outf < 0) {outf += 1;} if(outf >= 1) {outf -= 1;}
return outf;
}
最佳答案
是的,所以我第一次就错了(计算段的长度而不是对半点),第二次也就错了(有点儿狡猾,所以最终删除了答案),但请耐心等待。
解决的办法在于我们在这里谈论一个圈子。因此,如果我们有一个减半的点,则可以通过将圆的一半周长(0.5)加上该一半而得到另一个。
假设0
if(a>b) {
hi=a;
lo=b;
} else {
hi=b;
lo=a;
}
d=hi-lo;
if( (d>0.5 && greater_segment_needed) || (d<=0.5 && !greater_segment_needed)) {
result=lo+d/2
} else
result=lo+d/2+0.5; //the marvels of geometry
}
if(result>1) result-=1; //handling possible overflow
return result;
我很确定这行得通。是的,我再次对其进行了编辑> _>