aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <aiden.woodruff@gmail.com>2023-12-25 16:57:10 -0600
committerAiden Woodruff <aiden.woodruff@gmail.com>2023-12-25 16:57:10 -0600
commitcce67aeadd283a09356ae8101bfc6818924f4a86 (patch)
treeabdaa8ee1fbe24205089a2bf2dfe598c181d04f4
downloadstars-cce67aeadd283a09356ae8101bfc6818924f4a86.tar.gz
stars-cce67aeadd283a09356ae8101bfc6818924f4a86.tar.bz2
stars-cce67aeadd283a09356ae8101bfc6818924f4a86.zip
Initial commit
Signed-off-by: Aiden Woodruff <aiden.woodruff@gmail.com>
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt9
-rw-r--r--ConstellationApp.h36
-rw-r--r--ConstellationController.h81
-rw-r--r--ConstellationModel.h98
-rw-r--r--ConstellationView.h72
-rw-r--r--config.sh3
-rw-r--r--main.cc7
8 files changed, 307 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..567609b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
build/
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..37b4227
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,9 @@
1cmake_minimum_required(VERSION 3.8)
2project(idkproject VERSION 0 LANGUAGES CXX)
3
4find_package(SFML 2 REQUIRED COMPONENTS graphics)
5
6add_executable(main main.cc)
7target_compile_options(main PUBLIC -g)
8target_link_libraries(main PRIVATE sfml-graphics)
9target_compile_features(main PRIVATE cxx_auto_type cxx_range_for) \ No newline at end of file
diff --git a/ConstellationApp.h b/ConstellationApp.h
new file mode 100644
index 0000000..5fa9ce0
--- /dev/null
+++ b/ConstellationApp.h
@@ -0,0 +1,36 @@
1#include "ConstellationModel.h"
2#include "ConstellationView.h"
3#include "ConstellationController.h"
4
5namespace Constellation {
6class App {
7 Model m;
8 View v;
9 Controller c;
10 int screenwidth, screenheight;
11
12 public:
13 /**
14 * @brief Construct a new App object.
15 *
16 * @param sw Screen width.
17 * @param sh Screen height.
18 * @param sr Star radius.
19 * @param n Star count.
20 * @param minc Minimum constellation number.
21 */
22 App(int sw, int sh, int sr, int n, int minc):
23 m(n, minc, sw, sh, sr), v(sw, sh, sr), c(&m, &v) {}
24
25 void run() {
26 v.make_window();
27 while (c.isRunning()) {
28 c.collect_input();
29 c.advance_state();
30 v.display();
31 sf::sleep(sf::milliseconds(1));
32 }
33 v.close_window();
34 }
35};
36}
diff --git a/ConstellationController.h b/ConstellationController.h
new file mode 100644
index 0000000..24b5328
--- /dev/null
+++ b/ConstellationController.h
@@ -0,0 +1,81 @@
1#include "ConstellationModel.h"
2#include "ConstellationView.h"
3
4#include <SFML/System.hpp>
5
6#ifndef CONSTELLATION_CONTROLLER_H_
7#define CONSTELLATION_CONTROLLER_H_
8
9namespace Constellation {
10 class Controller {
11 Model *model;
12 View *view;
13 bool running;
14
15 enum class Mode : int {
16 idle = 0,
17 stars,
18 edges
19 } mode;
20
21 Model::EdgeIterator eIt;
22 Model::VertexIterator vIt;
23
24 public:
25 Controller(Model *m, View *v) : model(m), view(v), running(true),
26 mode(Mode::idle) {}
27
28 bool isRunning() const { return running; }
29
30 void collect_input() {
31 sf::Event event;
32 while (view->window->pollEvent(event)) {
33 if (event.type == sf::Event::Closed) {
34 running = false;
35 } else if (mode == Mode::idle) {
36 if (event.type == sf::Event::KeyReleased) {
37 if (event.key.code == sf::Keyboard::R) {
38 mode = Mode::stars;
39 model->randomize_stars();
40 view->clear_stars();
41 view->clear_edges();
42 vIt = model->vbegin();
43 } else if (event.key.code == sf::Keyboard::G) {
44 mode = Mode::edges;
45 model->generate_edges();
46 view->clear_edges();
47 eIt = model->ebegin();
48 }
49 }
50 }
51 }
52 }
53
54 void advance_state() {
55 switch (mode) {
56 case Mode::stars:
57 if (vIt != model->vend()) {
58 view->add_star(*vIt);
59 ++vIt;
60 } else {
61 mode = Mode::idle;
62 }
63 break;
64 case Mode::edges:
65 if (eIt != model->eend()) {
66 std::pair<sf::Vector2f,sf::Vector2f> e = model->edge_data(*eIt);
67 view->add_edge(sf::Vertex(e.first), sf::Vertex(e.second));
68 ++eIt;
69 } else {
70 mode = Mode::idle;
71 }
72 break;
73 case Mode::idle:
74 default:
75 break;
76 }
77 }
78 };
79} // namespace Constellation
80
81#endif // CONSTELLATION_CONTROLLER_H_
diff --git a/ConstellationModel.h b/ConstellationModel.h
new file mode 100644
index 0000000..44b1b32
--- /dev/null
+++ b/ConstellationModel.h
@@ -0,0 +1,98 @@
1#include <random>
2#include <vector>
3#include <utility>
4#include <iostream>
5
6#include <SFML/System.hpp>
7
8#ifndef CONSTELLATION_MODEL_H_
9#define CONSTELLATION_MODEL_H_
10
11namespace Constellation {
12 class Model {
13 using Edge = std::pair<int, int>;
14
15 int stars, min_constellations;
16 std::mt19937 engine;
17 std::uniform_int_distribution<int> x_dist, y_dist;
18 std::vector<sf::Vector2f> vertices;
19 std::vector<Edge> edges;
20 public:
21 Model(int n, int minc, int sw, int sh, int sr) :
22 stars(n), min_constellations(minc),
23 x_dist(sr, sw - sr), y_dist(sr, sh - sr) {
24 engine = std::mt19937(std::random_device{}());
25 }
26 using EdgeIterator = std::vector<Edge>::const_iterator;
27 using VertexIterator = std::vector<sf::Vector2f>::const_iterator;
28
29 EdgeIterator ebegin() const { return edges.cbegin(); }
30 EdgeIterator eend() const { return edges.cend(); }
31 VertexIterator vbegin() const { return vertices.cbegin(); }
32 VertexIterator vend() const { return vertices.cend(); }
33
34
35 std::pair<sf::Vector2f, sf::Vector2f> edge_data(const Edge& e) {
36 return {vertices[e.first], vertices[e.second]};
37 }
38
39 void randomize_stars () {
40 vertices.clear();
41 edges.clear();
42 for (int i = 0; i < stars; ++i) {
43 float x = x_dist(engine), y = y_dist(engine);
44 vertices.push_back({x, y});
45 }
46 }
47
48 private:
49 float distance (int u, int v) {
50 float xdiff = vertices[v].x - vertices[u].x,
51 ydiff = vertices[v].y - vertices[u].y;
52 return xdiff * xdiff + ydiff * ydiff;
53 }
54 public:
55 void generate_edges() {
56 if (vertices.empty()) return;
57 edges.clear();
58
59 // Generate all possible edges.
60 std::vector<std::pair<float, Edge>> possible_edges;
61 possible_edges.reserve(stars * stars);
62 for (int i = 0; i < stars; ++i) {
63 for (int j = 0; j < stars; ++j) {
64 if (i != j)
65 possible_edges.push_back({distance(i, j), {i, j}});
66 }
67 }
68 // Sort in order of min distance.
69 std::sort(possible_edges.begin(), possible_edges.end());
70
71 std::vector<std::vector<int>> v_sets(stars); // Sets of vertices.
72 std::vector<int> v_s(stars, -1); // Owning set of each vertex.
73 for (int i = 0; i < stars; ++i) {
74 v_sets[i].push_back(i);
75 v_s[i] = i;
76 }
77
78 // Loop through min edges and and connect disconnected components.
79 for (int p = 0, c = stars ; p < possible_edges.size() &&
80 c > min_constellations; ++p) {
81 const Edge& e = possible_edges[p].second;
82 if (v_s[e.first] != v_s[e.second]) {
83 edges.push_back(e);
84 int V = v_s[e.first], U = v_s[e.second];
85 for (int i = 0; i < v_sets[U].size(); ++i) {
86 int u = v_sets[U][i];
87 v_s[u] = V;
88 v_sets[V].push_back(u);
89 }
90 v_sets[U].clear();
91 c--;
92 }
93 }
94 }
95 };
96} // namespace Constellation
97
98#endif // CONSTELLATION_MODEL_H_
diff --git a/ConstellationView.h b/ConstellationView.h
new file mode 100644
index 0000000..491afe3
--- /dev/null
+++ b/ConstellationView.h
@@ -0,0 +1,72 @@
1#include <iostream>
2#include <vector>
3
4#include <SFML/Graphics.hpp>
5
6#ifndef CONSTELLATION_VIEW_H_
7#define CONSTELLATION_VIEW_H_
8
9namespace Constellation {
10 class View {
11 int width, height, star_radius;
12 sf::RenderWindow *window;
13 std::vector<sf::Vector2f> starPos;
14 sf::VertexArray edges;
15 sf::CircleShape star;
16 public:
17 View(int w, int h, int sr) : width(w), height(h), star_radius(sr),
18 window(nullptr), star(star_radius), edges(sf::Lines) {
19 star.setOrigin(star_radius, star_radius);
20 }
21
22 ~View() {
23 if (window) {
24 delete window;
25 }
26 }
27
28 void make_window () {
29 if (!window) {
30 window = new sf::RenderWindow(sf::VideoMode(width, height), "Constellations");
31 }
32 }
33
34 void close_window () {
35 window->close();
36 }
37
38 void add_star(const sf::Vector2f& v) {
39 starPos.push_back(v);
40 }
41
42 void clear_stars() {
43 starPos.clear();
44 }
45
46 void add_edge(const sf::Vertex& v, const sf::Vertex& u) {
47 edges.append(v);
48 edges.append(u);
49 }
50
51 void clear_edges() {
52 edges.clear();
53 }
54
55 void print_done() {
56 std::cout << "Done." << std::endl;
57 }
58
59 void display() {
60 window->clear();
61 window->draw(edges);
62 for (const sf::Vector2f& p : starPos) {
63 star.setPosition(p);
64 window->draw(star);
65 }
66 window->display();
67 }
68
69 friend class Controller;
70 };
71} // namespace Constellation
72#endif // CONSTELLATION_VIEW_H_
diff --git a/config.sh b/config.sh
new file mode 100644
index 0000000..58c7d2c
--- /dev/null
+++ b/config.sh
@@ -0,0 +1,3 @@
1#!/usr/bin/env sh
2
3cmake -S . -B build
diff --git a/main.cc b/main.cc
new file mode 100644
index 0000000..f0c5fb6
--- /dev/null
+++ b/main.cc
@@ -0,0 +1,7 @@
1#include "ConstellationApp.h"
2
3int main () {
4 Constellation::App app(1200, 675, 3, 400, 10);
5 app.run();
6 return 0;
7}