20#include <glibmm/i18n.h>
63 if ((flags & SP_OBJECT_WRITE_BUILD) && !
repr) {
67 if (flags & SP_OBJECT_WRITE_EXT) {
125 this->
exp = g_ascii_strtod (value,
nullptr);
126 this->
exp = CLAMP (this->
exp, 0.0, 1000.0);
136 this->
revo = g_ascii_strtod (value,
nullptr);
137 this->
revo = CLAMP (this->
revo, 0.05, 1024.0);
155 this->
arg = g_ascii_strtod (value,
nullptr);
173 this->
t0 = g_ascii_strtod (value,
nullptr);
174 this->
t0 = CLAMP (this->
t0, 0.0, 0.999);
196 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
214 return g_strdup_printf (_(
"with %3f turns"), this->
revo);
226#define FITTING_MAX_BEZIERS 4
227#define BEZIER_LENGTH (BEZIER_SIZE * FITTING_MAX_BEZIERS)
229 g_assert (dstep > 0);
230 g_assert (is_unit_vector (hat1));
236 for (d = *t, i = 0; i <= SAMPLE_SIZE; d += dstep, i++) {
237 darray[i] = this->
getXY(d);
241 if ((i != 0) && (darray[i] == darray[i - 1]) && (d < 1.0)) {
263 double const next_t = d - 2 * dstep;
273 SPIRAL_TOLERANCE*SPIRAL_TOLERANCE,
274 FITTING_MAX_BEZIERS);
276 g_assert(depth * BEZIER_SIZE <= gint(G_N_ELEMENTS(bezier)));
279 if (*t == spiral->t0 || *t == 1.0)
280 g_print (
"[%s] depth=%d, dstep=%g, t0=%g, t=%g, arg=%g\n",
281 debug_state, depth, dstep, spiral->t0, *t, spiral->arg);
285 for (i = 0; i < 4*depth; i += 4) {
286 c->curveto(bezier[i + 1],
292 g_print (
"cant_fit_cubic: t=%g\n", *t);
294 for (i = 1; i < SAMPLE_SIZE; i++)
295 c->lineto(darray[i]);
300 g_assert (is_unit_vector (hat2));
315 g_print (
"cx=%g, cy=%g, exp=%g, revo=%g, rad=%g, arg=%g, t0=%g\n",
328 double const tstep = SAMPLE_STEP / this->
revo;
329 double const dstep = tstep / (SAMPLE_SIZE - 1);
335 for (t = this->
t0; t < (1.0 - tstep);) {
336 this->
fitAndDraw(&c, dstep, darray, hat1, hat2, &t);
341 if ((1.0 - t) > SP_EPSILON) {
342 this->
fitAndDraw(&c, (1.0 - t) / (SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t);
352void SPSpiral::setPosition(gdouble cx, gdouble cy, gdouble exp, gdouble revo, gdouble rad, gdouble arg, gdouble t0) {
361 this->rad =
MAX (
rad, 0.0);
363 this->t0 = CLAMP(
t0, 0.0, 0.999);
403 gdouble
const s = hypot(ret[0], ret[1]);
450 g_assert (this->
exp >= 0.0);
452 g_assert (this->
exp <= 1000.0);
457 double const rad = this->rad * pow(t, (
double)this->
exp);
458 double const arg = 2.0 * M_PI * this->
revo * t + this->
arg;
477 g_assert (this->
exp >= 0.0);
480 double const t_scaled = 2.0 * M_PI * this->
revo * t;
481 double const arg = t_scaled + this->
arg;
482 double const s = sin(
arg);
483 double const c = cos(
arg);
485 if (this->
exp == 0.0) {
487 }
else if (t_scaled == 0.0) {
491 double const s_len = L2 (unrotated);
492 g_assert (s_len != 0);
522 g_assert (is_unit_vector(ret));
531 *
rad = this->rad * pow(t, (
double)this->
exp);
535 *
arg = 2.0 * M_PI * this->
revo * t + this->
arg;
547 if (rad < 0.0 || rad > SP_HUGE) {
548 g_warning(
"rad(t=0)=%g",
rad);
554 if (rad < 0.0 || rad > SP_HUGE) {
555 g_warning(
"rad(t=1)=%g",
rad);
Lookup dictionary for attributes/properties.
Bezier fitting algorithms.
3x3 matrix representing an affine transformation.
bool isUniformScale(Coord eps=EPSILON) const
Check whether this matrix represents pure uniform scaling.
Affine inverse() const
Compute the inverse matrix.
Affine withoutTranslation() const
Two-dimensional point that doubles as a vector.
void normalize()
Normalize the vector representing the point.
Storing of snapping preferences.
void setTargetSnappable(Inkscape::SnapTargetType const target, bool enabled)
bool isTargetSnappable(Inkscape::SnapTargetType const target) const
Interface for refcounted XML nodes.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
Wrapper around a Geom::PathVector object.
void moveto(Geom::Point const &p)
Perform a moveto to a point, thus starting a new subpath.
Typed SVG document implementation.
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
void adjust_gradient(Geom::Affine const &postmul, bool set=false)
void adjust_pattern(Geom::Affine const &postmul, bool set=false, PaintServerTransform=TRANSFORM_BOTH)
void adjust_stroke(double ex)
bool pathEffectsEnabled() const
bool optimizeTransforms()
returns false when LPE write unoptimiced
Inkscape::XML::Node * repr
void requestModified(unsigned int flags)
Requests that a modification notification signal be emitted later (e.g.
void readAttr(char const *key)
Read value of key attribute from XML node into object.
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
Base class for shapes, including <path> element.
void update(SPCtx *ctx, unsigned int flags) override
void snappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs) const override
bool prepareShapeForLPE(SPCurve const *c)
void set(SPAttr key, char const *value) override
void build(SPDocument *document, Inkscape::XML::Node *repr) override
void update_patheffect(bool write) override
std::shared_ptr< SPCurve const > _curve
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
bool checkBrokenPathEffect()
void update_patheffect(bool write) override
void set_shape() override
bool isInvalid() const
Return true if spiral has properties that make it invalid.
void build(SPDocument *doc, Inkscape::XML::Node *repr) override
Geom::Point getTangent(double t) const
Returns the derivative of sp_spiral_get_xy with respect to t, scaled to a unit vector.
void update(SPCtx *ctx, unsigned int flags) override
float revo
Spiral revolution factor.
const char * typeName() const override
The item's type name, not node tag name.
float exp
Spiral expansion factor.
float arg
Spiral argument.
const char * displayName() const override
The item's type name as a translated human string.
void fitAndDraw(SPCurve *c, double dstep, Geom::Point darray[], Geom::Point const &hat1, Geom::Point &hat2, double *t) const
Fit beziers together to spiral and draw it.
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void setPosition(double cx, double cy, double exp, double revo, double rad, double arg, double t0)
Set spiral properties and update display.
char * description() const override
void getPolar(double t, double *rad, double *arg) const
Compute rad and/or arg for point on spiral.
Geom::Affine set_transform(Geom::Affine const &xform) override
Set spiral transform.
void snappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs) const override
void set(SPAttr key, char const *value) override
Geom::Point getXY(double t) const
Return one of the points on the spiral.
int bezier_fit_cubic_full(Point bezier[], int split_points[], Point const data[], int len, Point const &tHat1, Point const &tHat2, double error, unsigned max_beziers)
Fit a multi-segment Bezier curve to a set of digitized points, without possible weedout of identical ...
@ SNAPSOURCE_OBJECT_MIDPOINT
@ SNAPTARGET_OBJECT_MIDPOINT
static cairo_user_data_key_t key
Some utility classes to store various kinds of snap candidates.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
unsigned int sp_svg_length_read_computed_absolute(gchar const *str, float *length)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)
void dot(Cairo::RefPtr< Cairo::Context > &cr, double x, double y)
Interface for XML documents.