2015-08-08 20 views
1

我挑戰自己創建一個程序,以試驗素數,我已經有一個想法如何做到這一點,但不是編碼技巧..C# - 需要幫助創建程序,通過畫線模擬素數行爲

我的計劃是這樣的:首先 生病C#創建一個程序,使遵循一些規則直線:

規則1:所有行具有相同的長度。

規則2:所有行都是水平或垂直(無對角線)。

規則3:每一條新行都從上一行結束的位置開始(這樣所有行都被連接)。

現在到了棘手的部分:

我想作一個計數器,每創建一個新的行時間由1上升(初始值爲1我相信),而當它到達一個素數,線改變'方向'並開始'走向'原始方向的左側。

第10行會是這個樣子:

 | 
__ | 
| | | 
|__ __| 

注意它是如何在第2,第3,第5和第7行改變了方向。

這將創建一個長期扭曲線,這將是非常冷靜地看到它使什麼花樣(從外面結束內部開始)。

感謝您的幫助!

回答

3

這是一個有趣的項目。感謝我的早上娛樂!

我在this SO thread中使用SLaks代碼來獲取少於指定數量的Primes列表。

下面是一些示例輸出:

Example Output #1 Example Output #2 Example Output #3

生成素數後,我走列表並存儲在GraphicsPath的線條。使用Graphics.GetBounds()方法則允許我們適當規模,並在畫圖變換圖形()我們小組的活動讓整個圖形中可以看出:

public partial class Form1 : Form 
{ 

    private const int segmentLength = 10; 
    private GraphicsPath gpPrimes = null; 

    public Form1() 
    { 
     InitializeComponent(); 
     nudLessThanMax.Minimum = 15; 
     nudLessThanMax.Maximum = 500000; 
     nudLessThanMax.Value = nudLessThanMax.Minimum; 
     pnlPrimes.Paint += PnlPrimes_Paint; 
     pnlPrimes.SizeChanged += PnlPrimes_SizeChanged; 
    } 

    private void PnlPrimes_SizeChanged(object sender, EventArgs e) 
    { 
     pnlPrimes.Invalidate(); 
    } 

    private void PnlPrimes_Paint(object sender, PaintEventArgs e) 
    { 
     if (gpPrimes != null) 
     { 
      RectangleF rectF = gpPrimes.GetBounds(); 
      float max = Math.Max(rectF.Width + (2 * segmentLength), rectF.Height + (2 * segmentLength)); 
      e.Graphics.TranslateTransform(pnlPrimes.Width/2, pnlPrimes.Height/2); 
      e.Graphics.ScaleTransform((float)pnlPrimes.Width/max, (float)pnlPrimes.Height/max); 
      e.Graphics.TranslateTransform(-(rectF.Left + rectF.Width/2), -(rectF.Top + rectF.Height/2)); 
      e.Graphics.DrawPath(Pens.Black, gpPrimes); 
     } 
    } 

    private void btnGraphPrimes_Click(object sender, EventArgs e) 
    { 
     btnGraphPrimes.Enabled = false; 
     backgroundWorker1.RunWorkerAsync((int)this.nudLessThanMax.Value); 
    } 

    private List<int> PrimesLessThan(int num) // SLaks: https://stackoverflow.com/a/1510186/2330053 
    { 
     return Enumerable.Range(0, (int)Math.Floor(2.52 * Math.Sqrt(num)/Math.Log(num))).Aggregate(
      Enumerable.Range(2, num - 1).ToList(), 
      (result, index) => 
      { 
       var bp = result[index]; var sqr = bp * bp; 
       result.RemoveAll(i => i >= sqr && i % bp == 0); 
       return result; 
      } 
     ); 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     int diff; 
     int num = (int)e.Argument; 
     Point pt = new Point(0, 0); 
     Point pt2 = pt; 
     GraphicsPath gp = new GraphicsPath(); 
     List<int> primes = PrimesLessThan(num); 

     for(int i = 1; i < primes.Count; i++) 
     { 
      diff = primes[i] - primes[i - 1]; 
      switch(i % 4) 
      { 
       case 1: // up 
        pt2 = new Point(pt.X, pt.Y - (segmentLength * diff)); 
        break; 

       case 2: // left 
        pt2 = new Point(pt.X - (segmentLength * diff), pt.Y); 
        break; 

       case 3: // down 
        pt2 = new Point(pt.X, pt.Y + (segmentLength * diff)); 
        break; 

       case 0: // right 
        pt2 = new Point(pt.X + (segmentLength * diff), pt.Y); 
        break; 
      } 
      gp.AddLine(pt, pt2); 
      pt = pt2; 
     } 
     gpPrimes = gp; 
     e.Result = primes; 
    } 

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     lbPrimes.DataSource = (List<int>)e.Result; 
     pnlPrimes.Invalidate(); 
     btnGraphPrimes.Enabled = true; 
    } 

} 
+0

太感謝你了!這正是我想到的。 – Bearnnitr

+0

爲了好玩......這是圖表看起來像max [50'000'000](http://i.imgur.com/jIasnze.png) –

1

再一次,我希望我有足夠的觀點讓這只是一個評論,但我想確保你知道提前知道這不會導致一個螺旋。有一對素數只有2分開(n,n + 2都是素數),這將使你的蛇做180,並跨過它自己。

如果你沒有問題,那麼查看System.Drawing命名空間,尤其是Graphics.Drawline方法。或者看看一些有助於給你正確想法的代碼。只需在Windows窗體中放置一個pictureBox,此代碼將在其上放置一行。從那裏你可以處理你的筆顏色,規模,找到你的素數等。

 Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height); 
     using (Graphics g = Graphics.FromImage(bmp)) 
     { 
      g.DrawLine(new Pen(Color.Red), 300, 100, 100, 100); 
     } 
     pictureBox1.Image = bmp;