curve_helper.h

Go to the documentation of this file.
00001 /* === S Y N F I G ========================================================= */
00021 /* ========================================================================= */
00022 
00023 /* === S T A R T =========================================================== */
00024 
00025 #ifndef __SYNFIG_CURVE_HELPER_H
00026 #define __SYNFIG_CURVE_HELPER_H
00027 
00028 /* === H E A D E R S ======================================================= */
00029 #include <ETL/bezier>
00030 
00031 #include "rect.h"
00032 #include "real.h"
00033 #include "vector.h"
00034 
00035 #include <vector>
00036 
00037 /* === M A C R O S ========================================================= */
00038 
00039 /* === T Y P E D E F S ===================================================== */
00040 
00041 /* === C L A S S E S & S T R U C T S ======================================= */
00042 
00043 namespace synfig {
00044 
00045 //line helper functions
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; //get the projected time value for the current line
00055 
00056     //get distance to line segment with the time value clamped 0-1
00057     if(t >= 1)  //use p+v
00058     {
00059         vt += v; //makes it pp - (p+v)
00060         t = 1;
00061     }else if(t > 0) //use vt-proj
00062     {
00063         vt -= v * t; // vt - proj_v(vt) //must normalize the projection vector to work
00064     }else
00065     {
00066         t = 0;
00067     }
00068 
00069     //else use p
00070     return vt.mag_squared();
00071 }
00072 
00073 
00074 //----- RAY CLASS AND FUNCTIONS --------------
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 /* This algorithm calculates the INTERSECTION of 2 line segments
00085     (not the closest point or anything like that, just intersection)
00086     //parameter values returned are [0,1]
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     //ok so treat both lines as parametric (so we can find the time values simultaneously)
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 //Find the closest point on the curve to a point (and return its distance, and time value)
00110 Real find_closest(const etl::bezier<Point> &curve, const Point &point, float step, Real *closest, float *t);
00111 
00112 //----------- Rectangle helper functions ---------------
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 /*template < typename T >
00124 inline bool intersect(const etl::rect<T> &r1, const etl::rect<T> &r2)
00125 {
00126     return (r1.minx < r2.maxx) &
00127             (r2.minx < r1.maxx) &
00128             (r1.miny < r2.maxy) &
00129             (r2.miny < r1.maxy);
00130 }*/
00131 
00132 //----- Convex Hull of a Bezier Curve --------------
00133 struct BezHull
00134 {
00135     Point   p[4];
00136     int     size;
00137 
00138     void Bound(const etl::bezier<Point> &b);
00139 };
00140 
00141 //Line Intersection
00142 int intersect(const Rect &r1, const Point &p, const Vector &v);
00143 int intersect(const Rect &r1, const Point &p); //inside or to the right
00144 int intersect(const BezHull &bh, const Point &p, const Vector &v);
00145 //int intersect(const etl::bezier<Point> &b, const Point &p, const Vector &v);
00146 int intersect(const etl::bezier<Point> &b, const Point &p); //for use in containment tests for regions
00147 
00148 //Curve intersection object
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     //size should be equal
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 }; // END of namespace studio
00169 
00170 /* === E N D =============================================================== */
00171 
00172 #endif

Generated on Wed Dec 12 03:11:41 2007 for synfig by  doxygen 1.5.4