diff options
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | src/live_effects/lpe-pts2ellipse.cpp | 481 | ||||
| -rw-r--r-- | src/live_effects/lpe-pts2ellipse.h | 27 |
3 files changed, 309 insertions, 200 deletions
@@ -143,6 +143,7 @@ Felipe Corrêa da Silva Sanches Christian Schaller Marco Scholten Tom von Schwerdtner +Markus Schwienbacher Danilo Šegan Abhishek Sharma Tim Sheridan diff --git a/src/live_effects/lpe-pts2ellipse.cpp b/src/live_effects/lpe-pts2ellipse.cpp index 48655b25a..f9e23d68a 100644 --- a/src/live_effects/lpe-pts2ellipse.cpp +++ b/src/live_effects/lpe-pts2ellipse.cpp @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0-or-later /** \file * LPE "Points to Ellipse" implementation */ @@ -9,7 +8,7 @@ * * Copyright (C) Markus Schwienbacher 2013 <mschwienbacher@gmail.com> * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. + * Released under GNU GPL, read the file 'COPYING' for more information */ #include "live_effects/lpe-pts2ellipse.h" @@ -19,7 +18,6 @@ #include <object/sp-path.h> #include <object/sp-item-group.h> #include <svg/svg.h> -#include <display/curve.h> #include <2geom/path.h> #include <2geom/circle.h> @@ -29,15 +27,15 @@ #include <glib/gi18n.h> -using namespace Geom; - namespace Inkscape { namespace LivePathEffect { static const Util::EnumData<EllipseMethod> EllipseMethodData[] = { { EM_AUTO, N_("Auto ellipse"), "auto" }, //!< (2..4 points: circle, from 5 points: ellipse) - { EM_CIRCLE, N_("Force circle"), "circle" }, - { EM_ISONOMETRIC_CIRCLE, N_("Isometric circle"), "iso_circle" } + { EM_CIRCLE, N_("Force circle"), "circle" }, //!< always fit a circle + { EM_ISOMETRIC_CIRCLE, N_("Isometric circle"), "iso_circle" }, //!< use first two edges to generate a sheared ellipse + { EM_STEINER_ELLIPSE, N_("Steiner ellipse"), "steiner_ellipse" }, //!< generate a steiner ellipse from the first three points + { EM_STEINER_INELLIPSE, N_("Steiner inellipse"), "steiner_inellipse" } //!< generate a steiner inellipse from the first three points }; static const Util::EnumDataConverter<EllipseMethod> EMConverter(EllipseMethodData, EM_END); @@ -45,11 +43,11 @@ LPEPts2Ellipse::LPEPts2Ellipse(LivePathEffectObject *lpeobject) : Effect(lpeobject), method(_("Method:"), _("Methods to generate the ellipse"), "method", EMConverter, &wr, this, EM_AUTO), - gen_isometric_frame(_("_Frame (isometric rectangle)"), _("Draw Parallelogram around the ellipse"), + gen_isometric_frame(_("_Frame (isometric rectangle)"), _("Draw parallelogram around the ellipse"), "gen_isometric_frame", &wr, this, false), gen_arc(_("_Arc"), _("Generate open arc (open ellipse)"), "gen_arc", &wr, this, false), - other_arc(_("_Other Arc side"), _("switch sides of the arc"), "arc_other", &wr, this, false), - slice_arc(_("_Slice Arc"), _("slice the arc"), "slice_arc", &wr, this, false), + other_arc(_("_Other Arc side"), _("Switch sides of the arc"), "arc_other", &wr, this, false), + slice_arc(_("_Slice Arc"), _("Slice the arc"), "slice_arc", &wr, this, false), draw_axes(_("A_xes"), _("Draw both semi-major and semi-minor axes"), "draw_axes", &wr, this, false), rot_axes(_("Axes Rotation"), _("Axes rotation angle [deg]"), "rot_axes", &wr, this, 0), draw_ori_path(_("Source _Path"), _("Show the original source path"), "draw_ori_path", &wr, this, false) @@ -63,34 +61,37 @@ LPEPts2Ellipse::LPEPts2Ellipse(LivePathEffectObject *lpeobject) : registerParameter(&rot_axes); registerParameter(&draw_ori_path); - rot_axes.param_set_range(-360,360); - rot_axes.param_set_increments(1,10); + rot_axes.param_set_range(-360, 360); + rot_axes.param_set_increments(1, 10); - show_orig_path=true; + show_orig_path = true; } LPEPts2Ellipse::~LPEPts2Ellipse() -= default; +{ +} // helper function, transforms a given value into range [0, 2pi] inline double range2pi(double a) { - a = fmod(a, 2*M_PI); - if(a<0) a+=2*M_PI; + a = fmod(a, 2 * M_PI); + if (a < 0) { + a += 2 * M_PI; + } return a; } inline double deg2rad(double a) { - return a*M_PI/180.0; + return a * M_PI / 180.0; } inline double rad2deg(double a) { - return a*180.0/M_PI; + return a * 180.0 / M_PI; } // helper function, calculates the angle between a0 and a1 in ccw sense @@ -99,88 +100,85 @@ rad2deg(double a) inline double calc_delta_angle(const double a0, const double a1) { - double da=range2pi(a1-a0); - if((fabs(da)<1e-9) && (a0<a1)) - da=2*M_PI; + double da = range2pi(a1 - a0); + if ((fabs(da) < 1e-9) && (a0 < a1)) { + da = 2 * M_PI; + } return da; } int -unit_arc_path(Geom::Path &path, Geom::Affine &affine, - double start=0.0, double end=2*M_PI, // angles - bool slice=false) +unit_arc_path(Geom::Path &path_in, Geom::Affine &affine, + double start = 0.0, double end = 2 * M_PI, // angles + bool slice = false) { - double arc_angle = calc_delta_angle(start,end); + double arc_angle = calc_delta_angle(start, end); if (fabs(arc_angle) < 1e-9) { g_warning("angle was 0"); return -1; } // the delta angle - double da=M_PI_2; + double da = M_PI_2; // number of segments with da length - int nda=(int)ceil(arc_angle/M_PI_2); + int nda = (int)ceil(arc_angle / M_PI_2); // recalculate da - da=arc_angle/(double)nda; + da = arc_angle / (double)nda; - bool closed=false; - if (fabs(arc_angle - 2*M_PI) < 1e-8) { + bool closed = false; + if (fabs(arc_angle - 2 * M_PI) < 1e-8) { closed = true; - da=M_PI_2; - nda=4; + da = M_PI_2; + nda = 4; } - start = range2pi(start); - end=start+arc_angle; + double s = range2pi(start); + end = s + arc_angle; - // adopted from: sp-ellipse.cpp - SPCurve * curve=new SPCurve(); - // start point - curve->moveto(cos(start), sin(start)); - double s = start; - for (int i=0; i < nda; s = (++i)*da+start) { + double x0 = cos(s); + double y0 = sin(s); + // construct the path + Geom::Path path(Geom::Point(x0, y0)); + path.setStitching(true); + for (int i = 0; i < nda;) { double e = s + da; - if (e > end) + if (e > end) { e = end; - const double len = 4*tan((e - s)/4)/3; - const double x0 = cos(s); - const double y0 = sin(s); + } + const double len = 4 * tan((e - s) / 4) / 3; const double x1 = x0 + len * cos(s + M_PI_2); const double y1 = y0 + len * sin(s + M_PI_2); const double x3 = cos(e); const double y3 = sin(e); const double x2 = x3 + len * cos(e - M_PI_2); const double y2 = y3 + len * sin(e - M_PI_2); - curve->curveto(x1,y1, x2,y2, x3,y3); + path.appendNew<Geom::CubicBezier>(Geom::Point(x1, y1), Geom::Point(x2, y2), Geom::Point(x3, y3)); + s = (++i) * da + start; + x0 = cos(s); + y0 = sin(s); } if (slice && !closed) { - curve->lineto(0., 0.); + path.appendNew<Geom::LineSegment>(Geom::Point(0.0, 0.0)); } - curve->transform(affine); + path *= affine; - path.append(*curve->first_path()); + path_in.append(path); if ((slice && !closed) || closed) { - path.close(true); + path_in.close(true); } - // give to GC - curve->unref(); return 0; } void gen_iso_frame_paths(Geom::PathVector &path_out, const Geom::Affine &affine) { - Geom::Path rect; - SPCurve curve; - // unit rectangle - curve.moveto(-1, -1); - curve.lineto(1, -1); - curve.lineto(1, 1); - curve.lineto(-1, 1); - //curve.transform(Rotate(-rot_angle)*affine); - curve.transform(affine); - rect.append(*curve.first_path()); + Geom::Path rect(Geom::Point(-1, -1)); + rect.setStitching(true); + rect.appendNew<Geom::LineSegment>(Geom::Point(+1, -1)); + rect.appendNew<Geom::LineSegment>(Geom::Point(+1, +1)); + rect.appendNew<Geom::LineSegment>(Geom::Point(-1, +1)); + rect *= affine; rect.close(true); path_out.push_back(rect); } @@ -188,57 +186,58 @@ gen_iso_frame_paths(Geom::PathVector &path_out, const Geom::Affine &affine) void gen_axes_paths(Geom::PathVector &path_out, const Geom::Affine &affine) { - LineSegment clx(Point(-1,0),Point(1,0)); - LineSegment cly(Point(0,-1),Point(0,1)); + Geom::LineSegment clx(Geom::Point(-1, 0), Geom::Point(1, 0)); + Geom::LineSegment cly(Geom::Point(0, -1), Geom::Point(0, 1)); Geom::Path plx, ply; plx.append(clx); ply.append(cly); - plx*=affine; - ply*=affine; + plx *= affine; + ply *= affine; path_out.push_back(plx); path_out.push_back(ply); } bool -is_ccw(const std::vector<Geom::Point> & pts) +is_ccw(const std::vector<Geom::Point> &pts) { // method: sum up the angles between edges - size_t n=pts.size(); + size_t n = pts.size(); // edges about vertex 0 - Point e0=pts.front()-pts.back(); - Point e1=pts[1]-pts[0]; - Coord sum=cross(e0,e1); + Geom::Point e0(pts.front() - pts.back()); + Geom::Point e1(pts[1] - pts[0]); + Geom::Coord sum = cross(e0, e1); // the rest - for(size_t i=1;i<n;i++) { - e0=e1; - e1=pts[i]-pts[i-1]; - sum+=cross(e0,e1); + for (size_t i = 1; i < n; i++) { + e0 = e1; + e1 = pts[i] - pts[i - 1]; + sum += cross(e0, e1); } // edges about last vertex (closing) - e0=e1; - e1=pts.front()-pts.back(); - sum+=cross(e0,e1); + e0 = e1; + e1 = pts.front() - pts.back(); + sum += cross(e0, e1); // close the - if(sum<0) + if (sum < 0) { return true; - else + } else { return false; + } } void -endpoints2angles(const bool ccw_wind, const bool use_other_arc, const Point &p0, const Point &p1, Coord &a0, Coord &a1) +endpoints2angles(const bool ccw_wind, const bool use_other_arc, const Geom::Point &p0, const Geom::Point &p1, Geom::Coord &a0, Geom::Coord &a1) { - if(!p0.isZero() && !p1.isZero()) { - a0=atan2(p0); - a1=atan2(p1); - if(!ccw_wind) { - std::swap(a0,a1); + if (!p0.isZero() && !p1.isZero()) { + a0 = atan2(p0); + a1 = atan2(p1); + if (!ccw_wind) { + std::swap(a0, a1); } - if(!use_other_arc) { - std::swap(a0,a1); + if (!use_other_arc) { + std::swap(a0, a1); } } } @@ -249,42 +248,52 @@ endpoints2angles(const bool ccw_wind, const bool use_other_arc, const Point &p0, * slice, circle etc. the final result will be different */ Geom::PathVector -LPEPts2Ellipse::doEffect_path (Geom::PathVector const & path_in) +LPEPts2Ellipse::doEffect_path(Geom::PathVector const &path_in) { - PathVector path_out; + Geom::PathVector path_out; - if(draw_ori_path.get_value()){ - path_out.insert(path_out.end(),path_in.begin(),path_in.end()); + if (draw_ori_path.get_value()) { + path_out.insert(path_out.end(), path_in.begin(), path_in.end()); } // from: extension/internal/odf.cpp // get all points - std::vector<Point> pts; - for(const auto & pit : path_in) { + std::vector<Geom::Point> pts; + for (Geom::PathVector::const_iterator pit = path_in.begin(); pit != path_in.end(); ++pit) { // extract first point of this path - pts.push_back(pit.initialPoint()); + pts.push_back(pit->initialPoint()); // iterate over all curves - for (const auto & cit : pit) { - pts.push_back(cit.finalPoint()); + for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end(); ++cit) { + pts.push_back(cit->finalPoint()); } } // avoid identical start-point and end-point - if(pts.front() == pts.back()) { + if (pts.front() == pts.back()) { pts.pop_back(); } // special mode: Use first two edges, interpret them as two sides of a parallelogram and // generate an ellipse residing inside the parallelogram. This effect is quite useful when // generating isometric views. Hence, the name. - //if(gen_isometric.get_value()) - if(method == EM_ISONOMETRIC_CIRCLE) { - if(0!=genIsometricEllipse (pts, path_out)) - return path_in; - } else { - if(0!=genFitEllipse(pts, path_out)) - return path_in; + switch(method) { + case EM_ISOMETRIC_CIRCLE: + if (0 != genIsometricEllipse(pts, path_out)) { + return path_in; + } break; + case EM_STEINER_ELLIPSE: + if (0 != genSteinerEllipse(pts, false, path_out)) { + return path_in; + } break; + case EM_STEINER_INELLIPSE: + if (0 != genSteinerEllipse(pts, true, path_out)) { + return path_in; + } break; + default: + if (0 != genFitEllipse(pts, path_out)) { + return path_in; + } } return path_out; } @@ -296,164 +305,258 @@ LPEPts2Ellipse::doEffect_path (Geom::PathVector const & path_in) * ellipse. With 5 points each point is on the ellipse. For less points we get a circle. */ int -LPEPts2Ellipse::genFitEllipse (std::vector<Geom::Point> const & pts, - Geom::PathVector & path_out) +LPEPts2Ellipse::genFitEllipse(std::vector<Geom::Point> const &pts, + Geom::PathVector &path_out) { // rotation angle based on user provided rot_axes to position the vertices const double rot_angle = -deg2rad(rot_axes); // negative for ccw rotation - Affine affine; - affine*=Rotate(rot_angle); - Coord a0=0; - Coord a1=2*M_PI; - - if(pts.size()<2) { + Geom::Affine affine; + affine *= Geom::Rotate(rot_angle); + Geom::Coord a0 = 0; + Geom::Coord a1 = 2 * M_PI; + + if (pts.size() < 2) { return -1; - } else if(pts.size()==2) { + } else if (pts.size() == 2) { // simple line: circle in the middle of the line to the vertices - Point line=pts.front()-pts.back(); - double radius=line.length()*0.5; - if(radius<1e-9) + Geom::Point line = pts.front() - pts.back(); + double radius = line.length() * 0.5; + if (radius < 1e-9) { return -1; - Point center=middle_point(pts.front(),pts.back()); - Circle circle(center[0],center[1],radius); - affine*=Scale(circle.radius()); - affine*=Translate(circle.center()); + } + Geom::Point center = middle_point(pts.front(), pts.back()); + Geom::Circle circle(center[0], center[1], radius); + affine *= Geom::Scale(circle.radius()); + affine *= Geom::Translate(circle.center()); Geom::Path path; - unit_arc_path(path,affine); + unit_arc_path(path, affine); path_out.push_back(path); - } else if(pts.size()>=5 && EM_AUTO == method) { //!only_circle.get_value()) { + } else if (pts.size() >= 5 && EM_AUTO == method) { //!only_circle.get_value()) { // do ellipse try { - Ellipse ellipse; + Geom::Ellipse ellipse; ellipse.fit(pts); - affine*=Scale(ellipse.ray(X),ellipse.ray(Y)); - affine*=Rotate(ellipse.rotationAngle()); - affine*=Translate(ellipse.center()); - if(gen_arc.get_value()) { - Affine inv_affine=affine.inverse(); - Point p0=pts.front()*inv_affine; - Point p1=pts.back()*inv_affine; - const bool ccw_wind=is_ccw(pts); - endpoints2angles(ccw_wind,other_arc.get_value(),p0,p1,a0,a1); + affine *= Geom::Scale(ellipse.ray(Geom::X), ellipse.ray(Geom::Y)); + affine *= Geom::Rotate(ellipse.rotationAngle()); + affine *= Geom::Translate(ellipse.center()); + if (gen_arc.get_value()) { + Geom::Affine inv_affine = affine.inverse(); + Geom::Point p0 = pts.front() * inv_affine; + Geom::Point p1 = pts.back() * inv_affine; + const bool ccw_wind = is_ccw(pts); + endpoints2angles(ccw_wind, other_arc.get_value(), p0, p1, a0, a1); } Geom::Path path; - unit_arc_path(path,affine,a0,a1,slice_arc.get_value()); + unit_arc_path(path, affine, a0, a1, slice_arc.get_value()); path_out.push_back(path); - if(draw_axes.get_value()) { - gen_axes_paths(path_out,affine); + if (draw_axes.get_value()) { + gen_axes_paths(path_out, affine); } - } catch(...) { + } catch (...) { return -1; } } else { // do a circle (3,4 points, or only_circle set) try { - Circle circle; + Geom::Circle circle; circle.fit(pts); - affine*=Scale(circle.radius()); - affine*=Translate(circle.center()); - - if(gen_arc.get_value()) - { - Point p0=pts.front()-circle.center(); - Point p1=pts.back()-circle.center(); - const bool ccw_wind=is_ccw(pts); - endpoints2angles(ccw_wind,other_arc.get_value(),p0,p1,a0,a1); + affine *= Geom::Scale(circle.radius()); + affine *= Geom::Translate(circle.center()); + + if (gen_arc.get_value()) { + Geom::Point p0 = pts.front() - circle.center(); + Geom::Point p1 = pts.back() - circle.center(); + const bool ccw_wind = is_ccw(pts); + endpoints2angles(ccw_wind, other_arc.get_value(), p0, p1, a0, a1); } Geom::Path path; - unit_arc_path(path,affine,a0,a1,slice_arc.get_value()); + unit_arc_path(path, affine, a0, a1, slice_arc.get_value()); path_out.push_back(path); - } catch(...) { + } catch (...) { return -1; } } // draw frame? - if(gen_isometric_frame.get_value()) { - gen_iso_frame_paths(path_out,affine); + if (gen_isometric_frame.get_value()) { + gen_iso_frame_paths(path_out, affine); } // draw axes? - if(draw_axes.get_value()) { - gen_axes_paths(path_out,affine); + if (draw_axes.get_value()) { + gen_axes_paths(path_out, affine); } return 0; } int -LPEPts2Ellipse::genIsometricEllipse (std::vector<Geom::Point> const & pts, - Geom::PathVector & path_out) +LPEPts2Ellipse::genIsometricEllipse(std::vector<Geom::Point> const &pts, + Geom::PathVector &path_out) { // take the first 3 vertices for the edges - if(pts.size() < 3) return -1; + if (pts.size() < 3) { + return -1; + } // calc edges - Point e0=pts[0]-pts[1]; - Point e1=pts[2]-pts[1]; + Geom::Point e0 = pts[0] - pts[1]; + Geom::Point e1 = pts[2] - pts[1]; - Coord ce=cross(e0,e1); + Geom::Coord ce = cross(e0, e1); // parallel or one is zero? - if(fabs(ce)<1e-9) return -1; + if (fabs(ce) < 1e-9) { + return -1; + } // unit vectors along edges - Point u0=unit_vector(e0); - Point u1=unit_vector(e1); + Geom::Point u0 = unit_vector(e0); + Geom::Point u1 = unit_vector(e1); // calc angles - Coord a0=atan2(e0); + Geom::Coord a0 = atan2(e0); // Coord a1=M_PI_2-atan2(e1)-a0; - Coord a1=acos(dot(u0,u1))-M_PI_2; + Geom::Coord a1 = acos(dot(u0, u1)) - M_PI_2; // if(fabs(a1)<1e-9) return -1; - if(ce<0) a1=-a1; + if (ce < 0) { + a1 = -a1; + } // lengths: l0= length of edge 0; l1= height of parallelogram - Coord l0=e0.length()*0.5; - Point e0n=e1-dot(u0,e1)*u0; - Coord l1=e0n.length()*0.5; + Geom::Coord l0 = e0.length() * 0.5; + Geom::Point e0n = e1 - dot(u0, e1) * u0; + Geom::Coord l1 = e0n.length() * 0.5; // center of the ellipse - Point pos=pts[1]+0.5*(e0+e1); + Geom::Point pos = pts[1] + 0.5 * (e0 + e1); + + // rotation angle based on user provided rot_axes to position the vertices + const double rot_angle = -deg2rad(rot_axes); // negative for ccw rotation + + // build up the affine transformation + Geom::Affine affine; + affine *= Geom::Rotate(rot_angle); + affine *= Geom::Scale(l0, l1); + affine *= Geom::HShear(-tan(a1)); + affine *= Geom::Rotate(a0); + affine *= Geom::Translate(pos); + + Geom::Path path; + unit_arc_path(path, affine); + path_out.push_back(path); + + // draw frame? + if (gen_isometric_frame.get_value()) { + gen_iso_frame_paths(path_out, affine); + } + + // draw axes? + if (draw_axes.get_value()) { + gen_axes_paths(path_out, affine); + } + + return 0; +} + +void +evalSteinerEllipse(Geom::Point const &pCenter, + Geom::Point const &pCenter_Pt2, + Geom::Point const &pPt0_Pt1, + const double &angle, + Geom::Point &pRes) +{ + // formula for the evaluation of points on the steiner ellipse using parameter angle + pRes = pCenter + + pCenter_Pt2*cos(angle) + + pPt0_Pt1*sin(angle)/sqrt(3); +} + +int +LPEPts2Ellipse::genSteinerEllipse(std::vector<Geom::Point> const &pts, + bool gen_inellipse, + Geom::PathVector &path_out) +{ + // take the first 3 vertices for the edges + if (pts.size() < 3) { + return -1; + } + // calc center + Geom::Point pCenter = (pts[0]+pts[1]+pts[2])/3; + // calc main directions of affine triangle + Geom::Point f1 = pts[2]-pCenter; + Geom::Point f2 = (pts[1]-pts[0])/sqrt(3); + + // calc zero angle t0 + const double denominator = dot(f1, f1) - dot(f2, f2); + double t0=0; + if(fabs(denominator) > 1e-12) { + const double cot2t0 = 2.0 * dot(f1, f2) / denominator; + t0 = atan(cot2t0)/2.0; + } + + // calc relative points of main axes (for axis directions) + Geom::Point p0(0,0), pRel0, pRel1; + evalSteinerEllipse(p0, pts[2]-pCenter, pts[1]-pts[0], t0, pRel0); + evalSteinerEllipse(p0, pts[2]-pCenter, pts[1]-pts[0], t0+M_PI_2, pRel1); + Geom::Coord l0 = pRel0.length(); + Geom::Coord l1 = pRel1.length(); + + // basic rotation + double a0 = atan2(pRel0); + + bool swapped=false; + + if (l1 > l0) { + std::swap(l0,l1); + a0 += M_PI_2; + swapped = true; + } + + // the steiner inellipse is just scaled down by 2 + if(gen_inellipse) { + l0/=2; + l1/=2; + } // rotation angle based on user provided rot_axes to position the vertices const double rot_angle = -deg2rad(rot_axes); // negative for ccw rotation // build up the affine transformation - Affine affine; - affine*=Rotate(rot_angle); - affine*=Scale(l0,l1); - affine*=HShear(-tan(a1)); - affine*=Rotate(a0); - affine*=Translate(pos); + Geom::Affine affine; + affine *= Geom::Rotate(rot_angle); + affine *= Geom::Scale(l0, l1); + affine *= Geom::Rotate(a0); + affine *= Geom::Translate(pCenter); Geom::Path path; - unit_arc_path(path,affine); + unit_arc_path(path, affine); path_out.push_back(path); // draw frame? - if(gen_isometric_frame.get_value()) { - gen_iso_frame_paths(path_out,affine); + if (gen_isometric_frame.get_value()) { + gen_iso_frame_paths(path_out, affine); } // draw axes? - if(draw_axes.get_value()) { - gen_axes_paths(path_out,affine); + if (draw_axes.get_value()) { + gen_axes_paths(path_out, affine); } return 0; } + /* ######################## */ } //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 : +/* + 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 : diff --git a/src/live_effects/lpe-pts2ellipse.h b/src/live_effects/lpe-pts2ellipse.h index f9fd90109..1a4844893 100644 --- a/src/live_effects/lpe-pts2ellipse.h +++ b/src/live_effects/lpe-pts2ellipse.h @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0-or-later #ifndef INKSCAPE_LPE_PTS_TO_ELLIPSE_H #define INKSCAPE_LPE_PTS_TO_ELLIPSE_H @@ -12,7 +11,7 @@ * * Copyright (C) Markus Schwienbacher 2013 <mschwienbacher@gmail.com> * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. + * Released under GNU GPL, read the file 'COPYING' for more information */ #include "live_effects/effect.h" @@ -27,27 +26,33 @@ namespace LivePathEffect { enum EllipseMethod { EM_AUTO, EM_CIRCLE, - EM_ISONOMETRIC_CIRCLE, + EM_ISOMETRIC_CIRCLE, + EM_STEINER_ELLIPSE, + EM_STEINER_INELLIPSE, EM_END }; class LPEPts2Ellipse : public Effect { public: - LPEPts2Ellipse(LivePathEffectObject *lpeobject); + explicit LPEPts2Ellipse(LivePathEffectObject *lpeobject); ~LPEPts2Ellipse() override; - Geom::PathVector doEffect_path (Geom::PathVector const & path_in) override; + Geom::PathVector doEffect_path(Geom::PathVector const &path_in) override; private: - LPEPts2Ellipse(const LPEPts2Ellipse&) = delete; - LPEPts2Ellipse& operator=(const LPEPts2Ellipse&) = delete; + LPEPts2Ellipse(const LPEPts2Ellipse &); + LPEPts2Ellipse &operator=(const LPEPts2Ellipse &); - int genIsometricEllipse (std::vector<Geom::Point> const & points_in, - Geom::PathVector & path_out); + int genIsometricEllipse(std::vector<Geom::Point> const &points_in, + Geom::PathVector &path_out); - int genFitEllipse (std::vector<Geom::Point> const & points_in, - Geom::PathVector & path_out); + int genFitEllipse(std::vector<Geom::Point> const &points_in, + Geom::PathVector &path_out); + + int genSteinerEllipse(std::vector<Geom::Point> const &points_in, + bool gen_inellipse, + Geom::PathVector &path_out); EnumParam<EllipseMethod> method; BoolParam gen_isometric_frame; |
