00001
00021
00022
00023
00024
00025 #ifndef __SYNFIG_CURVE_HELPER_H
00026 #define __SYNFIG_CURVE_HELPER_H
00027
00028
00029 #include <ETL/bezier>
00030
00031 #include "rect.h"
00032 #include "real.h"
00033 #include "vector.h"
00034
00035 #include <vector>
00036
00037
00038
00039
00040
00041
00042
00043 namespace synfig {
00044
00045
00046 inline Real line_point_distsq(const Point &p1, const Point &p2,
00047 const Point &p, float &t)
00048 {
00049 Vector v,vt;
00050
00051 v = p2 - p1;
00052 vt = p - p1;
00053
00054 t = v.mag_squared() > 1e-12 ? (vt*v)/v.mag_squared() : 0;
00055
00056
00057 if(t >= 1)
00058 {
00059 vt += v;
00060 t = 1;
00061 }else if(t > 0)
00062 {
00063 vt -= v * t;
00064 }else
00065 {
00066 t = 0;
00067 }
00068
00069
00070 return vt.mag_squared();
00071 }
00072
00073
00074
00075 struct Ray
00076 {
00077 Point p;
00078 Vector v;
00079
00080 Ray() {}
00081 Ray(const Point &pin, const Vector &vin):p(pin), v(vin) {}
00082 };
00083
00084
00085
00086
00087
00088 int intersect(const Point &p1, const Vector &v1, float &t1,
00089 const Point &p2, const Vector &v2, float &t2);
00090
00091 inline bool intersect_line_segments(const Point &a, const Point &b, float &tout,
00092 const Point &c, const Point &d, float &sout)
00093 {
00094 Vector v1(b-a), v2(d-c);
00095
00096
00097 float t,s;
00098
00099 if( intersect(a,v1,t, b,v2,s) && t >= 0 && t <= 1 && s >= 0 && s <= 1 )
00100 {
00101 tout = t;
00102 sout = s;
00103 return true;
00104 }
00105
00106 return false;
00107 }
00108
00109
00110 Real find_closest(const etl::bezier<Point> &curve, const Point &point, float step, Real *closest, float *t);
00111
00112
00113
00114 template < typename T >
00115 inline void Bound(etl::rect<T> &r, const etl::bezier<Point> &b)
00116 {
00117 r.set_point(b[0][0],b[0][1]);
00118 r.expand(b[1][0],b[1][1]);
00119 r.expand(b[2][0],b[2][1]);
00120 r.expand(b[3][0],b[3][1]);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 struct BezHull
00134 {
00135 Point p[4];
00136 int size;
00137
00138 void Bound(const etl::bezier<Point> &b);
00139 };
00140
00141
00142 int intersect(const Rect &r1, const Point &p, const Vector &v);
00143 int intersect(const Rect &r1, const Point &p);
00144 int intersect(const BezHull &bh, const Point &p, const Vector &v);
00145
00146 int intersect(const etl::bezier<Point> &b, const Point &p);
00147
00148
00149 class CIntersect
00150 {
00151 public:
00152 struct SCurve;
00153 private:
00154 void recurse_intersect(const SCurve &left, const SCurve &right, int depth = 0);
00155
00156 public:
00157
00158 typedef std::vector< std::pair<float,float > > intersect_set;
00159 intersect_set times;
00160
00161 int max_depth;
00162
00163 CIntersect();
00164
00165 bool operator()(const etl::bezier<Point> &b1, const etl::bezier<Point> &b2);
00166 };
00167
00168 };
00169
00170
00171
00172 #endif