2010-03-23 158 views
1

我正在努力解決我與度有關的問題。我有數據是角度列表,以標準度數表示 - 例如26度通常當處理角度時,如果角度超過360度,則角度繼續並且有效地「重置」 - 即角度「再次開始」,例如, 357度,358度,359度,0度,1度等。我想要發生的是繼續增加的程度 - 即357度,358度,359度,360度,361度等。我想要修改我的數據,以便我有這個轉換後的數據。計算> 360度的旋轉。情況

當數接近0度的限制,我想他們成爲負 - 即,3度,2度,1度,0度,-1度,-2度等

隨着倍數360度(正面和負面),我想要度數繼續,例如720度等

任何建議採取什麼方法?毫無疑問,這是一個令人沮喪的簡單方法,但我目前的解決方案至少可以說是kludgey ....!我迄今爲止的最佳嘗試是查看角度n和角度n - 1之間的百分比差異。如果這是一個很大的差異 - 例如, > 60% - 那麼需要根據以前的角度值對當前值加上或減去360度來修改。也就是說,如果前一個角度爲負,則減去360,如果前一個角度爲正,則加上360。

有關改善這方面的任何建議嗎?任何改進?

+2

我想我明白你的問題,但對輸入的短例子和期望的產出,將有助於澄清事情極大。 – 2010-03-23 14:00:18

+0

你能提供更多關於你所擁有的數據的信息嗎?你能提供一些樣本數據嗎?每一段數據是輪換還是隱含輪換的新程度?我可以看到,作爲一個具有模糊性的人,除非每個數據之間的程度差異存在限制。編輯:+1 @法官打我:) – Cam 2010-03-23 14:00:47

+1

什麼假設可以作出關於角度的變化率?換句話說,你測量什麼物理角度? – 2010-03-23 14:48:48

回答

1

您可以繼續添加/減去所有度數,然後使用MODULUS運算符對最終結果使用360.這會給您剩下的度數。

+0

+1,那就是我會做的。 – 2010-03-23 14:04:43

+0

??這是相當模糊的,我不認爲這是OP所要求的。 – 2010-03-24 14:17:16

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 

然後在循環結束後,該數據集將包含所有數據,加起來爲您指定。

因此基本上遍歷數據集,並將差異添加到運行總數。在迭代時,運行總數將成爲每個數據片。

+0

從359到2時,data-prev不起作用。解決方案是正確的,除非沒有做這個區別。 – phkahler 2010-03-23 14:06:22

1

使用某種方法取每個角度和前一個角度的差異,以確保您在兩個方向上穿過0/360時獲得正確的符號。然後將此差異添加到不滾動的運行總數。

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); 
} 
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); 
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 /爪哇/等。存在用於比特擴展的類似算法,其中輸入例如是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; 
} 
+0

好的答案,smod在直接使用弧度時非常有用。爲我做了這份工作!謝謝。 – Oliver 2011-09-01 01:02:55