X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fvaluenode_bline.cpp;h=fc3e9165aa20d711f580683a454ad619e733ac12;hb=9459638ad6797b8139f1e9f0715c96076dbf0890;hp=366c3015886bbc5ff3734f634b35957de9e7cadc;hpb=55323d29e72ab09cb29414e861458ed0713b97be;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/valuenode_bline.cpp b/synfig-core/trunk/src/synfig/valuenode_bline.cpp index 366c301..fc3e916 100644 --- a/synfig-core/trunk/src/synfig/valuenode_bline.cpp +++ b/synfig-core/trunk/src/synfig/valuenode_bline.cpp @@ -42,6 +42,7 @@ #include #include #include "segment.h" +#include "curve_helper.h" #endif @@ -78,7 +79,12 @@ radial_interpolation(const Vector& a, const Vector& b, float c) affine_combo ang_combo; Real mag(mag_combo(a.mag(),b.mag(),c)); - Angle ang(ang_combo(Angle::tan(a[1],a[0]),Angle::tan(b[1],b[0]),c)); + Angle angle_a(Angle::tan(a[1],a[0])); + Angle angle_b(Angle::tan(b[1],b[0])); + float diff = Angle::deg(angle_b - angle_a).get(); + if (diff < -180) angle_b += Angle::deg(360); + else if (diff > 180) angle_a += Angle::deg(360); + Angle ang(ang_combo(angle_a, angle_b, c)); return Point( mag*Angle::cos(ang).get(),mag*Angle::sin(ang).get() ); } @@ -163,6 +169,118 @@ synfig::convert_bline_to_width_list(const ValueBase& bline) return ValueBase(ret,bline.get_loop()); } +Real +synfig::find_closest_point(const ValueBase &bline, const Point &pos, Real &radius, bool loop, Point *out_point) +{ + Real d,step; + float time = 0; + float best_time = 0; + int best_index = -1; + synfig::Point best_point; + + if(radius==0)radius=10000000; + Real closest(10000000); + + int i=0; + std::vector list(bline.get_list().begin(),bline.get_list().end()); + typedef std::vector::const_iterator iterT; + iterT iter, prev, first; + for(iter=list.begin(); iter!=list.end(); ++i, ++iter) + { + if( first == iterT() ) + first = iter; + + if( prev != iterT() ) + { + bezier curve; + + curve[0] = (*prev).get_vertex(); + curve[1] = curve[0] + (*prev).get_tangent2()/3; + curve[3] = (*iter).get_vertex(); + curve[2] = curve[3] - (*iter).get_tangent1()/3; + curve.sync(); + + #if 0 + // I don't know why this doesn't work + time=curve.find_closest(pos,6); + d=((curve(time)-pos).mag_squared()); + + #else + //set the step size based on the size of the picture + d = (curve[1] - curve[0]).mag() + (curve[2]-curve[1]).mag() + (curve[3]-curve[2]).mag(); + + step = d/(2*radius); //want to make the distance between lines happy + + step = max(step,0.01); //100 samples should be plenty + step = min(step,0.1); //10 is minimum + + d = find_closest(curve,pos,step,&closest,&time); + #endif + + if(d < closest) + { + closest = d; + best_time = time; + best_index = i; + best_point = curve(best_time); + } + + } + + prev = iter; + } + + // Loop if necessary + if( loop && ( first != iterT() ) && ( prev != iterT() ) ) + { + bezier curve; + + curve[0] = (*prev).get_vertex(); + curve[1] = curve[0] + (*prev).get_tangent2()/3; + curve[3] = (*first).get_vertex(); + curve[2] = curve[3] - (*first).get_tangent1()/3; + curve.sync(); + + #if 0 + // I don't know why this doesn't work + time=curve.find_closest(pos,6); + d=((curve(time)-pos).mag_squared()); + + #else + //set the step size based on the size of the picture + d = (curve[1] - curve[0]).mag() + (curve[2]-curve[1]).mag() + (curve[3]-curve[2]).mag(); + + step = d/(2*radius); //want to make the distance between lines happy + + step = max(step,0.01); //100 samples should be plenty + step = min(step,0.1); //10 is minimum + + d = find_closest(curve,pos,step,&closest,&time); + #endif + + if(d < closest) + { + closest = d; + best_time = time; + best_index = 0; + best_point = curve(best_time); + } + } + + if(best_index != -1) + { + if(out_point) + *out_point = best_point; + + int loop_adjust(loop ? 0 : -1); + int size = list.size(); + Real amount = (best_index + best_time + loop_adjust) / (size + loop_adjust); + return amount; + } + + return 0.0; + +} /* === M E T H O D S ======================================================= */ @@ -327,9 +445,14 @@ ValueNode_BLine::create_list_entry(int index, Time time, Real origin) return ret; } +static int instance_count; + ValueBase ValueNode_BLine::operator()(Time t)const { + if (getenv("SYNFIG_DEBUG_VALUENODE_OPERATORS")) + printf("%s:%d operator()\n", __FILE__, __LINE__); + std::vector ret_list; std::vector::const_iterator iter,first_iter; @@ -696,35 +819,6 @@ ValueNode_BLine::link_local_name(int i)const return etl::strprintf(_("Vertex %03d"),i+1); } -ValueNode* -ValueNode_BLine::clone(const GUID& deriv_guid)const -{ - { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; } - - ValueNode_BLine* ret=new ValueNode_BLine(); - ret->set_guid(get_guid()^deriv_guid); - - std::vector::const_iterator iter; - - for(iter=list.begin();iter!=list.end();++iter) - { - if(iter->value_node->is_exported()) - ret->add(*iter); - else - { - ListEntry list_entry(*iter); - //list_entry.value_node=find_value_node(iter->value_node->get_guid()^deriv_guid).get(); - //if(!list_entry.value_node) - list_entry.value_node=iter->value_node->clone(deriv_guid); - ret->add(list_entry); - //ret->list.back().value_node=iter->value_node.clone(); - } - } - ret->set_loop(get_loop()); - - return ret; -} - String ValueNode_BLine::get_name()const { @@ -740,8 +834,7 @@ ValueNode_BLine::get_local_name()const LinkableValueNode* ValueNode_BLine::create_new()const { - assert(0); - return 0; + return new ValueNode_BLine(); } bool