Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SFML/Graphics.hpp>
- #include <SFML/Window.hpp>
- #include <algorithm>
- #include <cmath>
- #include <iostream>
- #include <queue>
- #include <vector>
- #include <stack>
- sf::Color BackgroundColor = sf::Color(34, 40, 49), ElementColor = sf::Color(254, 233, 225),
- TextColor = sf::Color(232, 197, 71), ActionColor = sf::Color(217, 3, 104), GraphColor1 = sf::Color(80, 220, 100),
- GraphColor2 = sf::Color(70, 130, 191), GraphColor3 = sf::Color(157, 62, 70),
- FillColor = sf::Color(57, 62, 70), MeshColor = sf::Color(54, 60, 69);
- const int plus = 1, minus = 2, mult = 3, divide = 4, power = 5, sinus = 6, cosinus = 7, sqarert = 8, lg = 9;
- struct cord {
- double x = 0;
- double y = 0;
- int contains = 0;
- };
- struct OperationTree {
- float num = 0;
- int sign = 0;
- // -1 -- x, 0 -- none, 1 -- +, 2 -- -, 3 -- *, 4 -- /, 5 -- ^, 6 -- sin, 7 -- cos, 8 -- sqrt, 9 -- lg.
- OperationTree* root = nullptr;
- OperationTree* left = nullptr;
- OperationTree* right = nullptr;
- OperationTree* next = nullptr;
- bool check(cord& point, double precision) {
- double y = value(root, point.x);
- return y <= point.y + precision || y >= point.y - precision;
- }
- float value(OperationTree* search, float x) {
- if (search == nullptr) return 0;
- if (search->sign > 0) {
- if (search->sign == plus) {
- return value(search->left, x) + value(search->right, x);
- }
- if (search->sign == minus) {
- return value(search->left, x) - value(search->right, x);
- }
- if (search->sign == mult) {
- return value(search->left, x) * value(search->right, x);
- }
- if (search->sign == divide) {
- float left = value(search->left, x), right = value(search->right, x);
- if (right == 0) throw right;
- return left / right;
- }
- if (search->sign == power) {
- return pow(value(search->left, x), trunc(value(search->right, x)));
- }
- if (search->sign == sinus) {
- return std::sin(value(search->left, x));
- }
- if (search->sign == cosinus) {
- return std::cos(value(search->left, x));
- }
- if (search->sign == sqarert) {
- return std::sqrt(value(search->left, x));
- }
- if (search->sign == lg) {
- float val = value(search->left, x);
- if (val <= 0) throw val;
- return std::log10(val);
- }
- }
- else {
- return search->num;
- }
- }
- void placeValues(float x, OperationTree* search) {
- if (search == nullptr) return;
- if (search->sign == -1) search->num = x;
- placeValues(x, search->left);
- placeValues(x, search->right);
- }
- int create(std::string string) {
- std::stack<int> stack;
- OperationTree* process = nullptr;
- int num = 0;
- bool lastnum = false;
- for (int i = 0; i < string.size(); ++i) {
- char let = string[i];
- if (let == ' ') continue;
- if (let >= '0' && let <= '9') {
- num *= 10;
- num += let - '0';
- lastnum = true;
- }
- else if (let == 'x') {
- lastnum = true;
- if (num != 0) {
- OperationTree* numAdd = new OperationTree;
- numAdd->sign = -1;
- numAdd->next = process;
- process = numAdd;
- }
- else {
- num = -1;
- }
- }
- else {
- if (let == '(') {
- stack.push(-2);
- continue;
- }
- if (let == ')') {
- if (lastnum) {
- OperationTree* numAdd = new OperationTree;
- if (num == -1) {
- numAdd->sign = -1;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- else {
- numAdd->num = num;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- lastnum = false;
- }
- while (stack.size() != 0 && stack.top() != -2) {
- if (stack.top() < sinus) {
- if (process == nullptr) return 1;
- if (process->next == nullptr) return 2;
- OperationTree* left = process->next, * right = process;
- process = process->next->next;
- left->next = nullptr;
- right->next = nullptr;
- OperationTree* newNode = new OperationTree;
- newNode->sign = stack.top();
- newNode->left = left;
- newNode->right = right;
- newNode->next = process;
- process = newNode;
- stack.pop();
- continue;
- }
- if (stack.top() >= sinus) {
- if (process == nullptr) return 1;
- OperationTree* left = process;
- process = process->next;
- left->next = nullptr;
- OperationTree* newNode = new OperationTree;
- newNode->sign = stack.top();
- newNode->left = left;
- newNode->next = process;
- process = newNode;
- stack.pop();
- continue;
- }
- }
- if (stack.size() == 0) {
- return 4;
- }
- stack.pop();
- continue;
- }
- int sign = -4;
- if (let == '+') sign = plus;
- if (let == '-') sign = minus;
- if (let == '*') sign = mult;
- if (let == '/') sign = divide;
- if (let == '^') sign = power;
- if (let == 's') {
- let = string[++i];
- if (let == 'i') {
- let = string[++i];
- if (let == 'n') {
- sign = sinus;
- }
- else {
- return 3;
- }
- }
- else if (let == 'q') {
- let = string[++i];
- if (let == 'r') {
- let = string[++i];
- if (let == 't') {
- sign = sqarert;
- }
- else {
- return 7;
- }
- }
- else {
- return 8;
- }
- }
- else {
- return 9;
- }
- }
- else if (let == 'c') {
- let = string[++i];
- if (let == 'o') {
- let = string[++i];
- if (let == 's') {
- sign = cosinus;
- }
- else {
- return 10;
- }
- }
- else {
- return 11;
- }
- }
- else if (let == 'l') {
- let = string[++i];
- if (let == 'g') {
- sign = lg;
- }
- else {
- return 12;
- }
- }
- if (lastnum) {
- OperationTree* numAdd = new OperationTree;
- if (num == -1) {
- numAdd->sign = -1;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- else {
- numAdd->num = num;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- lastnum = false;
- }
- if (stack.size() == 0) {
- stack.push(sign);
- continue;
- }
- if (sign == -4) {
- return 6;
- }
- if (stack.top() >= sign && stack.top() < sinus) {
- if (process == nullptr) return 1;
- if (process->next == nullptr) return 2;
- OperationTree* left = process->next, * right = process;
- process = process->next->next;
- left->next = nullptr;
- right->next = nullptr;
- OperationTree* newNode = new OperationTree;
- newNode->sign = stack.top();
- newNode->left = left;
- newNode->right = right;
- newNode->next = process;
- process = newNode;
- stack.pop();
- stack.push(sign);
- continue;
- }
- if (stack.top() >= sinus) {
- if (process == nullptr) return 1;
- OperationTree* left = process;
- process = process->next;
- left->next = nullptr;
- OperationTree* newNode = new OperationTree;
- newNode->sign = stack.top();
- newNode->left = left;
- newNode->next = process;
- process = newNode;
- stack.pop();
- stack.push(sign);
- continue;
- }
- stack.push(sign);
- }
- }
- if (stack.size() != 0) {
- if (lastnum) {
- OperationTree* numAdd = new OperationTree;
- if (num == -1) {
- numAdd->sign = -1;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- else {
- numAdd->num = num;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- lastnum = false;
- }
- while (stack.size() != 0) {
- if (stack.top() < 0) {
- return 5;
- }
- if (stack.top() < sinus) {
- if (process == nullptr) return 1;
- if (process->next == nullptr) return 2;
- OperationTree* left = process->next, * right = process;
- process = process->next->next;
- left->next = nullptr;
- right->next = nullptr;
- OperationTree* newNode = new OperationTree;
- newNode->sign = stack.top();
- newNode->left = left;
- newNode->right = right;
- newNode->next = process;
- process = newNode;
- stack.pop();
- continue;
- }
- if (stack.top() >= sinus) {
- if (process == nullptr) return 1;
- OperationTree* left = process;
- process = process->next;
- left->next = nullptr;
- OperationTree* newNode = new OperationTree;
- newNode->sign = stack.top();
- newNode->left = left;
- newNode->next = process;
- process = newNode;
- stack.pop();
- continue;
- }
- }
- }
- if (lastnum) {
- OperationTree* numAdd = new OperationTree;
- if (num == -1) {
- numAdd->sign = -1;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- else {
- numAdd->num = num;
- numAdd->next = process;
- process = numAdd;
- num = 0;
- }
- lastnum = false;
- }
- root = process;
- return 0;
- }
- };
- /*void Recolor(sf::VertexArray& field, std::vector<cord> matrix, cord start, cord finish, double precision) {
- for (double i = start.x / precision; i < finish.x / precision; ++i) {
- for (double j = start.y; j < finish.y * precision; ++j) {
- if (matrix[i * j].contains == 1) {
- field[i * j].color = GraphColor1;
- }
- else if (matrix[i * j].contains == 2) {
- field[i * j].color = GraphColor2;
- }
- else if (matrix[i * j].contains == 3) {
- field[i * j].color = GraphColor3;
- }
- else {
- field[i * j].color = BackgroundColor;
- }
- }
- }
- }*/
- void ColorGraphs(sf::VertexArray& graph1, sf::VertexArray& graph2, sf::VertexArray& graph3, cord range, float precision) {
- for (int i = 0; i < range.x * 2 / precision; ++i) {
- graph1[i].color = GraphColor1;
- }
- for (int i = 0; i < range.x * 2 / precision; ++i) {
- graph2[i].color = GraphColor2;
- }
- for (int i = 0; i < range.x * 2 / precision; ++i) {
- graph3[i].color = GraphColor3;
- }
- }
- void BuildGraph(std::string string, sf::VertexArray& graph, cord range, float precision) {
- OperationTree* tree = new OperationTree;
- int k = tree->create(string);
- if (k != 0) {
- std::cout << "error number " << k;
- return;
- }
- int i = 0;
- for (float x = -range.x; x < range.x /*&& i < range.x * 2 / precision*/; x += precision) {
- tree->placeValues(x, tree->root);
- float y;
- try {
- y = tree->value(tree->root, x);
- }
- catch (float err) {
- y = 0;
- }
- sf::Vector2f pos = { x / precision, -y / precision };
- graph[i].position = pos;
- ++i;
- }
- }
- void CreateMesh(sf::VertexArray& mesh1, sf::VertexArray& mesh2, cord range, float precision) {
- int i = 0;
- for (float x = -range.x; x < range.x /*&& i < range.x * 2 / precision*/; x += precision * 512) {
- if (x == 0) {
- mesh1[i].position = sf::Vector2f(x, -range.y);
- mesh1[i].color = TextColor;
- ++i;
- mesh1[i].position = sf::Vector2f(x, range.y);
- mesh1[i].color = TextColor;
- ++i;
- continue;
- }
- mesh1[i].position = sf::Vector2f(x, -range.y);
- mesh1[i].color = MeshColor;
- ++i;
- mesh1[i].position = sf::Vector2f(x, range.y);
- mesh1[i].color = MeshColor;
- ++i;
- }
- i = 0;
- for (float x = -range.x; x < range.x /*&& i < range.x * 2 / precision*/; x += precision * 512) {
- if (x == 0) {
- mesh2[i].position = sf::Vector2f(-range.y, x);
- mesh2[i].color = TextColor;
- ++i;
- mesh2[i].position = sf::Vector2f(range.y, x);
- mesh2[i].color = TextColor;
- ++i;
- continue;
- }
- mesh2[i].position = sf::Vector2f(-range.y, x);
- mesh2[i].color = MeshColor;
- ++i;
- mesh2[i].position = sf::Vector2f(range.y, x);
- mesh2[i].color = MeshColor;
- ++i;
- }
- }
- void UpdateText(sf::Text& text, std::string s) { text.setString(s); }
- int main() {
- float precision = 0.03125;
- cord range;
- range.x = 512;
- range.y = 512;
- int selected = 0;
- sf::RenderWindow window(sf::VideoMode(1000, 1000), "FREE CUPA CHUPA", sf::Style::Titlebar | sf::Style::Close);
- std::string graphString1, graphString2, graphString3;
- sf::VertexArray graph1(sf::LinesStrip, range.x * 2 / precision), graph2(sf::LinesStrip, range.x * 2 / precision), graph3(sf::LinesStrip, range.x * 2 / precision);
- std::vector<cord> matrix(range.x * range.y * 4 / precision);
- sf::VertexArray mesh1(sf::Lines, range.x * 4 / precision / 512), mesh2(sf::Lines, range.x * 4 / precision / 512);
- sf::RectangleShape addNodeBox, removeNodeBox, addNBox;
- sf::Text grapText1, grapText2, grapText3;
- grapText1.setPosition(22, 944);
- grapText2.setPosition(342, 944);
- grapText3.setPosition(662, 944);
- grapText3.setOutlineThickness(2);
- grapText1.setOutlineThickness(2);
- grapText1.setFillColor(TextColor);
- grapText3.setFillColor(TextColor);
- grapText2.setOutlineThickness(2);
- grapText2.setFillColor(TextColor);
- addNodeBox.setSize(sf::Vector2f(300, 30));
- removeNodeBox.setSize(sf::Vector2f(300, 30));
- addNBox.setSize(sf::Vector2f(300, 30));
- addNodeBox.setPosition(20, 950);
- removeNodeBox.setPosition(340, 950);
- addNBox.setPosition(660, 950);
- addNodeBox.setOutlineThickness(2);
- addNodeBox.setOutlineColor(ElementColor);
- addNodeBox.setFillColor(FillColor);
- removeNodeBox.setOutlineThickness(2);
- removeNodeBox.setOutlineColor(ElementColor);
- removeNodeBox.setFillColor(FillColor);
- addNBox.setOutlineThickness(2);
- addNBox.setOutlineColor(ElementColor);
- addNBox.setFillColor(FillColor);
- sf::Font* font = new sf::Font;
- if (!font->loadFromFile("UbuntuMono-Regular.ttf")) {
- std::cout << "err\n";
- }
- grapText3.setFont(*font);
- grapText1.setFont(*font);
- grapText2.setFont(*font);
- ColorGraphs(graph1, graph2, graph3, range, precision);
- CreateMesh(mesh1, mesh2, range, precision);
- sf::View view(sf::Vector2f(0, 0), sf::Vector2f(1000, 1000));
- view.zoom(0.6);
- /*std::string s;
- std::cin >> s;
- OperationTree* tree = new OperationTree;
- int k = tree->create(s);
- if (k != 0) {
- std::cout << k << " err";
- return 0;
- }
- while (true) {
- float i;
- std::cin >> i;
- tree->placeValues(i, tree->root);
- std::cout << tree->value(tree->root, i) << "\n";
- }*/
- while (window.isOpen()) {
- sf::Event event;
- while (window.pollEvent(event))
- {
- if (event.type == sf::Event::TextEntered) {
- if (event.text.unicode != 8 && event.text.unicode != 9 && event.text.unicode != 13) {
- if (selected == 1) {
- graphString1 += event.text.unicode;
- UpdateText(grapText1, graphString1);
- }
- if (selected == 2) {
- graphString2 += event.text.unicode;
- UpdateText(grapText2, graphString2);
- }
- if (selected == 3) {
- graphString3 += event.text.unicode;
- UpdateText(grapText3, graphString3);
- }
- }
- }
- if (event.type == sf::Event::KeyPressed) {
- if (event.key.code == sf::Keyboard::BackSpace) {
- if (selected == 1) {
- if (graphString1.size() > 0) {
- graphString1.pop_back();
- UpdateText(grapText1, graphString1);
- }
- }
- if (selected == 2) {
- if (graphString2.size() > 0) {
- graphString2.pop_back();
- UpdateText(grapText2, graphString2);
- }
- }
- if (selected == 3) {
- if (graphString3.size() > 0) {
- graphString3.pop_back();
- UpdateText(grapText3, graphString3);
- }
- }
- }
- if (event.key.code == sf::Keyboard::Enter) {
- if (selected == 1) {
- BuildGraph(graphString1, graph1, range, precision);
- }
- if (selected == 2) {
- BuildGraph(graphString2, graph2, range, precision);
- }
- if (selected == 3) {
- BuildGraph(graphString3, graph3, range, precision);
- }
- selected = 0;
- removeNodeBox.setOutlineColor(ElementColor);
- addNodeBox.setOutlineColor(ElementColor);
- addNBox.setOutlineColor(ElementColor);
- }
- if (event.key.code == sf::Keyboard::P) {
- view.zoom(0.9);
- }
- if (event.key.code == sf::Keyboard::O) {
- view.zoom(1.1);
- }
- if (event.key.code == sf::Keyboard::Up) {
- view.move(0, -10 * view.getSize().x / 500);
- }
- if (event.key.code == sf::Keyboard::Down) {
- view.move(0, 10 * view.getSize().x / 500);
- }
- if (event.key.code == sf::Keyboard::Left) {
- view.move(-10 * view.getSize().x / 500, 0);
- }
- if (event.key.code == sf::Keyboard::Right) {
- view.move(10 * view.getSize().x / 500, 0);
- }
- }
- if (event.type == sf::Event::MouseButtonPressed) {
- if (addNodeBox.getGlobalBounds().contains(event.mouseButton.x,
- event.mouseButton.y)) {
- selected = 1;
- addNodeBox.setOutlineColor(ActionColor);
- removeNodeBox.setOutlineColor(ElementColor);
- addNBox.setOutlineColor(ElementColor);
- }
- else if (removeNodeBox.getGlobalBounds().contains(event.mouseButton.x,
- event.mouseButton.y)) {
- selected = 2;
- removeNodeBox.setOutlineColor(ActionColor);
- addNodeBox.setOutlineColor(ElementColor);
- addNBox.setOutlineColor(ElementColor);
- }
- else if (addNBox.getGlobalBounds().contains(event.mouseButton.x,
- event.mouseButton.y)) {
- selected = 3;
- addNBox.setOutlineColor(ActionColor);
- addNodeBox.setOutlineColor(ElementColor);
- removeNodeBox.setOutlineColor(ElementColor);
- }
- else {
- selected = 0;
- removeNodeBox.setOutlineColor(ElementColor);
- addNodeBox.setOutlineColor(ElementColor);
- addNBox.setOutlineColor(ElementColor);
- }
- }
- if (event.type == sf::Event::Closed) {
- window.close();
- }
- }
- window.clear(BackgroundColor);
- window.setView(view);
- window.draw(mesh1);
- window.draw(mesh2);
- window.draw(graph1);
- window.draw(graph2);
- window.draw(graph3);
- window.setView(window.getDefaultView());
- window.draw(addNodeBox);
- window.draw(addNBox);
- window.draw(removeNodeBox);
- window.draw(grapText1);
- window.draw(grapText3);
- window.draw(grapText2);
- window.display();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement