123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #ifndef _FP_PATH_HPP_
- #define _FP_PATH_HPP_
- #include <math.h>
- #include <assert.h>
- #include <vector>
- #include "base_data.h"
- #include "../point.h"
- struct fixed_point:point_2
- {
- fixed_point(double x,double y)
- :point_2(x,y)
- ,cos_(0),sin_(0)
- ,dist_(0)
- {}
- fixed_point(const point_2&pt)
- :point_2(pt)
- ,cos_(0),sin_(0)
- ,dist_(0)
- {}
- fixed_point(const fixed_point&pt)
- :point_2(pt)
- ,cos_(pt.cos_),sin_(pt.sin_)
- ,dist_(pt.dist_)
- {}
- double cos_;
- double sin_;
- double dist_;
- double set_next_point(const point_2&p)
- {
- dist_ = dist_to(p);
- assert(dist_>0);
- double deta_x = p.x_-x_;
- cos_ = deta_x/dist_;
- double deta_y = p.y_-y_;
- sin_ = deta_y/dist_;
- return dist_;
- }
- };
- struct fp_path
- {
- private:
- std::vector<fixed_point> path_;
- fp_path(const fp_path&);
- double m_total_length;
- private:
- static inline bool eq(double x1,double x2)
- {
- return fabs(x1-x2)<0.1;
- }
- public:
- fp_path()
- :m_total_length(0)
- {
- path_.reserve(8);
- }
- template<typename iterator>
- fp_path(iterator begin,iterator end)
- :m_total_length(0)
- {
- for (;begin != end; ++ begin)
- {
- add_point(*begin);
- }
- }
- void add_point(double x,double y)
- {
- add_point(point_2(x,y));
- }
- void add_point(const point &pt)
- {
- point_2 p(pt.x,pt.y);
- add_point(p);
- }
- void add_point(const point_2&pt)
- {
- if(!path_.empty())
- {
- double d = path_.back().set_next_point(pt);
- m_total_length += d;
- }
- path_.push_back(pt);
- }
- double map(double x,double y)
- {
-
- if(path_.size()<2)
- return -1.;
- double rc=0.;
- auto it1=path_.begin();
- double l1=it1->dist_to(x,y);
-
- auto it2=path_.begin(); ++it2;
- for(; it2!=path_.end();++it2)
- {
- double l2=it2->dist_to(x,y);
- if(eq(l1+l2, it1->dist_))
- {
- return rc+l1;
- }
- rc+=it1->dist_;
- it1=it2;
- l1=l2;
- }
- return -1.;
- }
- double map(const point_2& p)
- {
- return map(p.x_, p.y_);
- }
- point_2 map(double dist)
- {
- if(path_.size()>1)
- {
- for(auto it=path_.begin(), _e=path_.end()-1; it!=_e;++it)
- {
- if(dist<=it->dist_)
- {
- return point_2(it->x_+it->cos_*dist,it->y_+it->sin_*dist);
- }
- dist-=it->dist_;
- if(dist<0)
- break;
- }
- }
- return point_2::invalid_point();
- }
- double get_total_length()
- {
- return m_total_length;
- }
- };
- #endif
|