1+ #include <SDL.h>
2+ #include <time.h>
3+ #include <stdio.h>
4+ #include <stdbool.h>
5+
6+ #include "gui.h"
7+ #include "point.h"
8+ #include "dbscan.h"
9+ #include "gaussian_distribution.h"
10+
11+ int main ()
12+ {
13+ // Init SDL
14+ ////////////////////////////////////////////////////////////
15+
16+ // Define Window Width & Height
17+ const int WINDOW_WIDTH = 600 ;
18+ const int WINDOW_HEIGHT = 600 ;
19+
20+ // Create window and renderer
21+ SDL_Window * window = create_window (WINDOW_WIDTH , WINDOW_HEIGHT );
22+ SDL_Renderer * renderer = create_renderer (& window );
23+
24+ // Enable alpha blending
25+ SDL_SetRenderDrawBlendMode (renderer , SDL_BLENDMODE_BLEND );
26+
27+ // Set window color to black
28+ clear_window (& renderer );
29+
30+ ////////////////////////////////////////////////////////////
31+ // Generate k gaussian clusters dataset
32+ ////////////////////////////////////////////////////////////
33+
34+ // Init random number generator
35+ srand (time (NULL ));
36+
37+ const int N = 5000 ;
38+ Point dataset [N ];
39+
40+ const int k = 5 ;
41+ GaussianDistribution gaussian_distributions [k ];
42+
43+ for (int i = 0 ; i < k ; i ++ )
44+ {
45+ gaussian_distributions [i ].mu_x = ((double )rand ())/RAND_MAX * WINDOW_WIDTH * 0.8 + WINDOW_WIDTH * 0.1 ;
46+ gaussian_distributions [i ].mu_y = ((double )rand ())/RAND_MAX * WINDOW_HEIGHT * 0.8 + WINDOW_HEIGHT * 0.1 ;
47+ gaussian_distributions [i ].sigma_x = ((double )rand ())/RAND_MAX * 40 + 10 ;
48+ gaussian_distributions [i ].sigma_y = ((double )rand ())/RAND_MAX * 40 + 10 ;
49+ }
50+
51+ generate_gaussian_clusters_dataset (dataset , N , gaussian_distributions , k );
52+
53+ draw_classified_dataset (dataset , N , & renderer );
54+ SDL_RenderPresent (renderer );
55+
56+ ///////////////////////////////////////////////////////////////
57+ // Density Based Spatial Clustering of applications with Noise
58+ // (DBSCAN) Algorithm
59+ ///////////////////////////////////////////////////////////////
60+
61+ // Algorithm hyper-parameters
62+ double eps = 5 ;
63+ double minPts = 10 ;
64+
65+ int cluster_counter = 0 ;
66+
67+ for (int i = 0 ; i < N ; i ++ )
68+ {
69+
70+ // Check if point was already processed
71+ // in the inner loop
72+ if (dataset [i ].label != -1 )
73+ {
74+ continue ;
75+ }
76+
77+ Vector * neighbors = find_neighbors (dataset ,N , dataset [i ], eps , BRUTE );
78+
79+ if ( neighbors -> size < minPts )
80+ {
81+ dataset [i ].label = -2 ;
82+ free (neighbors -> array );
83+ free (neighbors );
84+ continue ;
85+ }
86+
87+ cluster_counter ++ ;
88+
89+ // Assign to point the current cluster number
90+ dataset [i ].label = cluster_counter ;
91+
92+
93+ for (int j = 0 ; j < neighbors -> size ; j ++ )
94+ {
95+ if ( neighbors -> array [j ]-> x == dataset [i ].x & neighbors -> array [j ]-> y == dataset [i ].y )
96+ {
97+ continue ;
98+ }
99+
100+ if (j %10 == 0 )
101+ {
102+ clear_window (& renderer );
103+ draw_classified_dataset (dataset , N , & renderer );
104+ SDL_RenderPresent (renderer );
105+ }
106+
107+
108+ if (neighbors -> array [j ]-> label == -2 )
109+ {
110+ neighbors -> array [j ]-> label = cluster_counter ;
111+ }
112+
113+ if (neighbors -> array [j ]-> label != -1 )
114+ {
115+ continue ;
116+ }
117+
118+ neighbors -> array [j ]-> label = cluster_counter ;
119+
120+ Vector * n2 = find_neighbors (dataset , N , * neighbors -> array [j ], eps , BRUTE );
121+
122+ for (int k = 0 ; k < n2 -> size ; k ++ )
123+ {
124+ vector_push_back (neighbors , n2 -> array [k ]);
125+ }
126+
127+ free (n2 -> array );
128+ free (n2 );
129+ }
130+
131+ // free dynamic neighbors array
132+ free (neighbors -> array );
133+ free (neighbors );
134+
135+ }
136+
137+ printf ("Found %d clusters\n" ,cluster_counter );
138+
139+ clear_window (& renderer );
140+ SDL_SetRenderDrawColor (renderer , 0 , 0 , 0 , 255 ); // RGBA
141+ SDL_RenderClear (renderer );
142+ draw_classified_dataset (dataset , N , & renderer );
143+ SDL_RenderPresent (renderer );
144+
145+ // SDL Visualization Loop
146+ SDL_Event e ;
147+ bool quit = false;
148+ while (!quit )
149+ {
150+
151+ while (SDL_PollEvent (& e ) != 0 )
152+ {
153+
154+ if (e .type == SDL_QUIT )
155+ {
156+ quit = 1 ;
157+ }
158+ }
159+ }
160+
161+
162+ return 0 ;
163+ }
0 commit comments