#define INKSCAPE_LPE_MIRROR_REFLECT_CPP /** \file * LPE implementation: mirrors a path with respect to a given line. */ /* * Authors: * Maximilian Albert * Johan Engelen * * Copyright (C) Johan Engelen 2007 * Copyright (C) Maximilin Albert 2008 * * Released under GNU GPL, read the file 'COPYING' for more information */ #include "live_effects/lpe-mirror_reflect.h" #include #include #include #include <2geom/path.h> #include <2geom/transforms.h> #include <2geom/matrix.h> namespace Inkscape { namespace LivePathEffect { LPEMirrorReflect::LPEMirrorReflect(LivePathEffectObject *lpeobject) : Effect(lpeobject), reflection_line(_("Reflection line"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L100,100") { show_orig_path = true; registerParameter( dynamic_cast(&reflection_line) ); } LPEMirrorReflect::~LPEMirrorReflect() { } void LPEMirrorReflect::acceptParamPath (SPPath *param_path) { using namespace Geom; SPCurve* curve = sp_path_get_curve_for_edit (param_path); Geom::Point A(curve->first_point().to_2geom()); Geom::Point B(curve->last_point().to_2geom()); Piecewise > rline = Piecewise >(D2(Linear(A[X], B[X]), Linear(A[Y], B[Y]))); reflection_line.param_set_and_write_new_value(rline); SP_OBJECT(param_path)->deleteObject(true); // don't remove this; needed for cleanup tasks Effect::acceptParamPath(param_path); } std::vector LPEMirrorReflect::doEffect_path (std::vector const & path_in) { std::vector path_out; std::vector mline(reflection_line.get_pathvector()); Geom::Point A(mline.front().initialPoint()); Geom::Point B(mline.back().finalPoint()); Geom::Matrix m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); double hyp = Geom::distance(A, B); double c = (B[0] - A[0]) / hyp; // cos(alpha) double s = (B[1] - A[1]) / hyp; // sin(alpha) Geom::Matrix m2(c, -s, s, c, 0.0, 0.0); Geom::Matrix sca(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); Geom::Matrix m = m1.inverse() * m2; m = m * sca; m = m * m2.inverse(); m = m * m1; for (int i = 0; i < path_in.size(); ++i) { path_out.push_back(path_in[i] * m); } return path_out; } /* ######################## */ } //namespace LivePathEffect } /* namespace Inkscape */ /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :