-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
178 lines (126 loc) · 5.46 KB
/
main.cpp
File metadata and controls
178 lines (126 loc) · 5.46 KB
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
#include "ChaosFramework.h"
#include <iostream>
#include <memory>
class ChenAttractor : public chaos::AttractorEquation {
private:
float a, b, c;
std::vector<float> initialCondition;
public:
ChenAttractor(float a = 35.0f, float b = 3.0f, float c = 28.0f)
: a(a), b(b), c(c) {
initialCondition = {-10.0f, 0.0f, 37.0f};
}
void computeNextPoint(const float* current, float* next, float dt) const override {
next[0] = current[0] + dt * (a * (current[1] - current[0]));
next[1] = current[1] + dt * ((c - a) * current[0] - current[0] * current[2] + c * current[1]);
next[2] = current[2] + dt * (current[0] * current[1] - b * current[2]);
}
int getDimension() const override { return 3; }
std::vector<float> getDefaultInitialCondition() const override {
return initialCondition;
}
std::vector<float> getParameters() const override {
return {a, b, c};
}
std::string getName() const override {
return "Chen Attractor";
}
};
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action != GLFW_PRESS) return;
chaos::ChaosFramework* framework = static_cast<chaos::ChaosFramework*>(glfwGetWindowUserPointer(window));
switch (key) {
case GLFW_KEY_1:
std::cout << "Switching to Lorenz attractor" << std::endl;
framework->setEquation(std::make_shared<chaos::LorentzAttractor>());
break;
case GLFW_KEY_2:
std::cout << "Switching to Rossler attractor" << std::endl;
framework->setEquation(std::make_shared<chaos::RosslerAttractor>());
break;
case GLFW_KEY_3:
std::cout << "Switching to Chen attractor" << std::endl;
framework->setEquation(std::make_shared<ChenAttractor>());
break;
case GLFW_KEY_4:
std::cout << "Switching to Aizawa attractor" << std::endl;
framework->setEquation(std::make_shared<chaos::AizawaAttractor>());
break;
case GLFW_KEY_UP:
framework->setIterationsPerFrame(framework->getIterationsPerFrame() + 5);
std::cout << "Iterations per frame: " << framework->getIterationsPerFrame() << std::endl;
break;
case GLFW_KEY_DOWN:
if (framework->getIterationsPerFrame() > 5) {
framework->setIterationsPerFrame(framework->getIterationsPerFrame() - 5);
}
std::cout << "Iterations per frame: " << framework->getIterationsPerFrame() << std::endl;
break;
}
}
double lastX = 0, lastY = 0;
bool firstMouse = true;
float yaw = -90.0f, pitch = 0.0f;
void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
if (firstMouse) {
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
float xoffset = xpos - lastX;
float yoffset = lastY - ypos;
lastX = xpos;
lastY = ypos;
const float sensitivity = 0.1f;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch < -89.0f) pitch = -89.0f;
chaos::ChaosFramework* framework = static_cast<chaos::ChaosFramework*>(glfwGetWindowUserPointer(window));
glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
glm::vec3 cameraFront = glm::normalize(front);
float cameraDistance = 50.0f;
framework->setCameraPosition(glm::vec3(0.0f) - cameraFront * cameraDistance);
framework->setCameraTarget(glm::vec3(0.0f));
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
chaos::ChaosFramework* framework = static_cast<chaos::ChaosFramework*>(glfwGetWindowUserPointer(window));
float fov = framework->getCameraFov();
fov -= yoffset * 2.0f;
if (fov < 10.0f) fov = 10.0f;
if (fov > 90.0f) fov = 90.0f;
framework->setCameraFov(fov);
}
int main() {
chaos::ChaosFramework framework;
if (!framework.initialize(1024, 768, "Chaos Attractor Renderer")) {
std::cerr << "Failed to initialize framework" << std::endl;
return -1;
}
framework.setEquation(std::make_shared<chaos::LorentzAttractor>());
framework.setNumPoints(500000);
framework.setTimeStep(0.003f);
framework.setIterationsPerFrame(20);
framework.setPointSize(1.2f);
framework.setPointColor(glm::vec3(0.2f, 0.6f, 1.0f));
GLFWwindow* window = framework.getWindow();
glfwSetWindowUserPointer(window, &framework);
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
std::cout << "=== Chaos Attractor Renderer ===" << std::endl;
std::cout << "Press keys 1-3 to switch between attractors:" << std::endl;
std::cout << " 1 - Lorenz Attractor" << std::endl;
std::cout << " 2 - Rossler Attractor" << std::endl;
std::cout << " 3 - Chen Attractor" << std::endl;
std::cout << "Use mouse to rotate camera" << std::endl;
std::cout << "Use scroll wheel to zoom in/out" << std::endl;
std::cout << "Press UP/DOWN to increase/decrease iterations per frame" << std::endl;
std::cout << "Press ESC to exit" << std::endl;
framework.run();
return 0;
}