2012-12-25 100 views
4

我想在下面的圖片上顯示與圖形類似的圖形。我想實現類似於cos/sin的圖形,但是有一點隨機性。圖表不應超過(100)或低於(0)限制。 沒有隨機性,我們可以寫函數是這樣的:隨機平滑圖

f(x)=cos(x)*50+50 

Random graph

我正在尋找任何語言實現,或只是一個簡單的解釋。

+0

爲了什麼目的?這有點太開放了...... – RBarryYoung

+0

@RBarryYoung產生一個簡單的遊戲隨機地形。 – ewooycom

+0

啊,好的。我記得,隨機地形最好生成爲f(0)和f(1)過程的組合...... – RBarryYoung

回答

2

你可以簡單地將幾個sin/cos與隨機係數和週期相​​加。

實現的例子:

internal struct SineWave 
{ 
    internal readonly double Amplitude; 
    internal readonly double OrdinaryFrequency; 
    internal readonly double AngularFrequency; 
    internal readonly double Phase; 
    internal readonly double ShiftY; 

    internal SineWave(double amplitude, double ordinaryFrequency, double phase, double shiftY) 
    { 
     Amplitude = amplitude; 
     OrdinaryFrequency = ordinaryFrequency; 
     AngularFrequency = 2 * Math.PI * ordinaryFrequency; 
     Phase = phase; 
     ShiftY = shiftY; 
    } 
} 

public class RandomCurve 
{ 
    private SineWave[] m_sineWaves; 

    public RandomCurve(int components, double minY, double maxY, double flatness) 
    { 
     m_sineWaves = new SineWave[components]; 

     double totalPeakToPeakAmplitude = maxY - minY; 
     double averagePeakToPeakAmplitude = totalPeakToPeakAmplitude/components; 

     int prime = 1; 
     Random r = new Random(); 
     for (int i = 0; i < components; i++) 
     { 
      // from 0.5 to 1.5 of averagePeakToPeakAmplitude 
      double peakToPeakAmplitude = averagePeakToPeakAmplitude * (r.NextDouble() + 0.5d); 

      // peak amplitude is a hald of peak-to-peak amplitude 
      double amplitude = peakToPeakAmplitude/2d; 

      // period should be a multiple of the prime number to avoid regularities 
      prime = Utils.GetNextPrime(prime); 
      double period = flatness * prime; 

      // ordinary frequency is reciprocal of period 
      double ordinaryFrequency = 1d/period; 

      // random phase 
      double phase = 2 * Math.PI * (r.NextDouble() + 0.5d); 

      // shiftY is the same as amplitude 
      double shiftY = amplitude; 

      m_sineWaves[i] = 
       new SineWave(amplitude, ordinaryFrequency, phase, shiftY); 
     } 
    } 

    public double GetY(double x) 
    { 
     double y = 0; 
     for (int i = 0; i < m_sineWaves.Length; i++) 
      y += m_sineWaves[i].Amplitude * Math.Sin(m_sineWaves[i].AngularFrequency * x + m_sineWaves[i].Phase) + m_sineWaves[i].ShiftY; 

     return y; 
    } 
} 

internal static class Utils 
{ 
    internal static int GetNextPrime(int i) 
    { 
     int nextPrime = i + 1; 
     for (; !IsPrime(nextPrime); nextPrime++) ; 
     return nextPrime; 
    } 

    private static bool IsPrime(int number) 
    { 
     if (number == 1) return false; 
     if (number == 2) return true; 

     for (int i = 2; i < number; ++i) 
      if (number % i == 0) return false; 

     return true; 
    } 
} 
+0

也有隨機期間,我假設? – RBarryYoung

+0

@RBarryYoung,是的。 –

0

爲了您的功能,你可以使用Math類和Cos()方法。

public static double GetCosFunction(double d) 
{ 
    return Math.Cos(d) * 50 + 50; 
} 

對於圖形解決方案,您可以檢查這些主題;

+0

我認爲你誤解了這個問題。他並沒有問如何繪製這個功能,而是在問如何讓這個功能更隨機。 – RBarryYoung

+0

這是什麼意思「使功能更隨機」?功能清楚輸入和清除輸出。一個更隨機的函數怎麼可能只用一個叫做「cos(x)* 50 + 50」的表達式呢?請點亮我.. –

+1

他想要一個類似於那個函數的函數,但是它有一些隨機性。 – RBarryYoung

2

因此,這裏是C#編寫的代碼,它可以與隨機輸入值是隨機的多。 我只是給你一些輸出值,看看你是否可以。 Amplite可以修改餘弦值和正弦值。最後加上偏移量(因此最小值始終爲0),並且縮放比例可以確保最大值爲100.正如您所看到的,可以將噪聲添加到(圖3,圖4)。

terr1:RandomTerrarain(1000,4,1,10,5,0); Figure 1

terr2:RandomTerrarain(1000,2,3,-10,5,0); Figure 2

希望這有助於!

 private static Random rnd = new Random(); 
    private double[] RandomTerrarain(int length, int sinuses, int cosinuses, double amplsin, double amplcos, double noise) 
    { 
     if (length <= 0) 
      throw new ArgumentOutOfRangeException("length", length, "Length must be greater than zero!"); 
     double[] returnValues = new double[length]; 

     for (int i = 0; i < length; i++) 
     { 
      // sin 
      for (int sin = 1; sin <= sinuses; sin++) 
      { 
       returnValues[i] += amplsin * Math.Sin((2 * sin * i * Math.PI)/(double)length); 
      } 
      // cos 
      for (int cos = 1; cos <= cosinuses; cos++) 
      { 
       returnValues[i] += amplcos * Math.Cos((2 * cos * i * Math.PI)/(double)length); 
      } 
      // noise 
      returnValues[i] += (noise * rnd.NextDouble()) - (noise * rnd.NextDouble()); 
     } 
     // give offset so it be higher than 0 
     double ofs = returnValues.Min(); 
     if (ofs < 0) 
     { 
      ofs *= -1; 
      for (int i = 0; i < length; i++) 
      { 
       returnValues[i] += ofs; 
      } 
     } 
     // resize to be fit in 100 
     double max = returnValues.Max(); 
     if (max >= 100) 
     { 
      double scaler = max/100.0; 
      for (int i = 0; i < length; i++) 
      { 
       returnValues[i] /= scaler; 
      } 
     } 
     return returnValues; 
    } 
+0

[圖5] http://dl.dropbox.com/u/64369382/terr.png – kurtyka

0

忘記這個....

terr3:RandomTerrarain(1000,5,5,-2,5,2); Figure 3

terr4:RandomTerrarain(1000,4,1,5,-20,1); Figure 4

0

看一看xkcd-style graphs,方法隨機噪聲添加到圖和平滑它的方式,使它看起來手繪,模仿xkcd cartoons的風格。雖然這不完全是你想要的,但我想簡單地將輸入圖設置爲零(例如,y = 0)並且將噪聲平滑參數調整爲更大的噪聲幅度,並且更大的平滑距離可能導致隨機圖你正在尋找。