Prime numbers spiral exploration

Share your advanced PureBasic knowledge/code with the community.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Prime numbers spiral exploration

Post by djes »

Some guys played a bit with prime numbers on french forum. I've imagined a way to find some special patterns if numbers were distributed on 2D ; I've thought of spiral and discovered someone did that before (isn't it strange ;) ) : http://www.numberspiral.com/index.html. Anyway, I tried to alter dynamically the spiral parameters to push further the exploration. Here's the code, if you find the magical pattern, don't forget me ;)

Code: Select all

;**********************************
;
; Primes numbers spiral exploration
; 26/05/2011
; by djes (djes@free.fr)
; Thx to Sirius-2337, Demivec, Gnasen for IsPrime optim
; Thx to DjPoke, Fig, zaphod, graph100, LSI & Nat the Great for LookForPrimes() optim
;
;**********************************

Global PrimesNb, ww, wh, GadgetAngle, GadgetDeviation, TextFlag
Global Dim Primes(80000)

Procedure IsPrime(number.l)

  If number = 2
    ProcedureReturn 1
  ElseIf number % 2 = 0
    ProcedureReturn 0
  Else
    x = Sqr(number)
    For t = 3 To x Step 2
      If number % t = 0
        ProcedureReturn 0
      EndIf
    Next t
  EndIf

  ProcedureReturn 1

EndProcedure

Procedure SpiralDraw()
 
  cx = ww / 2 - 20 : cy = wh / 2
 
  Angle.d = #PI / (GetGadgetState(0) / 100)
  Deviation.d = #PI / (GetGadgetState(1) / 10 )
 
  i.d = 0
  e.d = 0
  ;PreviousPrime = 0
  StartDrawing(ImageOutput(0))
  Box(0, 0, ww - 40, wh, $FFFFFF)
  If TextFlag
    DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_XOr)
    For u = 0 To PrimesNb - 1
      x = cx + e * Sin(i)
      y = cy + e * Cos(i)
      DrawText(x, y, Str(Primes(u)), RGB($FF, $FF, 0))
      i = Angle * Primes(u)
      ;e = Deviation * Primes(u) ;deviation from the center is based on the prime value
      e + Deviation              ;deviation is linear
    Next u
  EndIf
 
  i.d = 0
  e.d = 0
  DrawingMode(#PB_2DDrawing_Default)
  For u = 0 To PrimesNb - 1
    x = cx + e * Sin(i)
    y = cy + e * Cos(i)
    If x >= 0 And x < ww - 40 And y >= 0 And y < wh
      Plot(x, y, 0)
    EndIf
    i = Angle * Primes(u)
    ;e = Deviation * Primes(u) ;deviation from the center is based on the prime value
    e + Deviation              ;deviation is linear
    ;PreviousPrime = Primes(u)
  Next u

  StopDrawing()
  StartDrawing(WindowOutput(0))
  DrawImage(ImageID(0), 0, 0)
  DrawText(0,  0, "Angle : PI/" + StrD(GetGadgetState(0) / 100, 2), 0, $FFFFFF)
  DrawText(0, 20, "Deviation : PI/" + Str(GetGadgetState(1)), 0, $FFFFFF)
  StopDrawing()

EndProcedure

Procedure GUIInit()
 
  ww = WindowWidth(0) : wh = WindowHeight(0)
  CreateImage(0, ww - 40, wh)
  TrackBarGadget(0, WindowWidth(0) - 40, 16, 20, WindowHeight(0) - 16, 1, 31410, #PB_TrackBar_Vertical)
  TrackBarGadget(1, WindowWidth(0) - 20, 16, 20, WindowHeight(0) - 16, 1, 4000, #PB_TrackBar_Vertical)
  CheckBoxGadget(2, WindowWidth(0) - 40,  1, 40, 16, "Text")
 
  SetGadgetState(0, GadgetAngle)
  SetGadgetState(1, GadgetDeviation)
 
EndProcedure

Procedure LookForPrimes(RangeSearch)
;  
;   TextGadget(4, 5, wh / 2 - 20, ww - 40 - 5, 20, "Looking for primes numbers - Please wait", #PB_Text_Right)
;   ProgressBarGadget(3,  5, wh / 2, ww - 40 - 5, 20, 0, RangeSearch, #PB_ProgressBar_Smooth)
;  
;   PrimesNb = 0
;   For u = 2 To RangeSearch
;     If IsPrime(u)
;       Primes(PrimesNb) = u
;       PrimesNb + 1
;     EndIf
;     SetGadgetState(3, u)
;   Next u
;   SetGadgetText(4, Str(PrimesNb) + " found")
;   Delay(1000)
;   FreeGadget(3)
;   FreeGadget(4)

   ; algo nat the great pour blitzmax
   ; port en pb by zaphod - 23/05/2011
   
  Define num.i = RangeSearch
  Define sqrnum.i = Sqr(RangeSearch)+1
  Dim PrimeFlags.i(RangeSearch)
  ReDim Primes.i(RangeSearch)
  Define tim.i
  
  PrimesNb = 1
  
  For x = 3 To sqrnum Step 2
    If PrimeFlags(x) = #False
      Primes(PrimesNb) = x
      PrimesNb+1   
      
      tim = x + x
      Repeat
        PrimeFlags(tim) = #True
        tim + x
      Until tim >= num
    EndIf
  Next
  
  Primes(0) = 2
  For y = x To num Step 2
    If PrimeFlags(y) = #False
      Primes(PrimesNb) = y     
      PrimesNb+1   
    EndIf
  Next

EndProcedure

;-MAIN

If OpenWindow(0, 0, 0, 600, 600, "Prime nb spiral explorer by djes@free.fr - Use top/down keys on gadgets", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
 
  WindowBounds(0, 500, 500, 4000, 4000)
 
  TextFlag = #False
  GadgetAngle = 247
  GadgetDeviation = 600
 
  GUIInit()
  LookForPrimes(500000)
  SpiralDraw()
     
  Repeat
   
    Event = WaitWindowEvent()
   
    Select Event
       
      Case #PB_Event_SizeWindow
       
        GUIInit()
        SpiralDraw()
       
      Case #PB_Event_Gadget
       
        Select EventGadget()
           
          Case 0, 1
           
            GadgetAngle = GetGadgetState(0)
            GadgetDeviation = GetGadgetState(1)
            SpiralDraw()
           
          Case 2
           
            TextFlag = ~TextFlag
            SpiralDraw()
           
        EndSelect

      Case #PB_Event_CloseWindow
        Quit = 1
       
    EndSelect
   
  Until Quit = 1
 
EndIf

End
Edit: optimised IsPrime() function
Last edited by djes on Thu May 26, 2011 8:23 pm, edited 5 times in total.
Sirius-2337
User
User
Posts: 59
Joined: Sat May 14, 2011 10:39 am

Re: Prime numbers spiral exploration

Post by Sirius-2337 »

Nice Code, but it work realy faster if you change your IsPrime-Function a bit

Code: Select all

Procedure IsPrime(Number.l)
 
  For t = 2 To Number - 1
    If Number % t = 0
      ProcedureReturn 0
    EndIf
  Next t
 
  ProcedureReturn 1
 
EndProcedure
You can Return 0 as soon as Number % t = 0 and don't have to check all the other numbers.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Prime numbers spiral exploration

Post by Demivec »

Here's a one up on Sirus-2337's improvement:

Code: Select all

Procedure IsPrime(number.l)
  
  x = Sqr(number)
  For t = 2 To x
    If number % t = 0
      ProcedureReturn 0
    EndIf
  Next t
  
  ProcedureReturn 1
  
EndProcedure
:)

Nice code. I'll definitely be taking a deeper look into the spiral patterns.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Prime numbers spiral exploration

Post by djes »

Thanks guys :)
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Prime numbers spiral exploration

Post by rsts »

I keep getting blown away by things I'll likely never have a use for.

Very impressive. :shock:

Thanks for sharing.
gnasen
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Sep 24, 2008 12:21 am

Re: Prime numbers spiral exploration

Post by gnasen »

the end is not reached yet (and there may be more to tune :twisted: )

Code: Select all

Procedure IsPrime(number.l)
  
  If number = 2
    ProcedureReturn 1
  ElseIf number % 2 = 0
    ProcedureReturn 0
  Else
    x = Sqr(number)
    For t = 3 To x Step 2
      If number % t = 0
        ProcedureReturn 0
      EndIf
    Next t
  EndIf
  
  ProcedureReturn 1
  
EndProcedure
However, Im still very impressed by the pure beauty of this. I never thought about prime numbers in this way and I would be interested if there is some research in this direction already done. Im sure there must be much material about this fact, because there seems to be no other themes next to prime numbers for theoretical mathematics
pb 5.11
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Prime numbers spiral exploration

Post by djes »

Optimised LookForPrimes() by Nat the Great, DjPoke, Fig, zaphod, graph100 & LSI :)
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Prime numbers spiral exploration

Post by djes »

Color (difference between two numbers) ; keyboard shortcuts : up/down, left/right, +/-

Code: Select all

;**********************************
;
; Primes numbers spiral exploration
; 26/05/2011
; by djes (djes@free.fr)
; Thx to Sirius-2337, Demivec, Gnasen for IsPrime optim
; Thx to DjPoke, Fig, zaphod, graph100, LSI & Nat the Great for LookForPrimes() optim
;
;**********************************

Global PrimesNb, ww, wh, GadgetAngle, GadgetDeviation, TextFlag, ColorFactor
Global Dim Primes(80000)

Procedure IsPrime(number.l)

  If number = 2
    ProcedureReturn 1
  ElseIf number % 2 = 0
    ProcedureReturn 0
  Else
    x = Sqr(number)
    For t = 3 To x Step 2
      If number % t = 0
        ProcedureReturn 0
      EndIf
    Next t
  EndIf

  ProcedureReturn 1

EndProcedure

Procedure SpiralDraw()
 
  cx = ww / 2 - 20 : cy = wh / 2
 
  Angle.d = #PI / (GetGadgetState(0) / 10000)
  Deviation.d = #PI / (GetGadgetState(1) / 10 )
 
  i.d = 0
  e.d = 0
  PreviousPrime = 0
  StartDrawing(ImageOutput(0))
  Box(0, 0, ww - 40, wh, 0)
  If TextFlag
    DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_XOr)
    For u = 0 To PrimesNb - 1
      x = cx + e * Sin(i)
      y = cy + e * Cos(i)
      If x >= 0 And x < ww - 40 And y >= 0 And y < wh
        DrawText(x, y, Str(Primes(u)), RGB($FF, $FF, 0))
      EndIf
      i = Angle * Primes(u)
      ;e = Deviation * Primes(u) ;deviation from the center is based on the prime value
      e + Deviation              ;deviation is linear
    Next u
  EndIf
 
  i.d = 0
  e.d = 0
  DrawingMode(#PB_2DDrawing_Default)
  For u = 0 To PrimesNb - 1
    x = cx + e * Sin(i)
    y = cy + e * Cos(i)
    If x >= 0 And x < ww - 40 And y >= 0 And y < wh
      Plot(x, y, (Primes(u) - PreviousPrime) * ColorFactor)
    EndIf
    i = Angle * Primes(u)
    ;e = Deviation * Primes(u) ;deviation from the center is based on the prime value
    e + Deviation              ;deviation is linear
    PreviousPrime = Primes(u)
  Next u

  StopDrawing()
  StartDrawing(WindowOutput(0))
  DrawImage(ImageID(0), 0, 0)
  DrawText(0,  0, "Angle : PI/" + StrD(GetGadgetState(0) / 10000, 4), $FFFFFF, 0)
  DrawText(0, 16, "Deviation : PI/" + Str(GetGadgetState(1)), $FFFFFF, 0)
  DrawText(0, 32, "Color Factor : " + Str(ColorFactor), $FFFFFF, 0)
  StopDrawing()

EndProcedure

Procedure GUIInit()
 
  ww = WindowWidth(0) : wh = WindowHeight(0)
  CreateImage(0, ww - 40, wh)
  TrackBarGadget(0, WindowWidth(0) - 40, 16, 20, WindowHeight(0) - 16, 1, 3141600, #PB_TrackBar_Vertical)
  TrackBarGadget(1, WindowWidth(0) - 20, 16, 20, WindowHeight(0) - 16, 1, 16000, #PB_TrackBar_Vertical)
  CheckBoxGadget(2, WindowWidth(0) - 40,  1, 40, 16, "Text")
 
  SetGadgetState(0, GadgetAngle)
  SetGadgetState(1, GadgetDeviation)
 
EndProcedure

Procedure LookForPrimes(RangeSearch)
;  
;   TextGadget(4, 5, wh / 2 - 20, ww - 40 - 5, 20, "Looking for primes numbers - Please wait", #PB_Text_Right)
;   ProgressBarGadget(3,  5, wh / 2, ww - 40 - 5, 20, 0, RangeSearch, #PB_ProgressBar_Smooth)
;  
;   PrimesNb = 0
;   For u = 2 To RangeSearch
;     If IsPrime(u)
;       Primes(PrimesNb) = u
;       PrimesNb + 1
;     EndIf
;     SetGadgetState(3, u)
;   Next u
;   SetGadgetText(4, Str(PrimesNb) + " found")
;   Delay(1000)
;   FreeGadget(3)
;   FreeGadget(4)

   ; algo nat the great pour blitzmax
   ; port en pb by zaphod - 23/05/2011
   
  Define num.i = RangeSearch
  Define sqrnum.i = Sqr(RangeSearch)+1
  Dim PrimeFlags.i(RangeSearch)
  ReDim Primes.i(RangeSearch)
  Define tim.i
  
  PrimesNb = 1
  
  For x = 3 To sqrnum Step 2
    If PrimeFlags(x) = #False
      Primes(PrimesNb) = x
      PrimesNb+1   
      
      tim = x + x
      Repeat
        PrimeFlags(tim) = #True
        tim + x
      Until tim >= num
    EndIf
  Next
  
  Primes(0) = 2
  For y = x To num Step 2
    If PrimeFlags(y) = #False
      Primes(PrimesNb) = y     
      PrimesNb+1   
    EndIf
  Next

EndProcedure

;-MAIN

If OpenWindow(0, 0, 0, 500, 500, "Prime nb spiral explorer by djes@free.fr - Use top/down keys on gadgets", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
 
  WindowBounds(0, 500, 500, 4000, 4000)
  
  AddKeyboardShortcut(0, #PB_Shortcut_Up, 1)
  AddKeyboardShortcut(0, #PB_Shortcut_Down, 2)

  AddKeyboardShortcut(0, #PB_Shortcut_Left, 3)
  AddKeyboardShortcut(0, #PB_Shortcut_Right, 4)
  
  AddKeyboardShortcut(0, #PB_Shortcut_Add, 5)
  AddKeyboardShortcut(0, #PB_Shortcut_Subtract, 6)

 
  TextFlag = #False
  GadgetAngle = 1123612
  GadgetDeviation = 10000
  ColorFactor = 16
 
  GUIInit()
  LookForPrimes(2000000)
  SpiralDraw()
     
  Repeat
   
    Event = WaitWindowEvent()
   
    Select Event
       
      Case #PB_Event_SizeWindow
       
        GUIInit()
        SpiralDraw()
       
      Case #PB_Event_Gadget
       
        Select EventGadget()
            
          Case 0, 1
            
            GadgetAngle = GetGadgetState(0)
            GadgetDeviation = GetGadgetState(1)
            SpiralDraw()
            
          Case 2
            
            TextFlag = ~TextFlag
            SpiralDraw()
            
        EndSelect        
                
      Case #PB_Event_Menu
        
        Select EventMenu()
            
          Case 1
            
            GadgetAngle + 1
            SetGadgetState(0, GadgetAngle)
            SpiralDraw()
            
          Case 2
            
            GadgetAngle - 1
            SetGadgetState(0, GadgetAngle)
            SpiralDraw()
            
          Case 3
            
            ColorFactor + 1
            SpiralDraw()
            
          Case 4
            
            ColorFactor - 1
            SpiralDraw()
            
          Case 5
            
            GadgetDeviation + 1
            SetGadgetState(1, GadgetDeviation)
            SpiralDraw()
            
          Case 6
            
            GadgetDeviation - 1
            SetGadgetState(1, GadgetDeviation)
            SpiralDraw()
            
        EndSelect
        
      Case #PB_Event_CloseWindow
        Quit = 1
       
    EndSelect
   
  Until Quit = 1
 
EndIf

End
Post Reply