3D Prime numbers spiral

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

3D Prime numbers spiral

Post by applePi »

prime numbers spiral in 3D demo, by plotting a 3D spiral and attach the numbers from 0 to 100000 to it and coloring the prime numbers as Green, i have used
IsPrime to detect the primes since it is speedy.
it is easy to implement:
plot the 3D spiral:
x = t*Cos(6*t)
y = t*Sin(6*t)
z = t
number = number + 1 : IsPrime(number): if prime color=green
MeshVertexPosition(x, y, z)
MeshVertexColor(RGB(red,green,blue))


let the spiral rotate until its wide mouth facing you then press space bar to stop rotation, then press Page_Down to zoom out so you can see a pattern like this:
Image

zoom Page_Up to see the details of the spiral
note that you can save the mesh of the spiral, uncomment line 83 "SaveMesh(1, "spiral.mesh") and open it in a mesh viewer. but i don't know if the saved mesh have the vertex color info inside it or not. any way you can use the pure 3D shape
references: djes article "Prime numbers spiral exploration": http://www.purebasic.fr/english/viewtop ... 12&t=46476
http://www.mathematische-basteleien.de/spiral.htm
http://www.intmath.com/blog/golden-spiral/6512

Code: Select all

Enumeration
   #MESH
   #LIGHT
   #CAMERA_ONE
   #BUTTON
   #mainwin
 EndEnumeration

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

Quit.b = #False
stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD Zoom ..., space: stop/rotate ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

;Initialize environment
InitEngine3D()
InitSprite()
;OpenWindowedScreen(WindowID(#mainwin), 0, 0, 800, 600-70, 0, 0, 0)
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
WorldShadows(#PB_Shadow_Additive)

InitKeyboard()
SetFrameRate(60)

Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)

CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))

CreateCamera(#CAMERA_ONE, 0, 0, 100, 100)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)

RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf


CreateTexture(0,16,16)
StartDrawing(TextureOutput(0))
Box(0, 0, 16, 16,RGB(255,255,255))
StopDrawing()

CreateMaterial(0, TextureID(0))
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static )

SetMeshMaterial(1, MaterialID(0))

For number = 0 To 100000
        t.f+0.01
        x = t*Cos(6*t)
        y = t*Sin(6*t)
        z = t
        
        If IsPrime(number)
          red=0:green=255:blue=0
                  Else
                    red=255:green=0:blue=0
        EndIf
        MeshVertexPosition(x, y, z)
        MeshVertexColor(RGB(red,green,blue))
         
      Next 
NormalizeMesh(1)
FinishMesh(#True)
CreateEntity(1, MeshID(1), MaterialID(0))
ScaleEntity(1,0.1,0.1,0.1)
;MoveEntity(1,-2,1.5,-2)
MoveEntity(1,0,1,-2)

SaveMesh(1, "spiral.mesh")
turn.b=0: rot.f=0.5
Repeat
  Event = WindowEvent()
    
   y+rot
   RotateEntity(1,0,y,0)
   
   RenderWorld()
   FlipBuffers()

   ExamineKeyboard()
   If KeyboardReleased(#PB_Key_Space)
     If turn
       rot=0.5
     Else
       rot=0
    EndIf
    turn ! 1 
  
  ElseIf KeyboardPushed(#PB_Key_PageUp) ; scale up model
    xs.f = 1.1:ys.f = 1.1:zs.f = 1.1
    ScaleEntity(1,xs,ys,zs)
   
  ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
    xs = 0.9:ys = 0.9:zs= 0.9
    ScaleEntity(1,xs,ys,zs)
   
  EndIf
  
   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
   
Until Quit = #True Or Event = #PB_Event_CloseWindow
PS: after checking the spiral.mesh produced from SaveMesh with the mesh viewer, i thing SaveMesh store some info , i'm still investigating, but you can see the primes pattern on the spiral.mesh by texturing it with a pure color.
PS2: i know now how to see the spiral.mesh. since it is produced from red and green colore. just texture it with a yellow color (red+green) and you will see exactly the same original pattern
something like this:
CreateTexture(0,16,16)
StartDrawing(TextureOutput(0))
Box(0, 0, 16, 16,RGB(255,255,0))
StopDrawing()
CreateMaterial(0, TextureID(0))
DisableMaterialLighting(0, #True)

LoadMesh(#MESH, "spiral.mesh")
SetMeshMaterial(#MESH, MaterialID(0))
User avatar
Michael Vogel
Addict
Addict
Posts: 2823
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: 3D Prime numbers spiral

Post by Michael Vogel »

I think, IsPrime could be a little bit quicker, when only checking uneven numbers...

Haven't tested the following code, should work:

Code: Select all

Procedure IsPrime(Number.l)

	If Number&1

		Protected n=Sqr(number)

		n-(n&1)!1
		While n>1
			If number%n=0
				ProcedureReturn #False
			EndIf
			n-2
		Wend
		ProcedureReturn #True

	ElseIf Number=2
		ProcedureReturn #True

	Else
		ProcedureReturn #False

	EndIf

EndProcedure

n=1234567890
For i=0 To 1
	Debug IsPrime(n+i)
Next i
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: 3D Prime numbers spiral

Post by jassing »

I ran some simple tests -- and the original IsPrime() was much faster....

edit: x86 is faster than x64 too.
User avatar
Michael Vogel
Addict
Addict
Posts: 2823
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: 3D Prime numbers spiral

Post by Michael Vogel »

You're right, I was to optimistic, that it won't make a big difference to start checking for high dividers first, now I started PB and changed the check order to speed it up a little bit...

Code: Select all

Procedure OriginalIsPrime(Number.i)
	
	n = Sqr(number)
	For t = 2 To n
		If number % t = 0
			ProcedureReturn 0
		EndIf
	Next t

	ProcedureReturn 1
EndProcedure

Procedure IsPrime(Number.i)

	If Number&1

		If Number=1
			ProcedureReturn #False
			
		Else

			Protected n=Sqr(number)
			Protected t=3

			n-(n&1)!1
			While t<=n
				If number%t=0
					ProcedureReturn #False
				EndIf
				t+2
			Wend
			ProcedureReturn #True

		EndIf


	ElseIf Number=2
		ProcedureReturn #True

	Else
		ProcedureReturn #False

	EndIf

EndProcedure

#Max=1234567;890

c0=0
n0=ElapsedMilliseconds()
For i=0 To #Max
	c0+OriginalIsPrime(i)
Next i
n0-ElapsedMilliseconds()

c1=0
n1=ElapsedMilliseconds()
For i=0 To #Max
	c1+IsPrime(i)
Next i
n1-ElapsedMilliseconds()

MessageRequester("IsPrime",Str(c0)+"    "+Str(-n0)+"ms"+#CR$+Str(c1)+"    "+Str(-n1)+"ms")

Post Reply