我正在努力解决我在学位上遇到的问题。我有一个数据,它是一个角度列表,标准度表示法 - 例如26度
通常在处理角度时,如果角度超过360度,则角度继续并且有效地“重置” - 即角度“再次开始”,例如, 357度,358度,359度,0度,1度等。我想要发生的是继续增加的程度 - 即357度,358度,359度,360度,361度等。我想要的修改我的数据,以便在其中包含此转换数据。
当数字接近0度限制时,我希望它们变为负数 - 即3度,2度,1度,0度,-1度,-2度等。
360度的倍数(正面和负面),我希望度数继续,例如720度等。
有关采取何种方法的任何建议?毫无疑问,毫无疑问,这是一种令人沮丧的简单方法,但我目前的解决方案至少可以说是笨蛋......!我迄今为止最好的尝试是查看角度n和角度n-1之间的百分比差异。如果这是一个很大的差异 - 例如> 60% - 然后需要修改,通过在当前值上加上或减去360度,具体取决于之前的角度值。也就是说,如果前一个角度为负,则减去360,如果前一个角度为正,则添加360.
有关改善此事的任何建议吗?有什么改进吗?
答案 0 :(得分:2)
你所谈论的是一个unwrap
算法,它推广(不是特定于数字360 ......你可以用m = 2 * pi的弧度来做)。这是javascript中的一个:
/* symmetric modulo:
* y = smod(x,m) = x+k*m where k is an integer,
* and y is always in the range [-0.5,0.5)*m
*/
function smod(x, m)
{
return x-((Math.floor(x/m + 0.5))*m);
}
/* unwrap:
* for all i, y[i] = x[i] + k*m where k is an integer,
* and for i > 0, the increment y[i]-y[i-1] is in the
* range [-0.5,0.5)*m as in smod().
*
* the "init" parameter is optional (default to 0)
* and specifies the starting value for the unwrap state.
*/
function unwrap(x, m, init)
{
var yi = init || 0;
var y = [];
for (i = 0; i < x.length; ++i)
{
yi += smod(x[i]-yi, m);
y[i] = yi;
}
return y;
}
这是一个示例输出:
js>unwrap([100, 200, 348, 359, 23, 37, 46, 10, 350, 190], 360)
100,200,348,359,383,397,406,370,350,190
另一个m = 100:
js>unwrap([99,1,7,60,80,22,30,20,90,88,61,23,2,87,50,12], 100, 1000)
999,1001,1007,960,980,1022,1030,1020,990,988,961,923,902,887,850,812
仅供参考:在C / Java /等中。存在用于比特扩展的类似算法,其中输入例如是16比特并且输出是32比特,并且环绕模数m = 65536 =输入值的范围。你不需要“smod”函数,只需使用带符号的数学:
typedef short int16_t;
typedef long int32_t;
// do typedefs as appropriate on your CPU
int32_t unwrap_extend(int32_t prev, int16_t input)
{
int16_t delta = input - prev;
return prev + delta;
}
答案 1 :(得分:1)
您可以继续添加/减去所有学位,然后使用360的最终结果使用MODULUS运算符。这将为您提供剩余的学位。
答案 2 :(得分:1)
使用某种方法获取每个角度与前一个角度的差异,以确保在两个方向上穿过0/360时获得正确的符号。然后将此差异添加到不会翻转的运行总计中。
答案 3 :(得分:0)
如果我能正确理解问题,可能会有效:
int prev=[first data piece in data set]
int total=prev
foreach data in [the rest of the data set]
total+=data-prev
prev=data
data=total
然后在循环结束时,数据集将包含所有数据,并按照您的指定相加。
所以基本上循环遍历数据集,并将差异添加到运行总计中。在您迭代时,运行总计将成为每个数据块。
答案 4 :(得分:0)
此C程序采用标准输入和0到359度范围内的角度列表 通过累积角度变化将无界值打印到标准输出。通过假设每个输入角度的最大可能变化来检测缠绕。
#include <stdio.h>
#include <stdlib.h>
int
main()
{
const float MAX_DELTA = 180.f; /* highest expected change */
float previous, next, delta, output;
/* set the initial value */
if (EOF == scanf("%f", &next))
exit(0);
previous = next;
output = previous;
do {
/* calculate the change in angle and adjust if too big */
delta = next - previous;
if (MAX_DELTA < delta)
delta -= 360.f;
else if (-MAX_DELTA > delta)
delta += 360.f;
/* accumlate the changes without wrap-around */
output += delta;
printf("%f\n", output);
/* store the value for calculating the next delta */
previous = next;
/* read angle values until end of file is reached */
} while (EOF != scanf("%f", &next));
exit(0);
}
答案 5 :(得分:0)
使用模数函数
static inline float GetAbsoluteModulous(float input ,float devisor )
{
double output = (devisor==0)?input:fmod(input, devisor);
return (output>0)?output:devisor+output;
}
angle = GetAbsoluteModulous(angle,360);