-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPrimeViewer.cpp
192 lines (162 loc) · 6 KB
/
PrimeViewer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#include <iostream>
#include <vector> // For vector
#include <cmath> // For floor, sqrt
#include "raylib.h"
#include "raymath.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
//Four ways to visualize the distribution of primes under 1,000,000
//Press 1, 2, 3 or 4 to change views
//Mode 1 = 3D view of distribution of primes in a 100x100x100 cube
//Mode 2 = 3D Sieve of Erathosthenes, showing primes in white, and eliminated non-primes in color
// The color represents the lowest prime factor which divides the non-prime.
// Use the sliders to display only the factors you want, and the check box to draw primes or not
//Mode 3 = Factor wheel, using sectors. Google "Wheel Factorization" for details.
//Mode 4 = Factor wheel, using points, which displays better when using a high factor base for the wheel
//Code and concepts by Eric J. Jenislawski.
//Thanks to Ramon Santamaria for the great RayLib and RayGUI libraries
using namespace std;
Color cubecolor(int f, int transparency) {
//separating color vals by 8, and using range 128-248, that leaves us: 15*15*15=3375 distinct colors
Color retcol;
int red, green, blue;
blue=120+(f%15)*8;
red=120+((f/15)%15)*8;
green=120+((f/255)%15)*8;
retcol=(Color){red,green,blue,transparency};
//cout<<"f="<<f<<" RGB"<<red<<" "<<green<<" "<<blue<<endl;
return retcol;
}
int main()
{
unsigned int maxval=1000000;
unsigned int bound;
int viewmode=1;
int transparency=64, lowerval=2, upperval=1000;
float factorbase=60;
int fbase=60;
bool boolDrawPrimes=true;
Vector3 position={0.0,0.0,0.0};
Vector3 posOffset={50,0,50};
Vector3 unitV={1.0,1.0,1.0};
Color cubecol={255,255,255,32};
vector<unsigned int> plist(maxval,1);
cout<<"Array initialized"<<endl;
for (uint i=2;i*i<maxval;i++){
if (plist[i]==1) {
bound=maxval/i;
for (uint x=bound;x>=i;x--){
if (plist[x]==1) {
plist[x*i]=i;
}
}
}
}
cout<<"Primes to "<<maxval<<" sieved."<<endl;
//Init raylib
InitWindow(1000, 1000, "Prime viewer");
SetWindowPosition(400,100);
Camera camera = { 0 };
camera.position = (Vector3){1.0, 0.0, 150.0};
camera.target=(Vector3){0.0,0.0,0.0};
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.fovy = 60.0f;
camera.projection = CAMERA_PERSPECTIVE;
SetCameraMode(camera,CAMERA_FREE);
SetTargetFPS(60);
//LOOP
while (!WindowShouldClose()){
//Process any input here
if (IsKeyPressed(KEY_ONE)) {viewmode=1;}
if (IsKeyPressed(KEY_TWO)) {viewmode=2;}
if (IsKeyPressed(KEY_THREE)) {viewmode=3;}
if (IsKeyPressed(KEY_FOUR)) {viewmode=4;}
//3D cube, only primes
if (viewmode==1) {
BeginDrawing();
ClearBackground(BLACK);
BeginMode3D(camera);
DrawGrid(100, 1.0f);
DrawGizmo({0,0,0});
for (uint i=2;i<maxval;i++){
if (plist[i]==1) {
position=(Vector3){(i % 100),((i/100) % 100),((i/10000) % 100)};
DrawCubeV(Vector3Subtract(position,posOffset),unitV,cubecol);
}
}
UpdateCamera(&camera);
EndMode3D();
DrawFPS(10,10);
EndDrawing();
}
//3D cube, all numbers by factor
if (viewmode==2) {
BeginDrawing();
ClearBackground(BLACK);
BeginMode3D(camera);
DrawGrid(100, 1.0f);
DrawGizmo({0,0,0});
for (uint i=2;i<maxval;i++){
if ((plist[i]==1)&&(boolDrawPrimes)) {
position=(Vector3){(i % 100),((i/100) % 100),((i/10000) % 100)};
DrawCubeV(Vector3Subtract(position,posOffset),unitV,RAYWHITE);
}
if ((plist[i]>lowerval)&&(plist[i]<upperval)) {
position=(Vector3){(i % 100),((i/100) % 100),((i/10000) % 100)};
DrawCubeV(Vector3Subtract(position,posOffset),unitV,cubecolor(plist[i],transparency));
}
}
UpdateCamera(&camera);
EndMode3D();
transparency=GuiSlider({200,10,100,10},"Transparency",transparency,16,255,true);
boolDrawPrimes=GuiCheckBox({350,10,10,10},"Draw Primes",boolDrawPrimes);
lowerval=GuiSlider({200,30,400,10},"Draw factors above:",lowerval,2,1000,true);
upperval=GuiSlider({200,50,400,10},"Draw factors below:",upperval,2,1000,true);
DrawFPS(10,10);
EndDrawing();
}
//Sector wheel
if (viewmode==3) {
float inrad, outrad;
int startangle,endangle;
Color segcolor=WHITE;
BeginDrawing();
ClearBackground(BLACK);
for (uint i=2;i<5000;i++) {
if (plist[i]==1) {
//segcolor=(Color){16*(i%15),16*(i%15),16*(i%15),64};
inrad=30+floor((i+30)/30)*3;
outrad=inrad+3;
startangle=(360/factorbase)*(i%fbase);
endangle=startangle+(360/factorbase)-1;
DrawRing((Vector2){500,500}, inrad, outrad, startangle, endangle, 20, segcolor);
//cout<<"i="<<i<<" inner rad="<<inrad<<" outer rad="<<outrad<<" Start angle="<<startangle<<" End angle="<<endangle<<endl;
}
}
GuiSpinner({5,30,100,40},&fbase,2,180,false);
factorbase = (float)fbase;
DrawFPS(10,10);
EndDrawing();
}
//Point wheel
if (viewmode==4) {
//cin>>factorbase;
float inrad,startangle;
BeginDrawing();
ClearBackground(BLACK);
for (uint i=2;i<50000;i++) {
if (plist[i]==1) {
//segcolor=(Color){16*(i%15),16*(i%15),16*(i%15),64};
inrad=30+floor((i+30)/30);
startangle=(3.14159*2.0/factorbase)*(float)(i%fbase);
DrawPixel(inrad*cos(startangle)+500,inrad*sin(startangle)+500,WHITE);
//cout<<"i="<<i<<" inner rad="<<inrad<<" Start angle="<<startangle<<endl;
}
}
GuiSpinner({5,30,100,40},&fbase,2,100,false);
factorbase = (float)fbase;
DrawFPS(10,10);
EndDrawing();
}
} //End LOOP
}