这很简单,我无法相信我遇到这么多麻烦。
对于我所想象的一个类比,想象一个双手钟面,而不是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 :(得分:2)
是的,所以我第一次弄错了(计算了段的长度而不是它的减半点),还有第二次(有点狡猾,最后删除了答案),但是忍受我。
解决方案在于我们在这里谈论一个圆圈。因此,如果我们有一个减半点,我们可以通过将圆的一半(0.5)加到那个来获得另一个。
假设0 <= a <&lt; 1,0&lt; = b&lt; 1
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;
我很确定这是有效的。是的,我再次编辑了它&gt; _&gt;
答案 1 :(得分:1)
你是对的(a + b)/ 2。但是如果结果大于0.5则指出它不是较短的部分,你必须计算零以获得它。
如果计算过零,则想象较大的数字为负数。例如,0.8是-0.2(= a-1)。并使用您建议的相同方程式。所以你的例子中的0.8和0.2看起来像(-0.2 + 0.2)/ 2 = 0 反之亦然size = true。
来源看起来像是:
float func(float a, float b, bool side)
{
float result = (a+b)/2;
if (result > 0.5)
result = (a+b-1)/2;
if (side == true)
return result;
else
return result<0.5 ? result+0.5 : result -0.5;
}
答案 2 :(得分:1)
这是我的尝试。未经测试:)
float func(float a, float b, bool side)
{
float seg_a = a - b;
if (seg_a < 0) seg_a += 1;
float seg_b = 1 - seg_a;
float result;
if (side && seg_a > 0.5 || !side && !(seg_a > 0.5))
result = b + seg_a / 2;
else
result = a + seg_b / 2;
if (result > 1) result -= 1;
return result;
}