From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/3rdparty/2geom/doc/manual2/piecewise | 134 +++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/3rdparty/2geom/doc/manual2/piecewise (limited to 'src/3rdparty/2geom/doc/manual2/piecewise') diff --git a/src/3rdparty/2geom/doc/manual2/piecewise b/src/3rdparty/2geom/doc/manual2/piecewise new file mode 100644 index 0000000..9f1bd98 --- /dev/null +++ b/src/3rdparty/2geom/doc/manual2/piecewise @@ -0,0 +1,134 @@ +h1. *Piecewise* + +In order to represent functions with a complex shape, it is necessary +to define functions in a piecewise manner. In the graphics world this +sort of function, when parametric, is often referred to as a 'spline'. +Even beyond the representation of paths, it is also often necessary +for mathematical operations to return piecewise functions, as otherwise +the single-fragment versions would require an inordinate degree to +still be accurate. An example of this is the *inverse* function. + +In the world of lib2geom, this is implemented as the *Piecewise* +template class. It manages a sequence of fragment 'segments' and the +cuts between them. These cuts are the various t-values which separate +the different segments. + +h2. Cuts + +The first and last cuts of a piecewise define it's intended range, and +the intermediary cuts separate the segments. With indices, segment i +is always bordered on the left with cut i and on the right with cut i+1. +In general, c = s+1, where c is the number of cuts and s is the number +of segments. These invariants are checked by the +@bool Piecewise::invariants();@ method. + +The cuts essentially define the position and scale of each segment. +For example, if the left and right cuts are 0.5 apart, the segment is +half its regular size; the derivative will be twice as big. + +h4. Cut Query Functions + +

+unsigned Piecewise::segN(double, int low = 0, int high = -1) const;
+double Piecewise::segT(double, int = -1) const;
+double mapToDomain(double t, unsigned i) const;
+
+ +These functions use the cut information to ascertain which segment a +t-value lies within ( *segN* ), and what the t-value is for that segment +at that particular point ( *segT* ). *segN* takes two optional parameters +which limit the range of the search, and are used internally as it is +defined as a recursive binary search. These may be used if you are sure +that the desired segment index lies within the range. *segT* takes an +optional parameter for the case where you already know the segment number. + +mapToDomain is the inverse of segT, as it takes a t-value for a particular +segment, and returns the global piecewise time for that point. + +h4. @ Interval Piecewise::domain() const; @ + +The *domain* function returns the Interval of the intended domain of the +function, from the first cut to the last cut. + +h4. Cut Modification Functions + +

+void Piecewise::offsetDomain(double o) 
+void Piecewise::scaleDomain(double s)
+void Piecewise::setDomain(Interval dom)
+
+ +These functions very simply transform the cuts with linear transformations. + +h3. Technical Details + +As the cuts are simply a public std::vector, they may also be accessed as +@pw.cuts@. + +While the actual segments begin on the first cut and end on the last, +the function is defined throughout all inputs by extending the first +and last segments. The exact switching between segments is arbitrarily +such that beginnings (t=0) have priority over endings (t=1). This only +really matters if it is discontinuous at that location. + +In the context of 2d parametrically defined curves, the usefulness of cuts +becomes less apparrent, as they make no real difference for the display +of the curves. Rather, cuts become more of an agreement between various +functions such that the proper data aligns. + +h2. Construction + +Most of the time there is no need for raw construction of *Piecewise* +functions, as they are usually obtained from operations and other sources. + +The following constructors defined for *Piecewise*: +* The blank constructor +* A constructor which explicitly lifts a fragment to a *Piecewise* on [0,1] +* A constructor which takes the *output_type*, and creates a constant function + +

+void Piecewise::push_seg(T);
+void Piecewise::push_cut(double);
+void Piecewise::push(T, double);
+
+ +The usual method for raw construction is to construct a blank *Piecewise* +function, and use these push methods to load the content. *push_seg* and +*push_cut* simply add to the segment and cut lists, although *push_cut* +also checks that the cut time is larger than the last cut. The current +recommended method for calling these functions is to have one initial +*push_cut*, followed by successive calls to *push*, as this will guarantee +that the cuts and segments properly align. + +h2. Operations + +h3. Arithmetic + +*Piecewise* has many arithmetic operations, and implements +*OffsetableConcept*, *ScalableConcept*, *AddableConcept*, and +*MultiplicableConcept*. The operations which operate on two Piecewise +functions (Addable and Multiplicable) work by interleaving the cuts using +mutual *partition* calls, and iterating the resulting segments. + +h3. Fragment Wrapping + +While *Piecewise* is not a fragment (it does not have the [0,1] domain), +it has many functions reminiscient of *FragmentConcept*, including the +bounds functions, () and valueAt. + +(TODO: reverse function?) + +h3. Concatenation + +

+void Piecewise::concat(const Piecewise &other);
+void Piecewise::continuousConcat(const Piecewise &other);
+
+ +These functions efficiently append another *Piecewise* to the end of a +*Piecewise*. They offset the _other_ *Piecewise* in time such that it is +flush with the end of this *Piecewise*. *continuousConcat* is basically +the same except that it also offsets in space so the functions also match +in value. + +(TODO: compose/derivative/integral) -- cgit v1.2.3