diff options
author | Jean Fabre-Monplaisir <jean-isaac-fm@live.fr> | 2015-02-01 19:06:59 +0100 |
---|---|---|
committer | Jean Fabre-Monplaisir <jean-isaac-fm@live.fr> | 2015-02-01 19:06:59 +0100 |
commit | 93cd8ba7c9ea2ee22bfcb828cd5190c4662a05b0 (patch) | |
tree | 8bdaae15ed9302409756a10faec053db5aea122a | |
parent | 2cb65f6726bbdecdc57b1544fe11fa6c586783dc (diff) | |
parent | 3b8497a4d6c71ac542a2992a645c00bf99d45390 (diff) | |
download | Robotique-Projet-93cd8ba7c9ea2ee22bfcb828cd5190c4662a05b0.tar.gz Robotique-Projet-93cd8ba7c9ea2ee22bfcb828cd5190c4662a05b0.zip |
Merge branch 'master' of github.com:Alexis211/Robotique
Conflicts:
problem.cpp
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | geom.hpp | 6 | ||||
-rw-r--r-- | main.cpp | 6 | ||||
-rw-r--r-- | problem.cpp | 19 | ||||
-rw-r--r-- | problem.hpp | 8 | ||||
-rw-r--r-- | ui.cpp | 205 | ||||
-rw-r--r-- | ui.hpp | 16 |
7 files changed, 240 insertions, 22 deletions
@@ -6,4 +6,4 @@ $(BIN): *.hpp $(OBJ) g++ -o $@ $(OBJ) -lm -lsfml-system -lsfml-window -lsfml-graphics -O2 -std=c++11 %.o: %.cpp *.hpp - g++ -c -o $@ $< -std=c++11 -O2 + g++ -c -o $@ $< -std=c++11 -O2 -Wall -Wextra @@ -27,7 +27,7 @@ struct vec { double angle() const { if (is_nil()) return 0; double xx = x / norm(); - double a = acos(x); + double a = acos(xx); return (y >= 0 ? a : -a + 2*M_PI); } @@ -144,6 +144,10 @@ struct circle { vec at_angle(double theta) const { return c + vec(r * cos(theta), r * sin(theta)); } + + bool intersects(vec p) const { + return (c - p).norm() <= r; + } }; struct circarc { @@ -4,9 +4,9 @@ int main() { hilare_a_param p; - p.l = 30; - p.r_c_car = 15; - p.r_c_trolley = 12; + p.l = 50; + p.r_c_car = 25; + p.r_c_trolley = 20; UI the_ui(&p); diff --git a/problem.cpp b/problem.cpp index fb7670b..28ef8fa 100644 --- a/problem.cpp +++ b/problem.cpp @@ -56,14 +56,29 @@ bool hilare_a_mvt::intersects(const problem &p) const { // ================================= // solution solution::direct_sol(const hilare_a &pos_a, const hilare_a &pos_b) { + vector<hilare_a_mvt> sol; + // TODO: try different possibilities and chose the shortest one - return solution(vector<hilare_a_mvt>()); + hilare_a_mvt mvt; + mvt.from = pos_a; + mvt.to = pos_b; + mvt.is_arc = false; + // la suite à compléter + sol.push_back(mvt); + + return solution(sol); } // =============================== // // IMPLEMENTATION FOR CLASS SOLVER // // =============================== // -// TODO +solver::solver() { + // nothing ? +} + +solver_internal solver::peek_internal() { + return _d; +} /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/problem.hpp b/problem.hpp index 3fc3054..f268d55 100644 --- a/problem.hpp +++ b/problem.hpp @@ -7,6 +7,7 @@ struct obstacle { circle c; + obstacle(circle cc) : c(cc) {} }; struct hilare_a_param { @@ -51,6 +52,7 @@ struct hilare_a_mvt { // deux étapes dans le mouvement : // - bien orienter la voiture (c'est l'angle dtheta_before) // - avancer/reculer sur le cercle (c'est l'angle domega) + hilare_a_mvt() : center(0, 0) {} hilare_a from, to; @@ -88,14 +90,14 @@ struct solver_internal { // intermediate data for the solver // represents a graph of randomly chosen positions and simple solutions between them std::vector<hilare_a> pts; - std::map<int, std::map<int, hilare_a_mvt> > paths; + std::map<int, std::map<int, solution> > paths; }; class solver { // mutex-protected asynchronous structure private: - //todo + solver_internal _d; public: solver(); @@ -103,6 +105,8 @@ class solver { void start(const problem &p); bool finished(); solution get_solution(); + + solver_internal peek_internal(); }; @@ -1,19 +1,30 @@ +#include <iostream> + #include "ui.hpp" /* All modes : - h, j, k, l : move around - i, o : zoom in/out - + Main mode (command mode) : + - s : select start pos + - e : select end pos + - a : add obstacle + - d : delete obstacle under mouse pointer + Select modes : no other keys */ -UI::UI(hilare_a_param *p) { +using namespace std; + +UI::UI(hilare_a_param *p) : _sel_obs(vec(0,0), 0) { _param = p; _p.begin_pos.param = _p.end_pos.param = p; _view.x0 = _view.y0 = 0; _view.zoom = 1; + + _mode = M_NORMAL; } void UI::run() { @@ -32,8 +43,24 @@ void UI::run() { if (ev.type == sf::Event::TextEntered) { int k = ev.text.unicode; - // TODO + if (k == 'h') { + _view.x0 -= 20 / _view.zoom; + } else if (k == 'j') { + _view.y0 += 20 / _view.zoom; + } else if (k == 'k') { + _view.y0 -= 20 / _view.zoom; + } else if (k == 'l') { + _view.x0 += 20 / _view.zoom; + } else if (k == 'i') { + _view.zoom *= 1.1; + } else if (k == 'o') { + _view.zoom /= 1.1; + } } + + if (_mode == M_NORMAL) handle_normal(ev); + if (_mode == M_INS_OBSTACLE) handle_ins_obs(ev); + if (_mode == M_SEL_BEGIN || _mode == M_SEL_END) handle_sel_pos(ev); } _win.clear(sf::Color::Black); @@ -42,10 +69,113 @@ void UI::run() { render_solution(); render_problem(); + if (_mode == M_INS_OBSTACLE) + render_circle(_sel_obs, sf::Color::Transparent, sf::Color::White, 0); + if (_mode == M_SEL_BEGIN || _mode == M_SEL_END) + render_pos(_sel_pos, sf::Color::White); + _win.display(); } } +void UI::handle_normal(const sf::Event &ev) { + if (ev.type == sf::Event::TextEntered) { + int k = ev.text.unicode; + + if (k == 's') { + _mode = M_SEL_BEGIN; + _sel_step = S_XY; + _sel_pos = _p.begin_pos; + vec p = mouse_coord(); + _sel_pos.x = p.x; + _sel_pos.y = p.y; + } + if (k == 'e') { + _mode = M_SEL_END; + _sel_step = S_XY; + _sel_pos = _p.end_pos; + vec p = mouse_coord(); + _sel_pos.x = p.x; + _sel_pos.y = p.y; + } + if (k == 'a') { + _mode = M_INS_OBSTACLE; + _sel_step = S_XY; + _sel_obs.c = mouse_coord(); + _sel_obs.r = 20 / _view.zoom; + } + if (k == 'd') { + vec p = mouse_coord(); + vector<obstacle> o2; + for(auto& i: _p.obstacles) { + if (!i.c.intersects(p)) o2.push_back(i); + } + _p.obstacles = o2; + } + } +} + +void UI::handle_ins_obs(const sf::Event &ev) { + if (_sel_step == S_XY) { + if (ev.type == sf::Event::MouseMoved) { + _sel_obs.c = mouse_coord(); + } else if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Left) { + _sel_step = S_RADIUS; + } + } else { + if (ev.type == sf::Event::MouseMoved) { + _sel_obs.r = (mouse_coord() - _sel_obs.c).norm(); + } else if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Left) { + _p.obstacles.push_back(obstacle(_sel_obs)); + _mode = M_NORMAL; + } + } + + if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Right) { + _mode = M_NORMAL; // cancel out + } +} + +void UI::handle_sel_pos(const sf::Event &ev) { + if (_sel_step == S_XY) { + if (ev.type == sf::Event::MouseMoved) { + vec p = mouse_coord(); + _sel_pos.x = p.x; + _sel_pos.y = p.y; + } else if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Left) { + _sel_step = S_THETA; + } + } else if (_sel_step == S_THETA) { + if (ev.type == sf::Event::MouseMoved) { + _sel_pos.theta = (mouse_coord() - _sel_pos.pos()).angle(); + } else if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Left) { + _sel_step = S_PHI; + } + } else { + if (ev.type == sf::Event::MouseMoved) { + _sel_pos.phi = (mouse_coord() - _sel_pos.pos()).angle() - _sel_pos.theta; + } else if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Left) { + if (_mode == M_SEL_BEGIN) { + _p.begin_pos = _sel_pos; + } else { + _p.end_pos = _sel_pos; + } + _mode = M_NORMAL; // cancel out + } + } + + if (ev.type == sf::Event::MouseButtonReleased + && ev.mouseButton.button == sf::Mouse::Button::Right) { + _mode = M_NORMAL; // cancel out + } +} + void UI::render_circle(const circle &c, sf::Color border, sf::Color inside, int w) { double r = c.r * _view.zoom; sf::CircleShape a(r); @@ -60,6 +190,17 @@ void UI::render_circle(const circle &c, sf::Color border, sf::Color inside, int void UI::render_pos(const hilare_a &pos, sf::Color c) { render_circle(circle(pos.pos(), pos.param->r_c_car), c, sf::Color::Transparent, 2); + sf::ConvexShape l; + + l.setPointCount(3); + l.setPoint(0, to_view(pos.pos() - vec::from_polar(pos.param->r_c_car * 0.8, pos.theta + M_PI / 2))); + l.setPoint(1, to_view(pos.pos() + vec::from_polar(pos.param->r_c_car * 0.8, pos.theta + M_PI / 2))); + l.setPoint(2, to_view(pos.pos() + vec::from_polar(pos.param->r_c_car * 0.8, pos.theta))); + + l.setFillColor(c); + + _win.draw(l); + render_circle(circle(pos.pos_trolley(), pos.param->r_c_trolley), c, sf::Color::Transparent, 2); } @@ -67,8 +208,34 @@ void UI::render_obstacle(const obstacle &o) { render_circle(o.c, sf::Color::Transparent, sf::Color(100, 100, 100), 0); } -void UI::render_mvt(const hilare_a_mvt &m) { - // TODO +void UI::render_mvt(const hilare_a_mvt &m, sf::Color c) { + if (m.is_arc) { + sf::Vertex l[20]; + + l[0] = sf::Vertex(to_view(m.from.pos()), c); + + double th = (m.from.pos() - m.center).angle(); + double r = (m.from.pos() - m.center).norm(); + for (int i = 1; i < 19; i++) { + l[i] = sf::Vertex(to_view(m.center + vec::from_polar(r, th + m.domega * i / 20)), c); + } + + l[19] = sf::Vertex(to_view(m.to.pos()), c); + + _win.draw(l, 20, sf::Lines); + } else { + sf::Vertex l[] = { + sf::Vertex(to_view(m.from.pos()), c), + sf::Vertex(to_view(m.to.pos()), c), + }; + _win.draw(l, 2, sf::Lines); + } +} + +void UI::render_sol(const solution &s, sf::Color c) { + for (auto i: s.movement) { + render_mvt(i, c); + } } void UI::render_problem() { @@ -84,20 +251,40 @@ void UI::render_solution() { for (auto i = _s.movement.begin(); i != _s.movement.end(); i++) { if (i != _s.movement.begin()) render_pos(i->from, sf::Color::Green); - render_mvt(*i); } + render_sol(_s.movement, sf::Color::Green); } void UI::render_internal() { - // TODO + solver_internal x = _solver.peek_internal(); + + for (auto& p: x.pts) { + render_pos(p, sf::Color(42, 42, 42)); + } + + for (auto& kv: x.paths) { + for (auto kv2: kv.second) { + render_sol(kv2.second, sf::Color(42, 42, 42)); + } + } } sf::Vector2f UI::to_view(const vec &p) { - return sf::Vector2f((p.x - _view.x0) * _view.zoom, (p.y - _view.y0) * _view.zoom); + sf::Vector2u s = _win.getSize(); + return sf::Vector2f((p.x - _view.x0) * _view.zoom + (s.x/2), (p.y - _view.y0) * _view.zoom + (s.y/2)); } vec UI::from_view(const sf::Vector2f &p) { - return vec(p.x / _view.zoom + _view.x0, p.y / _view.zoom + _view.y0); + sf::Vector2u s = _win.getSize(); + return vec((p.x - s.x/2) / _view.zoom + _view.x0, (p.y - s.y/2) / _view.zoom + _view.y0); +} + +vec UI::from_view(const sf::Vector2i &p) { + return from_view(sf::Vector2f(p.x, p.y)); +} + +vec UI::mouse_coord() { + return from_view(sf::Mouse::getPosition() - _win.getPosition()); } /* vim: set ts=4 sw=4 tw=0 noet :*/ @@ -10,7 +10,6 @@ enum { M_NORMAL, M_INS_OBSTACLE, - M_DEL_OBSTACLE, M_SEL_BEGIN, M_SEL_END }; @@ -19,7 +18,6 @@ enum { S_XY, S_THETA, S_PHI, - S_CENTER, S_RADIUS }; @@ -28,8 +26,8 @@ class UI { hilare_a_param *_param; problem _p; - solution _s; + solver _solver; struct { double x0, y0, zoom; @@ -40,14 +38,22 @@ class UI { // interaction mode int _mode, _sel_step; + hilare_a _sel_pos; + circle _sel_obs; public: UI(hilare_a_param *p); + void handle_normal(const sf::Event &ev); + void handle_ins_obs(const sf::Event &ev); + void handle_sel_pos(const sf::Event &ev); + void render_circle(const circle& c, sf::Color border, sf::Color inside, int linewidth); + void render_pos(const hilare_a &pos, sf::Color c); void render_obstacle(const obstacle &o); - void render_mvt(const hilare_a_mvt &m); + void render_mvt(const hilare_a_mvt &m, sf::Color c); + void render_sol(const solution &s, sf::Color c); void render_problem(); void render_solution(); @@ -55,6 +61,8 @@ class UI { sf::Vector2f to_view(const vec &p); vec from_view(const sf::Vector2f &p); + vec from_view(const sf::Vector2i &p); + vec mouse_coord(); void run(); }; |