- Main Page
- Related Pages
- Namespaces
- Classes
- Files

# 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