| 2757 | |
| 2758 | |
| 2759 | bool isSegment( const std::vector<double> &cx, const std::vector<double> &cy, const int i ) |
| 2760 | { |
| 2761 | // examine a part of cubic Bezier curve (i--i+1--i+2--i+3) is a segment or not. |
| 2762 | return (cx[i] == cx[i+1]) && (cy[i] == cy[i+1]) && (cx[i+2] == cx[i+3]) && (cy[i+2] == cy[i+3]); |
| 2763 | } |
| 2764 | |
| 2765 | int findSegment( const double x, const double y, |
| 2766 | const std::vector<double> &cx, const std::vector<double> &cy ) |
| 2767 | { |
| 2768 | const double EPS = 1e-10; |
| 2769 | |
| 2770 | // cx and cy are control points of cubic Bezier curve. |
| 2771 | // (cx[0],cy[0]) -- (cx[1],cy[1]) -- (cx[2],cy[2]) -- (cx[3],cy[3]) : 0 |
| 2772 | // -- ... |
| 2773 | // -- (cx[3i+1],cy[3i+1]) -- (cx[3i+2],cy[3i+2]) -- (cx[3i+3],cy[3i+3]) : 3i |
| 2774 | |
| 2775 | for(size_t i = 0; i+3 < cx.size(); i += 3){ |
| 2776 | |
| 2777 | if( !isSegment( cx, cy, i ) ) |
| 2778 | continue; |
| 2779 | |
| 2780 | const double &x0 = cx[i]; const double &y0 = cy[i]; |
| 2781 | const double &x1 = cx[i+3]; const double &y1 = cy[i+3]; |
| 2782 | |
| 2783 | // if (x,y) \in (x0,y0) -- (x1,y1), then |
| 2784 | // x = (1-t)*x0 + t*x1 and y = (1-t)*y0 + t*y1, 0 <= t <= 1 |
| 2785 | // <=> x = x0 - t*x0 + t*x1, y = y0 - t*y0 + t*y1 |
| 2786 | // <=> t = (x-x0) / (x1-x0) = (y-y0) / (y1-y0) |
| 2787 | |
| 2788 | if( fabs( (x-x0)*(y1-y0) - (x1-x0)*(y-y0) ) > EPS ) |
| 2789 | continue; |
| 2790 | |
| 2791 | if( fabs( x1-x0 ) > EPS ){ |
| 2792 | const double t = (x-x0) / (x1-x0); |
| 2793 | |
| 2794 | if( (-EPS < t) && (t < 1+EPS) ) |
| 2795 | return i; |
| 2796 | } |
| 2797 | |
| 2798 | if( fabs( y1-y0 ) > EPS ){ |
| 2799 | const double t = (y-y0) / (y1-y0); |
| 2800 | |
| 2801 | if( (-EPS < t) && (t < 1+EPS) ) |
| 2802 | return i; |
| 2803 | } |
| 2804 | } |
no test coverage detected