diff --git a/triangulation.cpp b/triangulation.cpp index 0d064ec..ce62c73 100644 --- a/triangulation.cpp +++ b/triangulation.cpp @@ -8,36 +8,11 @@ #include #include #include +#include +#include +#include +#include "libpoly.h" -#ifndef libpoly092986127876181939u43295237 -#define libpoly092986127876181939u43295237 - -extern void test(void); // prints to stdout to test linking - -#include -#include - -struct LP_Point { - double x, y; -}; - -struct LP_Polygon { - std::vector< LP_Point > points; - LP_Polygon(std::vector< LP_Point >&& p) : points(p) {} -}; - -struct LP_Task : public std::enable_shared_from_this< LP_Task > { - LP_Polygon p; - double minimal_triangulation; -}; - -using LP_Task_p = std::shared_ptr< LP_Task >; - -extern LP_Task_p pickup_task(); //je thread safe, nebo si to musím ošéfit? -extern bool submit_task(LP_Task_p&&); -extern void print_stats(); - -#endif // libpoly092986127876181939u43295237 //############################################################ GLOBALS @@ -47,27 +22,47 @@ std::condition_variable can_push; std::atomic_uint32_t active_producents; std::atomic_uint32_t active_consuments; std::atomic_bool tasks_incoming; +std::ostream& os = std::cout; +std::mutex os_l; //############################# MODIFY HERE -constexpr unsigned NUM_PRODUCENTS = 20; -constexpr unsigned NUM_WORKERS = 20; +constexpr unsigned NUM_PRODUCENTS = 1; +constexpr unsigned NUM_WORKERS = 3; //############################################################ COMMON STRUCTURES +struct Temp_Task: public std::enable_shared_from_this< Temp_Task > { + LP_Polygon p; + double minimal_triangulation; + + Temp_Task(LP_Polygon&& _p): p(_p){} +}; + +using Temp_Task_p = std::shared_ptr< Temp_Task >; + class Task { private: - LP_Task_p task; - bool ready_for_submit; + Temp_Task_p task; + + double triangulate(LP_Polygon* p); + double triangulate(); + double triangulate_subpolys(std::vector poly_key, std::map* m); public: - Task() = delete; + Task(): task(nullptr){}; Task(const Task&) = delete; - Task(Task&& t): task(t.task), ready_for_submit(t.ready_for_submit){ + Task(Task&& t): task(t.task){ t.task.reset(); } - Task(LP_Task_p&& tp): task(tp), ready_for_submit(false){} - void triangulate(); + Task(Temp_Task_p&& tp): task(tp){} + void solve_stupid(){ + task->minimal_triangulation = triangulate(&(task->p)); + } + Temp_Task_p unwrap(){ // TODO: vymyslet jinak, zaručit po tomto kroku selfdestruct + return std::move(task); + } + double const solution(){ return task->minimal_triangulation; } }; class Queue{ @@ -79,8 +74,7 @@ public: void push(Task&& t){ std::unique_lock pushlock(q_l); - can_push.wait(pushlock, [this]{ return (q.size() < MAX_LENGHT); }); - + can_push.wait(pushlock, [this](){ return (q.size() < MAX_LENGHT); }); q.push(std::move(t)); pushlock.unlock(); @@ -89,7 +83,7 @@ public: Task pop(){ std::unique_lock poplock(q_l); - can_pop.wait(poplock, [this]{ return !is_empty(); }); + can_pop.wait(poplock, [this](){ return !is_empty(); }); Task t(std::move(q.front())); q.pop(); @@ -116,12 +110,29 @@ public: ~Producent(){ active_producents--; } Task get_task(){ - LP_Task_p tp = pickup_task(); //might need to be locked - ask Ondra + //LP_Task_p tp = pickup_task(); + + //#########################3TEMP_PART: + std::vector< LP_Point > points; + srand(static_cast(std::chrono::system_clock::now().time_since_epoch().count())); + int num_of_points = (rand()%10) + 1; + for(int i = 0; i < num_of_points; i++){ + LP_Point p; + + p.x = rand()%199 +1; + p.y = rand()%199 +1; + points.push_back(p); + } + LP_Polygon p(std::move(points)); + Temp_Task_p tp = std::make_shared(std::move( p )); + return Task(std::move(tp)); } void fill_queue(){ while(tasks_incoming){ + //Task t = get_task(); + task_queue->push(get_task()); } } @@ -149,29 +160,123 @@ public: void work(){ while(active_producents || ! task_queue->is_empty()){ Task t = get_task(); - t.triangulate(); + t.solve_stupid(); + //submit_task(std::move(t.unwrap())); + os_l.lock(); + os << t.solution() << std::endl; + os_l.unlock(); } } }; void consume_thread(task_queue_ptr task_queue){ Consument c(task_queue); + c.work(); +} + +//############################################################ TRIANGULATION + +struct Line{ + LP_Point a; + LP_Point b; + double length; + + Line() = delete; + Line(LP_Point _a, LP_Point _b): a(_a), b(_b){ + LP_Point vec_ba; + vec_ba.x = b.x - a.x; + vec_ba.y = b.y - a.y; + length = sqrt(vec_ba.x*vec_ba.x + vec_ba.y*vec_ba.y); + } + Line(Line& l): a(l.a), b(l.b), length(l.length){} +}; + +double Task::triangulate(LP_Polygon* p){ + size_t poly_size = p->points.size(); + + if(poly_size == 3) return 0.; + + double triangulation; + double min_triangulation = INFINITY; + + for (size_t point_idx = 0; point_idx < poly_size; point_idx++){ + Line cut(p->points.at( (point_idx - 1) % poly_size ), + p->points.at( (point_idx + 1) % poly_size )); + + std::vector smaller_poly; + for(size_t i = 0; i < poly_size; i++){ + if(i != point_idx) smaller_poly.push_back(p->points.at(i)); + } + + LP_Polygon s_p(std::move(smaller_poly)); + triangulation = triangulate(&s_p) + cut.length; + if(triangulation < min_triangulation) min_triangulation = triangulation; + } + + return min_triangulation; + +} +//############################### dynamic something + +//use std::map to store triangulations of polygons +//KEY CREATION: + // take relative positions of points in polygon, add them as vectors and do something with the amount of them + // maybe num * vx + num^2 * vy + +double Task::triangulate(){ + std::map m; + std::vector poly_key; + return triangulate_subpolys(poly_key, &m); +} + +int vec_to_int(std::vector* vec){ + int res = 0; + for (size_t i = 0; i < vec->size(); i++){ + res += vec->at(i) * 2^i; + } + return res; +} + +double Task::triangulate_subpolys(std::vector poly_key, std::map* m){ + // convert p to int + // try to find in map + // success -> return mapped value + // failure -> compute triangulation + // save value in map + // return found value + // COMPUTE TRIANGULATION + // create polygon poly from p + // use stupid triangulation but create poly_key instead of small_poly + + return 0.; + + } //############################################################ MAIN int main(){ - active_producents = 0; - Queue q; - task_queue_ptr queue_ptr(&q); + active_producents = active_consuments = 0; + tasks_incoming = true; + + task_queue_ptr queue_ptr = std::make_shared(); std::vector threads; for(unsigned int i = 0; i < NUM_PRODUCENTS; i++){ threads.emplace_back(produce_thread, queue_ptr); } - std::this_thread::sleep_for(std::chrono::seconds(5)); + for(unsigned int i = 0; i < NUM_WORKERS; i++){ + threads.emplace_back(consume_thread, queue_ptr); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + tasks_incoming = false; for(auto& t : threads){ t.join(); + os_l.lock(); + os << "joined" << std::endl; + os_l.unlock(); } + //test(); } \ No newline at end of file