summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 97580dc)
raw | patch | inline | side by side (parent: 97580dc)
author | jfbarraud <jfbarraud@users.sourceforge.net> | |
Thu, 26 Mar 2009 06:37:02 +0000 (06:37 +0000) | ||
committer | jfbarraud <jfbarraud@users.sourceforge.net> | |
Thu, 26 Mar 2009 06:37:02 +0000 (06:37 +0000) |
src/live_effects/lpe-rough-hatches.cpp | patch | blob | history |
index 7fa865c01098ca49ba18d50c65711ec453685abd..8b2c8aaf8bd2a67f88ef586fd56399c62b2f8c0a 100644 (file)
};\r
struct LevelCrossingOrder {\r
bool operator()(LevelCrossing a, LevelCrossing b) {\r
- return a.pt[Y] < b.pt[Y];\r
+ return ( a.pt[Y] < b.pt[Y] );// a.pt[X] == b.pt[X] since we are supposed to be on the same level...\r
+ //return ( a.pt[X] < b.pt[X] || ( a.pt[X] == b.pt[X] && a.pt[Y] < b.pt[Y] ) );\r
}\r
};\r
struct LevelCrossingInfo{\r
}\r
double t = (*this)[level][idx].t;\r
double sign = ((*this)[level][idx].sign ? 1 : -1);\r
- double next_t = t;\r
+ //---double next_t = t;\r
//level += 1;\r
direction = (direction + 1)%4;\r
if (level == size()){\r
}\r
level = next.first;\r
idx = next.second;\r
-\r
-/*********************\r
- //look for next time on the same level\r
- for (unsigned j=0; j<(*this)[level].size(); j++){\r
- double tj = (*this)[level][j].t;\r
- if ( sign*(tj-t) > 0 ){\r
- if( next_t == t || sign*(tj-next_t)<0 ){\r
- next_t = tj;\r
- idx = j;\r
- }\r
- }\r
- }\r
- if ( next_t == t ){//not found? look at max/min time in this component, as time is "periodic".\r
- for (unsigned j=0; j<(*this)[level].size(); j++){\r
- double tj = (*this)[level][j].t;\r
- if ( -sign*(tj-next_t) > 0 ){\r
- next_t = tj;\r
- idx = j;\r
- }\r
- }\r
- }\r
- if ( next_t == t ){//still not found? houch! this should not happen.\r
- level = size();\r
- return;\r
- }\r
- if ( (*this)[level][idx].used ) {\r
- level = size();\r
- return;\r
- }\r
-*************************/\r
return;\r
}\r
};\r
scale_tb(_("1st side, out"), _("Set smoothness/sharpness of path when leaving a 'bottom' halfturn. 0=sharp, 1=default"), "scale_bb", &wr, this, 1.),\r
scale_bf(_("2nd side, in "), _("Set smoothness/sharpness of path when reaching a 'top' halfturn. 0=sharp, 1=default"), "scale_tf", &wr, this, 1.),\r
scale_bb(_("2nd side, out"), _("Set smoothness/sharpness of path when leaving a 'top' halfturn. 0=sharp, 1=default"), "scale_tb", &wr, this, 1.),\r
- top_smth_variation(_("variance: 1st side"), _("Randomness of 'bottom' halfturns smoothness"), "bottom_smth_variation", &wr, this, 0),\r
+ top_smth_variation(_("variance: 1st side"), _("Randomness of 'bottom' halfturns smoothness"), "top_smth_variation", &wr, this, 0),\r
bot_smth_variation(_("2nd side"), _("Randomness of 'top' halfturns smoothness"), "bottom_smth_variation", &wr, this, 0),\r
//\r
top_edge_variation(_("Magnitude jitter: 1st side"), _("Randomly moves 'bottom' halfsturns to produce magnitude variations."), "bottom_edge_variation", &wr, this, 0),\r
bender(_("Global bending"), _("Relative position to ref point defines global bending direction and amount"), "bender", &wr, this, Geom::Point(-5,0)),\r
//\r
fat_output(_("Generate thick/thin path"), _("Simulate a stroke of varrying width"), "fat_output", &wr, this, true),\r
- stroke_width_top(_("Thikness: at 1st side"), _("Width at 'bottom' half turns"), "stroke_width_bottom", &wr, this, 1.),\r
+ stroke_width_top(_("Thikness: at 1st side"), _("Width at 'bottom' half turns"), "stroke_width_top", &wr, this, 1.),\r
stroke_width_bot(_("at 2nd side"), _("Width at 'top' halfturns"), "stroke_width_bottom", &wr, this, 1.),\r
front_thickness(_("from 2nd to 1st side"), _("Width of paths from 'top' to 'bottom' halfturns"), "front_thickness", &wr, this, 1.),\r
back_thickness(_("from 1st to 2nd side"), _("Width of paths from 'top' to 'bottom' halfturns"), "back_thickness", &wr, this, .25)\r
registerParameter( dynamic_cast<Parameter *>(&back_thickness) );\r
\r
//hatch_dist.param_set_range(0.1, NR_HUGE);\r
- growth.param_set_range(-0.95, NR_HUGE);\r
+ growth.param_set_range(0, NR_HUGE);\r
dist_rdm.param_set_range(0, 99.);\r
stroke_width_top.param_set_range(0, NR_HUGE);\r
stroke_width_bot.param_set_range(0, NR_HUGE);\r
Geom::Piecewise<Geom::D2<Geom::SBasis> > \r
LPERoughHatches::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in){\r
\r
+ //std::cout<<"doEffect_pwd2:\n";\r
+\r
Piecewise<D2<SBasis> > result;\r
\r
Piecewise<D2<SBasis> > transformed_pwd2_in = pwd2_in;\r
@@ -326,13 +299,11 @@ LPERoughHatches::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const &
Matrix bend_mat;//used to bend the hatches\r
\r
if (do_bend.get_value()){\r
- //Point bend_dir = -rot90(unit_vector(direction.getOrigin() - bender));\r
- //double bend_amount = L2(direction.getOrigin() - bender);\r
- Point bend_dir = -rot90(unit_vector(direction.getVector()));\r
- double bend_amount = L2(direction.getVector());\r
+ Point bend_dir = -rot90(unit_vector(bender.getVector()));\r
+ double bend_amount = L2(bender.getVector());\r
bend_mat = Matrix(-bend_dir[Y], bend_dir[X], bend_dir[X], bend_dir[Y],0,0);\r
transformed_pwd2_in = pwd2_in * bend_mat;\r
- tilter = Piecewise<SBasis>(shift(Linear(bend_amount),1));\r
+ tilter = Piecewise<SBasis>(shift(Linear(-bend_amount),1));\r
OptRect bbox = bounds_exact( transformed_pwd2_in );\r
if (not(bbox)) return pwd2_in;\r
tilter.setDomain((*bbox)[Y]);\r
std::vector<std::vector<Point> > \r
LPERoughHatches::linearSnake(Piecewise<D2<SBasis> > const &f, Point const &org){\r
\r
+ //std::cout<<"linearSnake:\n";\r
std::vector<std::vector<Point> > result;\r
-\r
Piecewise<SBasis> x = make_cuts_independent(f)[X];\r
//Remark: derivative is computed twice in the 2 lines below!!\r
Piecewise<SBasis> dx = derivative(x);\r
@@ -400,7 +371,6 @@ LPERoughHatches::linearSnake(Piecewise<D2<SBasis> > const &f, Point const &org){
std::vector<double> levels = generateLevels(*range, org[X]);\r
std::vector<std::vector<double> > times;\r
times = multi_roots(x,levels);\r
-\r
//TODO: fix multi_roots!!!*****************************************\r
//remove doubles :-(\r
std::vector<std::vector<double> > cleaned_times(levels.size(),std::vector<double>());\r
@@ -416,27 +386,24 @@ LPERoughHatches::linearSnake(Piecewise<D2<SBasis> > const &f, Point const &org){
}\r
}\r
times = cleaned_times;\r
-// for (unsigned i=0; i<times.size(); i++){\r
-// std::cout << "roots on level "<<i<<": ";\r
-// for (unsigned j=0; j<times[i].size(); j++){\r
-// std::cout << times[i][j] <<" ";\r
-// }\r
-// std::cout <<"\n";\r
-// }\r
//*******************************************************************\r
+\r
LevelsCrossings lscs(times,f,dx);\r
+\r
unsigned i,j;\r
lscs.findFirstUnused(i,j);\r
\r
std::vector<Point> result_component;\r
int n = int((range->min()-org[X])/hatch_dist);\r
+ \r
while ( i < lscs.size() ){ \r
int dir = 0;\r
- //switch orientation of first segment according to org position.\r
- if (n % 2 == 0){\r
- j = lscs[i].size()-1;\r
+ //switch orientation of first segment according to starting point.\r
+ if (i % 2 == n%2 && j < lscs[i].size()-1 && !lscs[i][j].used){\r
+ j += 1;\r
dir = 2;\r
}\r
+\r
while ( i < lscs.size() ){\r
result_component.push_back(lscs[i][j].pt);\r
lscs[i][j].used = true;\r
@@ -458,7 +425,6 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake
Piecewise<D2<SBasis> > result;\r
for (unsigned comp=0; comp<linearSnake.size(); comp++){\r
if (linearSnake[comp].size()>=2){\r
- bool is_top = true;//Inversion here; due to downward y? \r
Point last_pt = linearSnake[comp][0];\r
Point last_top = linearSnake[comp][0];\r
Point last_bot = linearSnake[comp][0];\r
@@ -469,6 +435,9 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake
Geom::Path res_comp_top(last_pt);\r
Geom::Path res_comp_bot(last_pt);\r
unsigned i=1;\r
+ //bool is_top = true;//Inversion here; due to downward y? \r
+ bool is_top = ( linearSnake[comp][0][Y] < linearSnake[comp][1][Y] );\r
+\r
while( i+1<linearSnake[comp].size() ){\r
Point pt0 = linearSnake[comp][i];\r
Point pt1 = linearSnake[comp][i+1];\r
@@ -498,14 +467,21 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake
Point new_hdle_out = new_pt - (pt0-pt1) * (scale_out/2.);\r
\r
if ( fat_output.get_value() ){\r
- double scaled_width = double((is_top ? stroke_width_top : stroke_width_bot))/(pt1[X]-pt0[X]);\r
+ //double scaled_width = double((is_top ? stroke_width_top : stroke_width_bot))/(pt1[X]-pt0[X]);\r
+ double scaled_width = 1./(pt1[X]-pt0[X]);\r
Point hdle_offset = (pt1-pt0)*scaled_width;\r
Point inside = new_pt;\r
Point inside_hdle_in;\r
Point inside_hdle_out;\r
inside[Y]+= double((is_top ? -stroke_width_top : stroke_width_bot));\r
- inside_hdle_in = inside + (new_hdle_in -new_pt) + hdle_offset * double((is_top ? front_thickness : back_thickness));\r
- inside_hdle_out = inside + (new_hdle_out-new_pt) - hdle_offset * double((is_top ? back_thickness : front_thickness));\r
+ inside_hdle_in = inside + (new_hdle_in -new_pt);// + hdle_offset * double((is_top ? front_thickness : back_thickness));\r
+ inside_hdle_out = inside + (new_hdle_out-new_pt);// - hdle_offset * double((is_top ? back_thickness : front_thickness));\r
+\r
+ inside_hdle_in += (pt1-pt0)/2*( double((is_top ? front_thickness : back_thickness)) / (pt1[X]-pt0[X]) );\r
+ inside_hdle_out -= (pt1-pt0)/2*( double((is_top ? back_thickness : front_thickness)) / (pt1[X]-pt0[X]) );\r
+\r
+ new_hdle_in -= (pt1-pt0)/2*( double((is_top ? front_thickness : back_thickness)) / (pt1[X]-pt0[X]) );\r
+ new_hdle_out += (pt1-pt0)/2*( double((is_top ? back_thickness : front_thickness)) / (pt1[X]-pt0[X]) );\r
//TODO: find a good way to handle limit cases (small smthness, large stroke).\r
//if (inside_hdle_in[X] > inside[X]) inside_hdle_in = inside;\r
//if (inside_hdle_out[X] < inside[X]) inside_hdle_out = inside;\r
@@ -529,13 +505,14 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake
i+=2;\r
is_top = !is_top;\r
}\r
- if ( i<linearSnake[comp].size() )\r
+ if ( i<linearSnake[comp].size() ){\r
if ( fat_output.get_value() ){\r
res_comp_top.appendNew<CubicBezier>(last_top_hdle,linearSnake[comp][i],linearSnake[comp][i]);\r
res_comp_bot.appendNew<CubicBezier>(last_bot_hdle,linearSnake[comp][i],linearSnake[comp][i]);\r
}else{\r
res_comp.appendNew<CubicBezier>(last_hdle,linearSnake[comp][i],linearSnake[comp][i]);\r
}\r
+ }\r
if ( fat_output.get_value() ){\r
res_comp = res_comp_bot;\r
res_comp.append(res_comp_top.reverse(),Geom::Path::STITCH_DISCONTINUOUS);\r
vector = Geom::Point((*bbox)[X].extent()/4, 0.);\r
top_edge_variation.param_set_value( (*bbox)[Y].extent()/10, 0 );\r
bot_edge_variation.param_set_value( (*bbox)[Y].extent()/10, 0 );\r
+ top_edge_variation.write_to_SVG();\r
+ bot_edge_variation.write_to_SVG();\r
}\r
//direction.set_and_write_new_values(origin, vector);\r
//bender.param_set_and_write_new_value( origin + Geom::Point(5,0) );\r