diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2013-02-23 22:34:58 +0000 |
|---|---|---|
| committer | Jabiertxo Arraiza Zenotz <jtx@jtx.marker.es> | 2013-02-23 22:34:58 +0000 |
| commit | 9af17a6572db964acebd2b7eeea29c8b722c8221 (patch) | |
| tree | 20fef1b2c5a2f9d49a841be10238919be7acf72e /src/live_effects | |
| parent | Mayor refactor (diff) | |
| download | inkscape-9af17a6572db964acebd2b7eeea29c8b722c8221.tar.gz inkscape-9af17a6572db964acebd2b7eeea29c8b722c8221.zip | |
Saved for next refactor
(bzr r11950.1.37)
Diffstat (limited to 'src/live_effects')
| -rw-r--r-- | src/live_effects/lpe-bspline.cpp | 77 |
1 files changed, 48 insertions, 29 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 8147ae014..8dc840556 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -32,15 +32,15 @@ LPEBSpline::~LPEBSpline() void LPEBSpline::doEffect(SPCurve * curve) { - using Geom::X; - using Geom::Y; - if(curve->get_segment_count() < 2) return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); //Sbasis + Geom::D2< Geom::SBasis > SBasisIn; + Geom::D2< Geom::SBasis > SBasisOut; + Geom::D2< Geom::SBasis > SBasisEnd; Geom::D2< Geom::SBasis > SBasisHelper; //curves SPCurve * in = new SPCurve(); @@ -63,9 +63,9 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::CubicBezier const *cubicIn; - Geom::CubicBezier const *cubicOut; - Geom::CubicBezier const *cubicEnd; + + Geom::Point endPointAt2(0,0); + Geom::CubicBezier const *cubic; //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el penúltimo for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { //Si está vacío... @@ -75,7 +75,7 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_end = path_it->end(); // end curve + Geom::Path::const_iterator curve_end = path_it->end_open(); // end curve Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán @@ -92,12 +92,31 @@ LPEBSpline::doEffect(SPCurve * curve) //Si la curva está cerrada calculamos el punto donde //deveria estar el nodo BSpline de cierre/inicio de la curva //en posible caso de que se cierre con una linea recta creando un nodo BSPline - cubicEnd = dynamic_cast<Geom::CubicBezier const*>(&*curve_end); - cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); - if (path_it->closed() && cubicEnd && cubicIn) { - //Calculamos el nodo de inicio BSpline - lineHelper->moveto((*cubicIn)[1]); - lineHelper->lineto((*cubicEnd)[2]); + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + SBasisIn = in->first_segment()->toSBasis(); + SBasisEnd = end->first_segment()->toSBasis(); + cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); + if(cubic){ + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + } + cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_end); + if(cubic){ + endPointAt2 = SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())); + }else{ + endPointAt2 = end->first_segment()->finalPoint(); + } + lineHelper->moveto(pointAt1); + lineHelper->lineto(endPointAt2); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -110,18 +129,18 @@ LPEBSpline::doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; } - //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); - if(cubicIn){ - pointAt0 = (*cubicIn)[0]; - pointAt1 = (*cubicIn)[1]; - pointAt2 = (*cubicIn)[2]; - pointAt3 = (*cubicIn)[3]; + cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); + if(cubic){ + SBasisIn = in->first_segment()->toSBasis(); + pointAt0 = (*cubic)[0]; + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); + pointAt3 = (*cubic)[3]; }else{ pointAt0 = in->first_segment()->initialPoint(); pointAt1 = in->first_segment()->initialPoint(); @@ -130,15 +149,16 @@ LPEBSpline::doEffect(SPCurve * curve) } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); - if(cubicOut){ - nextPointAt1 = (*cubicOut)[1]; - nextPointAt2 = (*cubicOut)[2]; - nextPointAt3 = (*cubicOut)[3]; + cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); + if(cubic){ + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; + nextPointAt3 = (*cubic)[3]; }else{ - nextPointAt1 = in->first_segment()->initialPoint(); - nextPointAt2 = in->first_segment()->finalPoint(); - nextPointAt3 = in->first_segment()->finalPoint(); + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); } //La curva BSpline se forma calculando el centro del segmanto de unión //de el punto situado en las 2/3 partes de el segmento de entrada @@ -203,7 +223,6 @@ LPEBSpline::doEffect(SPCurve * curve) //Todo: remove? //delete SBasisHelper; } - }; //namespace LivePathEffect }; /* namespace Inkscape */ |
