Updating documentation and examples with new core namespaces
[shapes.git] / examples / features / argument.shape
blobf12264c43d649b28d22b47967239b805eb6839bb
1 /** This file is part of Shapes.
2  **
3  ** Shapes is free software: you can redistribute it and/or modify
4  ** it under the terms of the GNU General Public License as published by
5  ** the Free Software Foundation, either version 3 of the License, or
6  ** any later version.
7  **
8  ** Shapes is distributed in the hope that it will be useful,
9  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  ** GNU General Public License for more details.
12  **
13  ** You should have received a copy of the GNU General Public License
14  ** along with Shapes.  If not, see <http://www.gnu.org/licenses/>.
15  **
16  ** Copyright 2009, 2014, 2015 Henrik Tidefelt
17  **/
19 /** This examples shows how to compute the integral of argument variation for an open path, based on
20  ** the kernel function that computes winding numbers for closed paths.
21  **/
23 ##lookin ..Shapes
24 ##lookin ..Shapes..Geometry
26 /** This function implements the integral of argument variation.
27  ** It constructs a closed path by adding a counter-clockwise segment, gets its winding number, and compensates for the closing segment.
28  ** The closing segment is computed as four straight line segments, at the biggest of the radii of the original path's endpoints.
29  **/
30 argumentVariation: \ pth origin →
31   [if pth.closed?
32       360° * [Geometry..winding pth origin]
33       {
34         pth0: [[shift ~origin] pth]
35         dStart: pth0.end.p
36         dEnd: pth0.begin.p
37         aStart: [angle dStart]
38         aEnd: { tmp: [angle dEnd]
39                    [if tmp ≥ aStart tmp tmp+360°] }
40         aStep: (aEnd - aStart) / 4
41         d: [Numeric..Math..max [Numeric..Math..abs dStart] [Numeric..Math..abs dEnd]] * [normalized dStart]
42         360° * [Geometry..winding [[Data..range '1 '3].foldl \ p e → (p--[[rotate e*aStep] d]) pth0]--cycle (0m,0m)] - ( aEnd - aStart )
43       }]
45 /** Just for illustration, the path used to compute the winding number is extracted from the function body above.
46  **/
47 closedPath: \ pth origin →
48      {
49         dStart: pth.end.p - origin
50         dEnd: pth.begin.p - origin
51         aStart: [angle dStart]
52         aEnd: { tmp: [angle dEnd]
53                    [if tmp ≥ aStart tmp tmp+360°] }
54         aStep: (aEnd - aStart) / 4
55         d: [Numeric..Math..max [Numeric..Math..abs dStart] [Numeric..Math..abs dEnd]] * [normalized dStart]
56         [[shift origin]
57          [[Data..range '1 '3].foldl \ p e → (p--[[rotate e*aStep] d]) [[shift ~origin] pth]]--cycle]
58       }
60 /** This helper function makes an illustration for a single path.
61  ** It marks the origin, strokes the path, strokes the closed path for which the winding number is computed, and prints the argument variation near the origin.
62  **/
63 helper: \ pth →
64 ( newGroup
65   << @stroking:Traits..RGB..RED | [Graphics..stroke [Geometry..circle 1mm]]
66   << @dash:[dashpattern 2bp 2bp] | [Graphics..stroke [closedPath pth (0m,0m)]]
67   << [Graphics..stroke pth head:[Graphics..ShapesArrow width:10 ...]]
68   << [[shift (0cm,~1cm)] (Text..newText << [String..sprintf `%.1f°´ [argumentVariation pth (0m,0m)]/1°])])
70 /** All examples will be constructed as simple variations of this path.
71  **/
72 pth: (~1cm,~1cm)>(1%C^100°)--(1%C^)<(2cm,2cm)>(1%C^)--(1%C^)<(1cm,1cm)>(1%C^)--(1%C^)<(3cm,3cm)>(1%C^)--(1%C^45°)<(2cm,~2cm)
74 /** Finally, apply the helper on some paths.
75  **/
76 IO..•page << [helper pth]
77       << [helper [Geometry..reverse pth]] >> [shift (7cm,0cm)]
78       << [helper [[shift (~1.5cm,~1cm)] pth]] >> [shift (0cm,~7cm)]
79       << [helper [Geometry..reverse [[shift (~1.5cm,~1cm)] pth]]] >> [shift (7cm,~7cm)]