X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Fsrc%2Fsynfig%2Fcurve_helper.h;fp=synfig-core%2Fsrc%2Fsynfig%2Fcurve_helper.h;h=620387f2629d8f8a79842bf0bf728d7549bccc68;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-core/src/synfig/curve_helper.h b/synfig-core/src/synfig/curve_helper.h new file mode 100644 index 0000000..620387f --- /dev/null +++ b/synfig-core/src/synfig/curve_helper.h @@ -0,0 +1,172 @@ +/* === S Y N F I G ========================================================= */ +/*! \file curve_helper.h +** \brief Curve Helper Header +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** \endlegal +*/ +/* ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __SYNFIG_CURVE_HELPER_H +#define __SYNFIG_CURVE_HELPER_H + +/* === H E A D E R S ======================================================= */ +#include + +#include "rect.h" +#include "real.h" +#include "vector.h" + +#include + +/* === M A C R O S ========================================================= */ + +/* === T Y P E D E F S ===================================================== */ + +/* === C L A S S E S & S T R U C T S ======================================= */ + +namespace synfig { + +//line helper functions +inline Real line_point_distsq(const Point &p1, const Point &p2, + const Point &p, float &t) +{ + Vector v,vt; + + v = p2 - p1; + vt = p - p1; + + t = v.mag_squared() > 1e-12 ? (vt*v)/v.mag_squared() : 0; //get the projected time value for the current line + + //get distance to line segment with the time value clamped 0-1 + if(t >= 1) //use p+v + { + vt += v; //makes it pp - (p+v) + t = 1; + }else if(t > 0) //use vt-proj + { + vt -= v * t; // vt - proj_v(vt) //must normalize the projection vector to work + }else + { + t = 0; + } + + //else use p + return vt.mag_squared(); +} + + +//----- RAY CLASS AND FUNCTIONS -------------- +struct Ray +{ + Point p; + Vector v; + + Ray() {} + Ray(const Point &pin, const Vector &vin):p(pin), v(vin) {} +}; + +/* This algorithm calculates the INTERSECTION of 2 line segments + (not the closest point or anything like that, just intersection) + //parameter values returned are [0,1] +*/ +int intersect(const Point &p1, const Vector &v1, float &t1, + const Point &p2, const Vector &v2, float &t2); + +inline bool intersect_line_segments(const Point &a, const Point &b, float &tout, + const Point &c, const Point &d, float &sout) +{ + Vector v1(b-a), v2(d-c); + + //ok so treat both lines as parametric (so we can find the time values simultaneously) + float t,s; + + if( intersect(a,v1,t, b,v2,s) && t >= 0 && t <= 1 && s >= 0 && s <= 1 ) + { + tout = t; + sout = s; + return true; + } + + return false; +} + +//Find the closest point on the curve to a point (and return its distance, and time value) +Real find_closest(const etl::bezier &curve, const Point &point, float step, Real *closest, float *t); + +//----------- Rectangle helper functions --------------- + +template < typename T > +inline void Bound(etl::rect &r, const etl::bezier &b) +{ + r.set_point(b[0][0],b[0][1]); + r.expand(b[1][0],b[1][1]); + r.expand(b[2][0],b[2][1]); + r.expand(b[3][0],b[3][1]); +} + +/*template < typename T > +inline bool intersect(const etl::rect &r1, const etl::rect &r2) +{ + return (r1.minx < r2.maxx) & + (r2.minx < r1.maxx) & + (r1.miny < r2.maxy) & + (r2.miny < r1.maxy); +}*/ + +//----- Convex Hull of a Bezier Curve -------------- +struct BezHull +{ + Point p[4]; + int size; + + void Bound(const etl::bezier &b); +}; + +//Line Intersection +int intersect(const Rect &r1, const Point &p, const Vector &v); +int intersect(const Rect &r1, const Point &p); //inside or to the right +int intersect(const BezHull &bh, const Point &p, const Vector &v); +//int intersect(const etl::bezier &b, const Point &p, const Vector &v); +int intersect(const etl::bezier &b, const Point &p); //for use in containment tests for regions + +//Curve intersection object +class CIntersect +{ +public: + struct SCurve; +private: + void recurse_intersect(const SCurve &left, const SCurve &right, int depth = 0); + +public: + //size should be equal + typedef std::vector< std::pair > intersect_set; + intersect_set times; + + int max_depth; + + CIntersect(); + + bool operator()(const etl::bezier &b1, const etl::bezier &b2); +}; + +}; // END of namespace studio + +/* === E N D =============================================================== */ + +#endif