http://mathling.com/art/mutations library module
http://mathling.com/art/mutations
Mutation functions: point to point in the bi-unit square [-1,1]x[-1,1]
The functions are set up to allow them to be selected generically from
a mapping table (as in the fractal flame code) or applied directly.
Parameters:
Each parameterized function has a parameter with its name which is a map
its parameters. e.g. "mutation.blob" holds parameters for the "blob" function
See Scott Draves & Erik Reckase "The Fractal Flame Algorithm" for specifics.
These can be used to provide default parameter settings for each function.
In addition, the functions are given a weight parameter, which some of
them use. In the fractal flame component this is set to the function weight
in the selection tables. But see this:mutation() for defaulting.
Randomizers:
Copyright© Mary Holstege 2020-2023
CC-BY (https://creativecommons.org/licenses/by/4.0/)
Imports
http://mathling.com/geometric/mutationimport module namespace ann="http://mathling.com/geometric/mutation" at "../geo/mutation.xqy"http://mathling.com/core/callable
import module namespace f="http://mathling.com/core/callable" at "../core/callable.xqy"http://mathling.com/geometric/coordinates
import module namespace coordinates="http://mathling.com/geometric/coordinates" at "../geo/coordinates.xqy"http://mathling.com/type/distribution
import module namespace dist="http://mathling.com/type/distribution" at "../types/distributions.xqy"http://mathling.com/geometric/rectangle
import module namespace box="http://mathling.com/geometric/rectangle" at "../geo/rectangle.xqy"http://mathling.com/type/wrapper
import module namespace wrapper="http://mathling.com/type/wrapper" at "../types/wrapper.xqy"http://mathling.com/geometric
import module namespace geom="http://mathling.com/geometric" at "../geo/euclidean.xqy"http://mathling.com/geometric/affine
import module namespace affine="http://mathling.com/geometric/affine" at "../geo/affine.xqy"http://mathling.com/geometric/point
import module namespace point="http://mathling.com/geometric/point" at "../geo/point.xqy"http://mathling.com/core/random
import module namespace rand="http://mathling.com/core/random" at "../core/random.xqy"http://mathling.com/art/core
import module namespace core="http://mathling.com/art/core" at "../art/core.xqy"http://mathling.com/core/utilities
import module namespace util="http://mathling.com/core/utilities" at "../core/utilities.xqy"http://mathling.com/core/vector
import module namespace v="http://mathling.com/core/vector" at "../core/vector.xqy"http://mathling.com/noise/perlin
import module namespace perlin="http://mathling.com/noise/perlin" at "../noise/perlin.xqy"http://mathling.com/noise/modifiers
import module namespace noise="http://mathling.com/noise/modifiers" at "../noise/modifiers.xqy"http://mathling.com/core/config
import module namespace config="http://mathling.com/core/config" at "../core/config.xqy"http://mathling.com/core/errors
import module namespace errors="http://mathling.com/core/errors" at "../core/errors.xqy"
Variables
Variable: $URI as xs:string
Variable: $MUTATIONS as xs:string*
Variable: $FOREGROUND-MUTATIONS as xs:string*
Variable: $BACKGROUND-MUTATIONS as xs:string*
Functions
Function: rendering-parameters
declare function rendering-parameters($canvas as map(xs:string,item()*),
$algorithm-parameters as map(xs:string,item()*)) as map(xs:string,item()*)
declare function rendering-parameters($canvas as map(xs:string,item()*), $algorithm-parameters as map(xs:string,item()*)) as map(xs:string,item()*)
Params
- canvas as map(xs:string,item()*)
- algorithm-parameters as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:rendering-parameters( $canvas as map(xs:string,item()*), $algorithm-parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { map {} }
Function: algorithm-parameters
declare function algorithm-parameters($resolution as xs:string,
$canvas as map(xs:string, item()*)) as map(xs:string,item()*)
declare function algorithm-parameters($resolution as xs:string, $canvas as map(xs:string, item()*)) as map(xs:string,item()*)
Params
- resolution as xs:string
- canvas as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:algorithm-parameters( $resolution as xs:string, $canvas as map(xs:string, item()*) ) as map(xs:string,item()*) { map { "description": "Mutation functions", "mutation.weights": map {}, "mutation.blob": map { "high": 0.75, "low": 0.25, "waves": 7 }, "mutation.PDJ": map { "a": 0.9, "b": 0.75, "c": 0.9, "d": 0.75 }, "mutation.fan2": map { "x": 0.1, "y": -0.1 }, "mutation.rings2": map { "val": 0.5 }, "mutation.perspective": map { "angle": util:radians(30), "dist": 0.75 }, "mutation.juliaN": map { "power": 0.5, "dist": 0.4 }, "mutation.juliaScope": map { "power": 0.5, "dist": 0.4 }, "mutation.radialBlur": map { "angle": util:radians(20) }, "mutation.pie": map { "slices": 7, "rotation": util:radians(20), "thickness": 0.2 }, "mutation.ngon": map { "power": 0.3, "sides": 7, "corners": 4, "circle": 0.3 }, "mutation.curl": map { "c1": 0.8, "c2": 0.7 }, "mutation.rectangles": map { "x": 0.25, "y": -0.1 }, "mutation.flower": map { "holes": 0.5, "petals": 3 }, "mutation.supershape": map { "holes": 0.5, "m": 3, "rnd": 0.5, "n1": 20.0, "n2": 10.0, "n3": 10.0 }, "mutation.conic": map { "holes": 0.5, "eccentricity": 0.5 }, "mutation.parabola": map { "width": 1.0, "height": 1.0 }, "mutation.bent2": map { "x": 2.0, "y": 0.5, "at": 0.0 }, "mutation.disc2": map { "twist": 0.0, "rot": 0.0 }, "mutation.drift": map { "x.min": 0, "x.max": 0.03, "y.min": 0, "y.max": 0.01 }, "mutation.translate": map { "tx": 0.01, "ty": 0.01 }, "mutation.shear": map { "sx": 0.87, "sy": 0.87 }, "mutation.shear-x": map { "sx": 0.87 }, "mutation.shear-y": map { "sy": 0.87 }, "mutation.rotate": map { "angle": 90 }, "mutation.sinusoidal": map { "kx": 1, "ky": 1 }, "mutation.pillow": map { "depth": 0.5, "shrink": 1.0 }, "mutation.flowfield": map { "noise": perlin:noise2-vector(perlin:context()), "step-size": 0.05 }, "mutation.bipolar": map { "extent": 1.0 }, "mutation.elliptic": map { "scale": 1.0 }, "mutation.circular": map { "scale": 1.0 }, "mutation.parabolic": map { "scale": 1.0, "symmetric": false() }, "mutation.sphere": map { "radius": 1.0 } } }
Function: colophon
declare function colophon($parameters as map(xs:string,item()*)) as xs:string?
declare function colophon($parameters as map(xs:string,item()*)) as xs:string?
colophon()
Standard component colophon
Params
- parameters as map(xs:string,item()*): active parameters for component
Returns
- xs:string?
declare function this:colophon($parameters as map(xs:string,item()*)) as xs:string? { () }
Function: metadata
declare function metadata($canvas as map(xs:string,item()*),
$randomizers as map(xs:string,item()*),
$parameters as map(xs:string,item()*))
declare function metadata($canvas as map(xs:string,item()*), $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*))
metadata()
Standard component metadata
Params
- canvas as map(xs:string,item()*): canvas component is operating over
- randomizers as map(xs:string,item()*): active randomizers for component
- parameters as map(xs:string,item()*): active parameters for component
declare function this:metadata( $canvas as map(xs:string,item()*), $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) { () }
Function: randomizers
declare function randomizers($canvas as map(xs:string,item()*),
$parameters as map(xs:string,item()*)) as map(xs:string,item()*)
declare function randomizers($canvas as map(xs:string,item()*), $parameters as map(xs:string,item()*)) as map(xs:string,item()*)
Params
- canvas as map(xs:string,item()*)
- parameters as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:randomizers( $canvas as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { map { "mutation.n-composed": dist:zipf(1.7, 3), "mutation.mutations": dist:uniform-index-of($this:FOREGROUND-MUTATIONS), (: Function parameter randomizers :) "mutation.blob.high": dist:uniform(0.8, 1.2), "mutation.blob.low": dist:uniform(0.2, 0.7), "mutation.blob.waves": dist:uniform(2, 7)=>dist:cast("integer"), "mutation.PDJ.a": dist:uniform(-3.0, 3.0), "mutation.PDJ.b": dist:uniform(-3.0, 3.0), "mutation.PDJ.c": dist:uniform(-3.0, 3.0), "mutation.PDJ.d": dist:uniform(-3.0, 3.0), "mutation.fan2.x": dist:uniform(-1.0, 1.0), "mutation.fan2.y": dist:uniform(-1.0, 1.0), "mutation.rings2.val": dist:uniform(0.0, 2.0), "mutation.perspective.angle": dist:uniform(0.0, 1.0), (: radians :) "mutation.perspective.dist": dist:uniform(1.0, 3.0), "mutation.juliaN.power": dist:uniform(2, 7)=>dist:cast("integer"), "mutation.juliaN.dist": dist:constant(1.0), "mutation.juliaScope": dist:uniform(2, 7)=>dist:cast("integer"), "mutation.juliaScope.dist": dist:constant(1.0), "mutation.radialBlur.angle": dist:uniform(-1.0, 1.0), (: radians :) "mutation.pie.slices": dist:uniform(0, 10)=>dist:cast("integer"), "mutation.pie.rotation": dist:uniform(-2.0*math:pi(), 2.0*math:pi()), (: radians :) "mutation.pie.thickness": dist:uniform(0.0, 1.0), "mutation.ngon.power": dist:uniform(1.0, 4.0), "mutation.ngon.sides": dist:uniform(3, 13)=>dist:cast("integer"), "mutation.ngon.corners": dist:uniform(0.0, 3.0)=>dist:post-multiplier(1.5), (: should be ngon.circle value :) "mutation.ngon.circle": dist:uniform(0.0, 3.0), "mutation.curl.c1": dist:uniform(0.0, 1.0), "mutation.curl.c2": dist:uniform(0.0, 1.0), "mutation.rectangles.x": dist:uniform(0.0, 1.0), "mutation.rectangles.y": dist:uniform(0.0, 1.0), "mutation.supershape.holes": dist:constant(0.0), "mutation.supershape.m": dist:uniform(0, 6)=>dist:cast("integer"), "mutation.supershape.rnd": dist:uniform(0.0, 1.0), "mutation.supershape.n1": dist:uniform(0.0, 40.0), "mutation.supershape.n2": dist:uniform(0.0, 20.0), "mutation.supershape.n3": dist:uniform(0.0, 20.0), (: really = n2 :) "mutation.flower.holes": dist:uniform(0.0, 1.0), "mutation.flower.petals": dist:uniform(0.0, 4.0), "mutation.conic.holes": dist:uniform(0.0, 1.0), "mutation.conic.eccentricity": dist:uniform(0.0, 1.0), "mutation.parabola.height": dist:uniform(0.5, 1.5), "mutation.parabola.width": dist:uniform(0.5, 1.5), "mutation.bent2.at": dist:uniform(-1.0, 1.0), "mutation.bent2.x": dist:uniform(-1.5, 1.5), "mutation.bent2.y": dist:uniform(-1.5, 1.5), "mutation.disc2.twist": dist:uniform(-0.5, 0.5), "mutation.disc2.rot": dist:uniform(-0.5, 0.5), "mutation.drift.x.min": dist:constant(0.0), "mutation.drift.x.max": dist:uniform(0.01, 0.05), "mutation.drift.y.min": dist:constant(0.0), "mutation.drift.y.max": dist:uniform(0.01, 0.03), "mutation.rotate.angle": dist:normal(90, 20)=>dist:cast("integer"), (: degrees :) "mutation.sinusoidal.kx": dist:poisson(4.5)=>dist:min(0.5), "mutation.sinusoidal.ky": dist:poisson(4.5)=>dist:min(0.5), "mutation.translate.tx": dist:normal(0.0, 0.3), "mutation.translate.ty": dist:normal(0.0, 0.3), "mutation.shear.sx": dist:uniform(0.0, 1.5), "mutation.shear.sy": dist:uniform(0.0, 1.5), "mutation.shear-x.sx": dist:uniform(0.0, 1.5), "mutation.shear-y.sy": dist:uniform(0.0, 1.5), "mutation.pillow.depth": dist:uniform(0.25, 1.0), "mutation.pillow.shrink": dist:uniform(1.0, 3.0), "mutation.flowfield.step-size": dist:normal(0.05, 0.001)=>dist:min(0)=>dist:max(0.2), "mutation.bipolar.extent": dist:uniform(1.0, 4.0), "mutation.elliptic.scale": dist:uniform(0.5, 2.5), "mutation.circular.scale": dist:uniform(0.5, 3.5), "mutation.parabolic.scale": dist:uniform(0.5, 2.0), "mutation.parabolic.symmetric": dist:flip(50), "mutation.sphere.radius": dist:normal(1.0, 0.1)=>dist:min(0.5)=>dist:max(1.5) } }
Function: scaled
declare function scaled($f as item(),
$canvas as map(xs:string,item()*)) as map(*)
declare function scaled($f as item(), $canvas as map(xs:string,item()*)) as map(*)
scaled()
Map a point on the canvas to a point in the bi-unit square, apply the
function, and map it back out. (The functions generally only work
properly on bi-unit square.)
Params
- f as item()
- canvas as map(xs:string,item()*)
Returns
- map(*)
declare function this:scaled( $f as item(), $canvas as map(xs:string,item()*) ) as map(*) { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $width := box:width($canvas) let $height := box:height($canvas) let $fn := ann:function($f) return if (ann:is-mutation-point($f)) then ( ann:f("mut:scaled", function($point as map(xs:string,item()*)) as map(xs:string,item()*) { let $p := $fn( point:point( 2 * (point:px($point) - $width div 2) div $width, 2 * (point:py($point) - $height div 2) div $height ) ) return ( point:point( $width * (point:px($p) + 1) div 2, $height * (point:py($p) + 1) div 2 )=>point:snap() ) }, $f ) ) else ( ann:f("mut:scaled", function($point as xs:double*) as xs:double* { let $p := $fn( ( 2 * (v:px($point) - $width div 2) div $width, 2 * (v:py($point) - $height div 2) div $height ) ) return ( ( $width * (v:px($p) + 1) div 2, $height * (v:py($p) + 1) div 2 )=>v:snap() ) }, $f ) ) }
Function: as-point
declare function as-point($f as item()) as item()
declare function as-point($f as item()) as item()
as-point()
Pass through to make a point-as-point function, converting from vector
Params
- f as item()
Returns
- item()
declare function this:as-point( $f as item() ) as item() { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $fn := ann:function($f) return ( if (ann:is-mutation-vector($f)) then ( ann:f(util:function-name($f), function($point as map(xs:string,item()*)) as map(xs:string,item()*) { point:vector($fn(point:pcoordinates($point))) } ) ) else ( $f ) ) }
Function: as-vector
declare function as-vector($f as item()) as item()
declare function as-vector($f as item()) as item()
as-vector()
Pass through to make a vector-to-vector function, converting from point-to-point
Params
- f as item()
Returns
- item()
declare function this:as-vector( $f as item() ) as item() { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $fn := ann:function($f) return ( if (ann:is-mutation-point($f)) then ( ann:f(util:function-name($f), function($point as xs:double*) as xs:double* { point:pcoordinates($fn(point:vector($point))) } ) ) else ( $f ) ) }
Function: mutation
declare function mutation($name as xs:string,
$parameters as map(xs:string,item()*)) as map(*)
declare function mutation($name as xs:string, $parameters as map(xs:string,item()*)) as map(*)
mutation()
Get the function definition by name, fetch its corresponding parameter
bundle from the parameters, and return the resulting function.
The function will be one of the functions in this namespace.
Params
- name as xs:string
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:mutation( $name as xs:string, $parameters as map(xs:string,item()*) ) as map(*) { let $as-point := ends-with($name,"+point") let $name := if ($as-point) then substring-before($name,"+point") else $name let $f := function-lookup(QName($this:URI, "this:"||$name), 2) let $parms := ($parameters("mutation."||$name), map {})[1] let $weight := if (exists($parameters("mutation.weights"))) then ($parameters("mutation.weights")($name), 1.0)[1] else 1.0 return ( if ($as-point) then $f($weight, $parms)=>this:as-point() else $f($weight, $parms) ) }
Function: random-mutation
declare function random-mutation($name as xs:string,
$randomizers as map(xs:string,item()*),
$parameters as map(xs:string,item()*)) as map(xs:string,item()*)
declare function random-mutation($name as xs:string, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*)) as map(xs:string,item()*)
mutation()
Get the function definition by name, and construct the corresponding
parameter bundle by overriding default parameters with randomized values.
Return a wrapper of the resulting function with the dynamic values.
The function will be one of the functions in this namespace.
Params
- name as xs:string
- randomizers as map(xs:string,item()*)
- parameters as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:random-mutation( $name as xs:string, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { let $as-point := ends-with($name,"+point") let $name := if ($as-point) then substring-before($name,"+point") else $name let $f := function-lookup(QName($this:URI, "this:"||$name), 2) let $parms := util:merge-into(( ($parameters("mutation."||$name), map{})[1], for $key in map:keys($randomizers)[starts-with(., "mutation."||$name||".")] return ( map { substring-after($key, "mutation."||$name||"."): core:randomize($key, $randomizers) } ) )) let $weight := if (exists($parameters("mutation.weights"))) then ($parameters("mutation.weights")($name), 1.0)[1] else 1.0 return ( if ($as-point) then wrapper:wrapper($f($weight, $parms)=>this:as-point(), $parms) else wrapper:wrapper($f($weight, $parms), $parms) ) }
Function: mutation
declare function mutation($name as xs:string,
$parameters as map(xs:string,item()*),
$weight as xs:double) as map(*)
declare function mutation($name as xs:string, $parameters as map(xs:string,item()*), $weight as xs:double) as map(*)
mutation()
Get the function definition by name, fetch its corresponding parameter
bundle from the parameters, and return the resulting function.
The function will be one of the functions in this namespace.
Pass in the given weight.
Params
- name as xs:string
- parameters as map(xs:string,item()*)
- weight as xs:double
Returns
- map(*)
declare function this:mutation( $name as xs:string, $parameters as map(xs:string,item()*), $weight as xs:double ) as map(*) { let $as-point := ends-with($name,"+point") let $name := if ($as-point) then substring-before($name,"+point") else $name let $f := function-lookup(QName($this:URI, "this:"||$name), 2) let $parms := ($parameters("mutation."||$name), map {})[1] return ( if ($as-point) then $f($weight, $parms)=>this:as-point() else $f($weight, $parms) ) }
Function: compose
declare function compose($f as item(),
$g as item()) as map(*)
declare function compose($f as item(), $g as item()) as map(*)
compose()
Apply f then apply g
Params
- f as item()
- g as item()
Returns
- map(*)
declare function this:compose( $f as item(), $g as item() ) as map(*) { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), if (not(ann:is-mutation($g))) then errors:error("ML-BADARGS", ("g", $g)) else (), if (ann:is-mutation-vector($f) and ann:is-mutation-vector($g)) then ( let $fn := $f=>ann:function() let $gn := $g=>ann:function() return ( ann:f("mut.compose", function($point as xs:double*) as xs:double* { $fn($point)=>$gn() }, ($f, $g) ) ) ) else ( let $f := this:as-point($f) let $g := this:as-point($g) let $fn := $f=>ann:function() let $gn := $g=>ann:function() return ( ann:f("mut.compose", function($point as map(xs:string,item()*)) as map(xs:string,item()*) { $fn($point)=>$gn() }, ($f, $g) ) ) ) }
Function: compose
declare function compose($fs as item()*) as map(*)
declare function compose($fs as item()*) as map(*)
compose()
Apply functions in order
Params
- fs as item()*
Returns
- map(*)
declare function this:compose( $fs as item()* ) as map(*) { if (some $f in $fs satisfies not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("fs", $fs)) else (), if (every $f in $fs satisfies ann:is-mutation-vector($f)) then ( let $fns := $fs!ann:function(.) return ( ann:f("mut:compose", function($point as xs:double*) as xs:double* { fold-left($fns, $point, function($point as xs:double*, $fn as function(*)) as xs:double* { $fn($point) } ) }, $fs ) ) ) else ( let $fs := $fs!this:as-point(.) let $fns := $fs!ann:function(.) return ( ann:f("mut:compose", function($point as map(xs:string,item()*)) as map(xs:string,item()*) { fold-left($fns, $point, function($point as map(xs:string,item()*), $fn as function(*)) as map(xs:string,item()*) { $fn($point) } ) }, $fs ) ) ) }
Function: mutations
declare function mutations($mutations as xs:string,
$canvas as map(xs:string,item()*)?,
$parameters as map(xs:string,item()*)) as map(*)
declare function mutations($mutations as xs:string, $canvas as map(xs:string,item()*)?, $parameters as map(xs:string,item()*)) as map(*)
mutations()
Return the composite mutation function corresponding to a compound name.
e.g. eyefish·swirl = compose(eyefish(), swirl()) with appropriate parameters
If canvas is present, scale to/from the canvas.
Params
- mutations as xs:string
- canvas as map(xs:string,item()*)?
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:mutations( $mutations as xs:string, $canvas as map(xs:string,item()*)?, $parameters as map(xs:string,item()*) ) as map(*) { let $mutation-kinds := tokenize($mutations, "·")[. ne ''] return ( if ($mutations="none") then ( this:none(0, map{}) ) else if ($mutations="none+point") then ( this:none(0, map{})=>this:as-point() ) else if (empty($canvas)) then ( if (count($mutation-kinds)=1) then ( this:mutation($mutation-kinds, $parameters) ) else ( this:compose( for $fname in $mutation-kinds return ( this:mutation($fname, $parameters) ) ) ) ) else ( this:scaled( if (count($mutation-kinds)=1) then ( this:mutation($mutation-kinds, $parameters) ) else ( this:compose( for $fname in $mutation-kinds return ( this:mutation($fname, $parameters) ) ) ) , $canvas ) ) ) }
Function: mutations
declare function mutations($mutations as xs:string,
$canvas as map(xs:string,item()*)?,
$randomizers as map(xs:string,item()*),
$parameters as map(xs:string,item()*)) as map(xs:string,item()*)
declare function mutations($mutations as xs:string, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*)) as map(xs:string,item()*)
mutations()
Return the composite mutation function corresponding to a compound name
in a wrapper
e.g. eyefish·swirl = compose(eyefish(), swirl()) with appropriate parameters
If canvas is present, scale to/from the canvas.
If $mutations="random" pick a random mutation with random parameters
If $mutations starts with "random", randomize the rest of the mutation names
Params
- mutations as xs:string
- canvas as map(xs:string,item()*)?
- randomizers as map(xs:string,item()*)
- parameters as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:mutations( $mutations as xs:string, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { if ($mutations="random") then ( this:random-random-mutations(false(), $canvas, $randomizers, $parameters) ) else if ($mutations="random+point") then ( this:random-random-mutations(true(), $canvas, $randomizers, $parameters) ) else if (starts-with($mutations, "random·")) then ( this:random-mutations(substring-after($mutations, "random·"), $canvas, $randomizers, $parameters) ) else ( wrapper:wrapper( this:mutations($mutations, $canvas, $parameters), map {} ) ) }
Function: random-mutations
declare function random-mutations($mutations as xs:string,
$canvas as map(xs:string,item()*)?,
$randomizers as map(xs:string,item()*),
$parameters as map(xs:string,item()*)) as map(xs:string,item()*)
declare function random-mutations($mutations as xs:string, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*)) as map(xs:string,item()*)
random-mutations()
Return the composite mutation function corresponding to a compound name.
e.g. eyefish·swirl = compose(eyefish(), swirl()) with appropriate randomized
parameters
If canvas is present, scale to/from the canvas.
Returns a wrapper of the function with the dynamic values
Params
- mutations as xs:string
- canvas as map(xs:string,item()*)?
- randomizers as map(xs:string,item()*)
- parameters as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:random-mutations( $mutations as xs:string, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { let $mutation-kinds := tokenize($mutations, "·")[. ne ''] return ( if ($mutations="none") then ( wrapper:wrapper( this:none(0, map{}), map {} ) ) else if ($mutations="none+point") then ( wrapper:wrapper( this:none(0, map{})=>this:as-point(), map {} ) ) else if (empty($canvas)) then ( if (count($mutation-kinds)=1) then ( this:random-mutation($mutation-kinds, $randomizers, $parameters) ) else ( let $wrappers := for $fname in $mutation-kinds return ( this:random-mutation($fname, $randomizers, $parameters) ) return ( wrapper:wrapper( this:compose(for $wrapper in $wrappers return wrapper:body($wrapper)), util:merge-into(( for $fname at $i in $mutation-kinds return ( map { "mutation."||$fname: wrapper:dynamics($wrappers[$i]) } ) )) ) ) ) ) else ( let $wrappers := for $fname in $mutation-kinds return ( this:random-mutation($fname, $randomizers, $parameters) ) return ( wrapper:wrapper( this:scaled( if (count($mutation-kinds)=1) then ( wrapper:body($wrappers) ) else ( this:compose(for $wrapper in $wrappers return wrapper:body($wrapper)) ), $canvas ), util:merge-into(( for $fname at $i in $mutation-kinds return ( map { "mutation."||$fname: wrapper:dynamics($wrappers[$i]) } ) )) ) ) ) ) }
Function: random-random-mutations
declare function random-random-mutations($as-point as xs:boolean,
$canvas as map(xs:string,item()*)?,
$randomizers as map(xs:string,item()*),
$parameters as map(xs:string,item()*)) as map(xs:string,item()*)
declare function random-random-mutations($as-point as xs:boolean, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*)) as map(xs:string,item()*)
Params
- as-point as xs:boolean
- canvas as map(xs:string,item()*)?
- randomizers as map(xs:string,item()*)
- parameters as map(xs:string,item()*)
Returns
- map(xs:string,item()*)
declare function this:random-random-mutations( $as-point as xs:boolean, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { let $n-composed as xs:integer := core:randomize("mutation.n-composed", $randomizers) let $name as xs:string := (if ($n-composed = 0) then "none" else ( string-join( distinct-values( core:randomize($n-composed, (), "mutation.mutations", $randomizers) ), "·" ) ))|| (if ($as-point) then "+point" else "") return ( this:random-mutations($name, $canvas, $randomizers, $parameters) ) }
Function: trace
declare function trace($f as item()) as map(*)
declare function trace($f as item()) as map(*)
trace()
Tracing pass-through for mutation function
Params
- f as item()
Returns
- map(*)
declare function this:trace( $f as item() ) as map(*) { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $fn := ann:function($f) return ( if (ann:is-mutation-point($f)) then ( ann:f(util:function-name($f), function ($point as map(xs:string,item()*)) as map(xs:string,item()*) { $fn($point)=>trace(util:quote($f)||"("||point:quote($point)||")") } ) ) else ( ann:f(util:function-name($f), function ($point as xs:double*) as xs:double* { $fn($point)=>trace(util:quote($f)||"("||v:quote($point)||")") } ) ) ) }
Function: none
declare function none($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function none($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:none( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("no-op", function ($pt as xs:double*) as xs:double* { $pt } ) }
Function: div2
declare function div2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function div2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:div2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:div2", function($pt as xs:double*) as xs:double* { ($weight * v:px($pt) div 2, $weight * v:py($pt) div 2) }, ($weight, $parameters) ) }
Function: bump_x_div2
declare function bump_x_div2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function bump_x_div2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:bump_x_div2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bump_x_div2", function($pt as xs:double*) as xs:double* { ($weight * (v:px($pt)+1) div 2, $weight * v:py($pt) div 2) }, ($weight, $parameters) ) }
Function: bump_y_div2
declare function bump_y_div2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function bump_y_div2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:bump_y_div2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bump_y_div2", function($pt as xs:double*) as xs:double* { ($weight * v:px($pt) div 2, $weight * (v:py($pt)+1) div 2) }, ($weight, $parameters) ) }
Function: translate
declare function translate($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function translate($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:translate( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $tx as xs:numeric := $parameters("tx") let $ty as xs:numeric := $parameters("ty") return ( ann:f("mut:translate", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:translation2($tx, $ty))=>v:times($weight) }, ($weight, $parameters) ) ) }
Function: shear
declare function shear($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function shear($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:shear( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $sx as xs:numeric := $parameters("sx") let $sy as xs:numeric := $parameters("sy") return ( ann:f("mut:shear", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:shearing2($sx, $sy))=>v:times($weight) }, ($weight, $parameters) ) ) }
Function: shear-x
declare function shear-x($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function shear-x($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:shear-x( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $sx as xs:numeric := $parameters("sx") return ( ann:f("mut:shear-x", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:shearing2($sx, 0))=>v:times($weight) }, ($weight, $parameters) ) ) }
Function: shear-y
declare function shear-y($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function shear-y($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:shear-y( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $sy as xs:numeric := $parameters("sy") return ( ann:f("mut:shear-y", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:shearing2(0, $sy))=>v:times($weight) }, ($weight, $parameters) ) ) }
Function: reflect
declare function reflect($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function reflect($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:reflect( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:reflect", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:reflection2($point:ORIGIN))=>v:times($weight) }, ($weight, $parameters) ) }
Function: identity
declare function identity($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function identity($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:identity( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:identity", function($pt as xs:double*) as xs:double* { $pt=>v:times($weight) }, ($weight, $parameters) ) }
Function: rotate
declare function rotate($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function rotate($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:rotate( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $angle as xs:numeric := $parameters("angle") return ( ann:f("mut:rotate", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:rotation2($angle))=>v:times($weight) }, ($weight, $parameters) ) ) }
Function: sinusoidal
declare function sinusoidal($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function sinusoidal($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:sinusoidal( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $kx as xs:numeric := $parameters("kx") let $ky as xs:numeric := $parameters("ky") return ( ann:f("mut:sinusoidal", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ($weight * math:sin($kx * $x), $weight * math:sin($ky * $y)) }, ($weight, $parameters) ) ) }
Function: spherical
declare function spherical($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function spherical($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:spherical( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:spherical", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y return if ($r2=0) then ($weight * $x div ($r2+1), $weight * $y div ($r2+1)) else ($weight * $x div $r2, $weight * $y div $r2) }, ($weight, $parameters) ) }
Function: swirl
declare function swirl($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function swirl($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:swirl( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:swirl", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y return ( $weight * ($x*math:sin($r2) - $y*math:cos($r2)), $weight * ($x*math:cos($r2) + $y*math:sin($r2)) ) }, ($weight, $parameters) ) }
Function: horseshoe
declare function horseshoe($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function horseshoe($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:horseshoe( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:horseshoe", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return if ($r=0) then ($weight*($x - $y)*($x + $y) div ($r+1), $weight*2*$x*$y div ($r+1)) else ($weight*($x - $y)*($x + $y) div $r, $weight*2*$x*$y div $r) }, ($weight, $parameters) ) }
Function: polar
declare function polar($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function polar($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:polar( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:polar", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ($weight * $θ div math:pi(), $weight * ($r - 1)) }, ($weight, $parameters) ) }
Function: hankerchief
declare function hankerchief($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function hankerchief($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:hankerchief( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:hankerchief", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ($weight * $r*math:sin($θ + $r), $weight * $r*math:cos($θ - $r)) }, ($weight, $parameters) ) }
Function: heart
declare function heart($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function heart($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:heart( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:heart", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ($weight * $r*math:sin($θ*$r), $weight * $r*-math:cos($θ*$r)) }, ($weight, $parameters) ) }
Function: disc
declare function disc($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function disc($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:disc( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:disc", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ( $weight * ($θ div math:pi()) * math:sin($θ*$r), $weight * ($θ div math:pi()) * math:cos($θ*$r) ) }, ($weight, $parameters) ) }
Function: spiral
declare function spiral($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function spiral($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:spiral( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:spiral", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return if ($r = 0) then ( $weight * (math:cos($θ) + math:sin($r)) div ($r+1), $weight * (math:sin($θ) - math:cos($r)) div ($r+1) ) else ( (math:cos($θ) + math:sin($r)) div $r, (math:sin($θ) - math:cos($r)) div $r ) }, ($weight, $parameters) ) }
Function: hyperbolic
declare function hyperbolic($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function hyperbolic($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:hyperbolic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:hyperbolic", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return if ($r = 0) then ($weight * math:sin($θ) div ($r + 1), $weight * $r * math:cos($θ)) else ($weight * math:sin($θ) div $r, $weight * $r * math:cos($θ)) }, ($weight, $parameters) ) }
Function: diamond
declare function diamond($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function diamond($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:diamond( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:diamond", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ( $weight * math:sin($θ) * math:cos($r), $weight * math:cos($θ) * math:sin($r) ) }, ($weight, $parameters) ) }
Function: ex
declare function ex($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function ex($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:ex( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:ex", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $p0 := math:sin($θ + $r) let $p1 := math:cos($θ - $r) return ( $weight * $r*($p0*$p0*$p0 + $p1*$p1*$p1), $weight * $r*($p0*$p0*$p0 - $p1*$p1*$p1) ) }, ($weight, $parameters) ) }
Function: julia
declare function julia($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function julia($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:julia( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:julia", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $root_r := math:sqrt(math:sqrt($x*$x + $y*$y)) let $θ := math:atan2($x,$y) let $Ω := if (rand:flip(50)) then 0 else math:pi() return ( $weight * $root_r * math:cos($θ div 2 + $Ω), $weight * $root_r * math:sin($θ div 2 + $Ω) ) }, ($weight, $parameters) ) }
Function: bent
declare function bent($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function bent($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:bent( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bent", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( if ($x ge 0 and $y ge 0) then $pt else if ($x lt 0 and $y ge 0) then ($weight * 2*$x, $weight * $y) else if ($x ge 0 and $y lt 0) then ($weight * $x, $weight * $y div 2) else (: x lt 0 and y lt 0 :) ($weight * 2*$x, $weight * $y div 2) ) }, ($weight, $parameters) ) }
Function: fisheye
declare function fisheye($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function fisheye($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:fisheye( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:fisheye", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return ( $weight * (2 div ($r + 1)) * $y, $weight * (2 div ($r + 1)) * $x ) }, ($weight, $parameters) ) }
Function: exponential
declare function exponential($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function exponential($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:exponential( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:exponential", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * math:exp($x - 1)*math:cos(math:pi()*$y), $weight * math:exp($x - 1)*math:sin(math:pi()*$y) ) }, ($weight, $parameters) ) }
Function: power
declare function power($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function power($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:power( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:power", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($x,$y) let $r := math:sqrt($x*$x + $y*$y) let $rexp := math:pow($r, math:sin($θ)) return ($weight * $rexp*math:cos($θ), $weight * $rexp*math:sin($θ)) }, ($weight, $parameters) ) }
Function: cosine
declare function cosine($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function cosine($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:cosine( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:cosine", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * math:cos(math:pi()*$x)*util:cosh($y), $weight * math:sin(math:pi()*$x)*util:sinh($y) ) }, ($weight, $parameters) ) }
Function: blob
declare function blob($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function blob($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:blob( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("high") let $p2 as xs:numeric := $parameters("low") let $p3 as xs:numeric := $parameters("waves") return ( ann:f("mut:blob", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $factor := $r*($p2 + (($p1 - $p2) div 2)*(math:sin($p3*$θ)+1)) return ( $weight * $factor*math:cos($θ), $weight * $factor*math:sin($θ) ) }, ($weight, $parameters) ) ) }
Function: PDJ
declare function PDJ($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function PDJ($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:PDJ( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("a") let $p2 as xs:numeric := $parameters("b") let $p3 as xs:numeric := $parameters("c") let $p4 as xs:numeric := $parameters("d") return ( ann:f("mut:PDJ", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * (math:sin($p1*$y) - math:cos($p2*$x)), $weight * (math:sin($p3*$x) - math:cos($p4*$y)) ) }, ($weight, $parameters) ) ) }
Function: fan2
declare function fan2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function fan2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:fan2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $fan2_x := $parameters("x") let $p1 as xs:numeric := math:pi()*($fan2_x)*($fan2_x) let $p2 as xs:numeric := $parameters("y") return ( ann:f("mut:fan2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $t := $θ + $p2 - $p1*util:trunc(2*$θ*$p2 div $p1) return if ($t gt $p1 div 2) then ( ( $weight * $r * math:sin($θ - $p1 div 2), $weight * $r * math:cos($θ - $p1 div 2) ) ) else ( ( $weight * $r * math:sin($θ + $p1 div 2), $weight * $r * math:cos($θ + $p1 div 2) ) ) }, ($weight, $parameters) ) ) }
Function: rings2
declare function rings2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function rings2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:rings2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $rings2_val := $parameters("val") let $p as xs:numeric := $rings2_val*$rings2_val return ( ann:f("mut:rings2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $t := $r - 2*util:trunc(($r + $p) div (2*$p)) + $r*(1-$p) return ($weight * $t * math:sin($θ), $weight * $t * math:cos($θ)) }, ($weight, $parameters) ) ) }
Function: eyefish
declare function eyefish($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function eyefish($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:eyefish( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:eyefish", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $factor := 2 div ($r + 1) return ($weight * $factor * $x, $weight * $factor * $y) }, ($weight, $parameters) ) }
Function: bubble
declare function bubble($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function bubble($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:bubble( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bubble", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y let $factor := 4 div ($r2 + 4) return ($weight * $factor * $x, $weight * $factor * $y) }, ($weight, $parameters) ) }
Function: cylinder
declare function cylinder($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function cylinder($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:cylinder( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:cylinder", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ($weight * math:sin($x), $weight * $y) }, ($weight, $parameters) ) }
Function: perspective
declare function perspective($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function perspective($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:perspective( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("angle") let $p2 as xs:numeric := $parameters("dist") return ( ann:f("mut:perspective", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y let $factor := $p2 div ($p2 - $y*math:sin($p1)) return ( $weight * $factor * $x, $weight * $factor * $y * math:cos($p1) ) }, ($weight, $parameters) ) ) }
Function: noise
declare function noise($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function noise($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:noise( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:noise", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ( $weight * $Ψ1 * $x * math:cos(2*math:pi()*$Ψ2), $weight * $Ψ1 * $y * math:sin(2*math:pi()*$Ψ2) ) }, ($weight, $parameters) ) }
Function: juliaN
declare function juliaN($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function juliaN($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:juliaN( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("power") let $p2 as xs:numeric := $parameters("dist") return ( ann:f("mut:juliaN", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $p3 as xs:numeric := util:trunc(abs($p1)*$Ψ) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $t := ($φ + 2*math:pi()*$p3) div $p1 let $factor := math:pow($r, $p2 div $p1) return ( $weight * $factor * math:cos($t), $weight * $factor * math:sin($t) ) }, ($weight, $parameters) ) ) }
Function: juliaScope
declare function juliaScope($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function juliaScope($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:juliaScope( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("power") let $p2 as xs:numeric := $parameters("dist") return ( ann:f("mut:juliaScope", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $p3 as xs:numeric := util:trunc(abs($p1)*$Ψ) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $Λ := if (rand:flip(50)) then 0 else 1 let $t := ($Λ*$φ + 2*math:pi()*$p3) div $p1 let $factor := math:pow($r, $p2 div $p1) return ( $weight * $factor * math:cos($t), $weight * $factor * math:sin($t) ) }, ($weight, $parameters) ) ) }
Function: blur
declare function blur($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function blur($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:blur( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:blur", function($pt as xs:double*) as xs:double* { let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ( $weight * $Ψ1 * math:cos(2*math:pi()*$Ψ2), $weight * $Ψ1 * math:sin(2*math:pi()*$Ψ2) ) }, ($weight, $parameters) ) }
Function: gaussian
declare function gaussian($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function gaussian($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:gaussian( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:gaussian", function($pt as xs:double*) as xs:double* { (: Q&D approximation for Gaussian distribution :) let $Ψ := for $i in 1 to 5 return rand:uniform(0.0, 1.0) let $factor := sum($Ψ[position()<=4]) - 2 return ( $weight * $factor * math:cos(2*math:pi()*$Ψ[5]), $weight * $factor * math:sin(2*math:pi()*$Ψ[5]) ) }, ($weight, $parameters) ) }
Function: radialBlur
declare function radialBlur($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function radialBlur($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:radialBlur( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("angle") * (math:pi() div 2) let $ν36 as xs:numeric := $weight return ( ann:f("mut:radialBlur", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $Ψ := for $i in 1 to 4 return rand:uniform(0.0, 1.0) let $t1 := $ν36 * (sum($Ψ) - 2) let $t2 := $φ + $t1*math:sin($p1) let $t3 := $t1 * math:cos($p1) - 1 return ( $weight * ($r*math:cos($t2) + $t3*$x) div $ν36, $weight * ($r*math:sin($t2) + $t3*$y) div $ν36 ) }, ($weight, $parameters) ) ) }
Function: pie
declare function pie($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function pie($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:pie( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("slices") let $p2 as xs:numeric := $parameters("rotation") let $p3 as xs:numeric := $parameters("thickness") return ( ann:f("mut:pie", function($pt as xs:double*) as xs:double* { let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) let $Ψ3 := rand:uniform(0.0, 1.0) let $t1 := util:trunc($Ψ1*$p1 + 0.5) let $t2 := $p2 + (2*math:pi() div $p1)*($t1 + $Ψ2*$p3) return ($weight * $Ψ3*math:cos($t2), $weight * $Ψ3*math:sin($t2)) }, ($weight, $parameters) ) ) }
Function: ngon
declare function ngon($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function ngon($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:ngon( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("power") let $p2 as xs:numeric := $parameters("sides") let $p3 as xs:numeric := $parameters("corners") let $p4 as xs:numeric := $parameters("circle") return ( ann:f("mut:ngon", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $t3 := $φ - $p2*floor($φ div $p2) let $t4 := if ($t3 gt $p2 div 2) then $t3 else $t3 - $p2 let $k := ($p3 * ((1 div math:cos($t4)) - 1) + $p4) div math:pow($r, $p1) return ($weight * $k*$x, $weight * $k*$y) }, ($weight, $parameters) ) ) }
Function: curl
declare function curl($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function curl($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:curl( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("c1") let $p2 as xs:numeric := $parameters("c2") return ( ann:f("mut:curl", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $t1 := 1 + $p1*$x + $p2*($x*$x - $y*$y) let $t2 := $p1*$y + 2*$p2*$x*$y let $inv-factor := $t1*$t1 + $t2*$t2 let $factor := if ($inv-factor = 0) then 1 div ($inv-factor + 1) else 1 div $inv-factor return ( $weight * $factor*($x*$t1 + $y*$t2), $weight * $factor*($y*$t1 - $x*$t2) ) }, ($weight, $parameters) ) ) }
Function: rectangles
declare function rectangles($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function rectangles($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:rectangles( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("x") let $p2 as xs:numeric := $parameters("y") return ( ann:f("mut:rectangles", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * ((2*floor($x div $p1) + 1)*$p1 - $x), $weight * ((2*floor($y div $p2) + 1)*$p2 - $y) ) }, ($weight, $parameters) ) ) }
Function: supershape
declare function supershape($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function supershape($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:supershape( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $holes as xs:numeric := $parameters("holes") let $m as xs:numeric := $parameters("m") let $n1 as xs:numeric := $parameters("n1") let $n2 as xs:numeric := $parameters("n1") let $n3 as xs:numeric := $parameters("n1") let $rnd as xs:numeric := $parameters("rnd") let $m_over_4 := $m div 4.0 let $neg1_over_n1 := -1.0 div $n1 return ( ann:f("mut:supershape", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($y,$x) let $α := $m_over_4 * $θ + math:pi() div 4.0 let $t1 := math:pow(abs(math:sin($α)), $n2) let $t2 := math:pow(abs(math:cos($α)), $n3) let $Ψ1 := rand:uniform(0.0, 1.0) let $factor := ( ($rnd*$Ψ1 + (1.0 - $rnd)*$r - $holes) * math:pow($t1 + $t2, $neg1_over_n1) ) div $r return ( ($weight * $factor * $x, $weight * $factor * $y) ) }, ($weight, $parameters) ) ) }
Function: flower
declare function flower($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function flower($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:flower( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $holes as xs:numeric := $parameters("holes") let $petals as xs:numeric := $parameters("petals") return ( ann:f("mut:flower", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($y,$x) let $Ψ1 := rand:uniform(0.0, 1.0) let $r := $weight * ($Ψ1 - $holes) * math:cos($petals * $θ) return ( ($r * math:cos($θ), $r * math:sin($θ)) ) }, ($weight, $parameters) ) ) }
Function: conic
declare function conic($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function conic($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:conic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $holes as xs:numeric := $parameters("holes") let $eccentricity as xs:numeric := $parameters("eccentricity") return ( ann:f("mut:conic", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($y,$x) let $Ψ1 := rand:uniform(0.0, 1.0) let $r := $weight * ($Ψ1 - $holes) * $eccentricity div (1 + $eccentricity * math:cos($θ)) return ( ($r * math:cos($θ), $r * math:sin($θ)) ) }, ($weight, $parameters) ) ) }
Function: parabola
declare function parabola($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function parabola($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:parabola( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $width as xs:numeric := $parameters("width") let $height as xs:numeric := $parameters("height") return ( ann:f("mut:parabola", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($y,$x) let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ( ( $weight * $height * math:sin($r) * math:sin($r) * $Ψ1, $weight * $width * math:cos($r) * $Ψ2 ) ) }, ($weight, $parameters) ) ) }
Function: bent2
declare function bent2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function bent2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:bent2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $at as xs:numeric := $parameters("at") let $bendx as xs:numeric := $parameters("x") let $bendy as xs:numeric := $parameters("y") return ( ann:f("mut:bent2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $x := if ($x < $at) then $x * $bendx else $x let $y := if ($y < $at) then $y * $bendy else $y return ( ($weight * $x, $weight * $y) ) }, ($weight, $parameters) ) ) }
Function: arch
declare function arch($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function arch($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:arch( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν41 as xs:numeric := $weight return ( ann:f("mut:arch", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $sin := math:sin($Ψ*math:pi()*$ν41) return ( $weight * $sin, $weight * $sin*$sin div math:cos($Ψ*math:pi()*$ν41) ) }, ($weight, $parameters) ) ) }
Function: tangent
declare function tangent($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function tangent($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:tangent( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:tangent", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return if (math:cos($y) = 0) then ($weight, $weight * math:tan($y)) else ($weight * math:sin($x) div math:cos($y), $weight * math:tan($y)) }, ($weight, $parameters) ) }
Function: square
declare function square($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function square($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:square( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:square", function($pt as xs:double*) as xs:double* { let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ($weight * ($Ψ1 - 0.5), $weight * ($Ψ2 - 0.5)) }, ($weight, $parameters) ) }
Function: rays
declare function rays($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function rays($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:rays( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν44 as xs:numeric := $weight return ( ann:f("mut:rays", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y + 1.0E-7 let $factor := math:tan($Ψ*math:pi()*$ν44) div $r2 return ( $weight * $factor*math:cos($x), $weight * $factor*math:sin($y) ) }, ($weight, $parameters) ) ) }
Function: blade
declare function blade($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function blade($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:blade( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν45 as xs:numeric := $weight return ( ann:f("mut:blade", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return ( $weight * ($x*(math:cos($Ψ*$r*$ν45) + math:sin($Ψ*$r*$ν45))), $weight * ($x*(math:cos($Ψ*$r*$ν45) - math:sin($Ψ*$r*$ν45))) ) }, ($weight, $parameters) ) ) }
Function: secant
declare function secant($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function secant($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:secant( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν46 as xs:numeric := $weight return ( ann:f("mut:secant", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return if (math:cos($r*$ν46)=0) then ( $weight * $x, $weight * (1 + 1.0 div math:cos($r*$ν46)) ) else ( $weight * $x, $weight * (-1 + 1.0 div math:cos($r*$ν46)) ) }, ($weight, $parameters) ) ) }
Function: twintrian
declare function twintrian($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function twintrian($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:twintrian( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν47 as xs:numeric := $weight return ( ann:f("mut:twintrian", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $t := math:log10(math:sin($Ψ*$r*$ν47)*math:sin($Ψ*$r*$ν47)) + math:cos($Ψ*$r*$ν47) return ( $weight * $x * $t, $weight * $x * ($t - math:pi()*math:sin($Ψ*$r*$ν47)) ) }, ($weight, $parameters) ) ) }
Function: cross
declare function cross($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function cross($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:cross( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:cross", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $d := $x*$x - $y*$y let $factor := math:sqrt(1.0 div ($d*$d + 1.0E-7)) return ($weight * $factor * $x, $weight * $factor * $y) }, ($weight, $parameters) ) }
Function: disc2
declare function disc2($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function disc2($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:disc2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $twist as xs:numeric := $parameters("twist") let $rot as xs:numeric := $parameters("rot") let $pirot := $rot * math:pi() let $sintwist := math:sin($twist) let $costwist := math:cos($twist) let $high := $twist > 2*math:pi() let $low := $twist < -2*math:pi() let $sinadd := if ($high) then $sintwist * (1 + $twist - 2*math:pi()) else if ($low) then $sintwist * (1 + $twist + 2*math:pi()) else $sintwist let $cosadd := if ($high) then $costwist * (1 + $twist - 2*math:pi()) else if ($low) then $costwist * (1 + $twist + 2*math:pi()) else $costwist return ( ann:f("mut:disc2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($y,$x) let $t := $rot * math:pi() * ($x + $y) let $r := $weight * $θ div math:pi() return ($r * (math:sin($t) + $cosadd), $r * (math:cos($t) + $sinadd)) }, ($weight, $parameters) ) ) }
Function: drift
declare function drift($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function drift($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:drift( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $dx1 as xs:numeric := $parameters("x.min") let $dy1 as xs:numeric := $parameters("y.min") let $dx2 as xs:numeric? := $parameters("x.max") let $dy2 as xs:numeric? := $parameters("y.max") let $x-range as map(xs:string,item()*) := if (empty($dx2) or $dx1=$dx2) then dist:constant($dx1) else dist:uniform($dx1, $dx2) let $y-range as map(xs:string,item()*) := if (empty($dy2) or $dy1=$dy2) then dist:constant($dy1) else dist:uniform($dy1, $dy2) return ( ann:f("mut:drift", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) + rand:randomize($x-range) let $y := v:py($pt) + rand:randomize($y-range) return ($weight * $x, $weight * $y) }, ($weight, $parameters) ) ) }
Function: crumple
declare function crumple($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function crumple($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:crumple( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:crumple", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $rfold := abs(0.5 - $r) let $θ := math:atan2($x,$y) return ( ($weight * $rfold * math:cos($θ), $weight * $rfold * math:sin($θ)) ) }, ($weight, $parameters) ) }
Function: pillow
declare function pillow($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function pillow($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:pillow( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $depth as xs:numeric := $parameters("depth") let $shrink as xs:numeric := $parameters("shrink") let $d2 as xs:numeric := $depth * $depth return ( ann:f("mut:pillow", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := abs($d2 - $x*$x + $y*$y) let $θ := math:atan2($x,$y) let $factor := $shrink div ($r2 + 1) return ( ($weight * $factor * $x, $weight * $factor * $y) ) }, ($weight, $parameters) ) ) }
Function: flowfield
declare function flowfield($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function flowfield($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:flowfield( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $noise as function(*) := $parameters("noise")=>noise:as-vector()=>f:function() let $step as xs:numeric := $parameters("step-size") return ( ann:f("mut:flowfield", function($pt as xs:double*) as xs:double* { let $θ := $noise($pt) * 180 + 180 return v:destination($pt, $θ, $step) }, ($weight, $parameters) ) ) }
Function: bipolar
declare function bipolar($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function bipolar($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:bipolar( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $extent := $parameters("extent") return ann:f("mut:bipolar", function($pt as xs:double*) as xs:double* { let $u := (v:px($pt) + 1) * math:pi() (: [-1,1]=>[0,2π) :) let $v := v:py($pt) * $extent (: [-1,1] => [-extent,extent] :) return coordinates:bipolar($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) }
Function: elliptic
declare function elliptic($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function elliptic($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:elliptic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $scale := $parameters("scale") return ann:f("mut:elliptic", function($pt as xs:double*) as xs:double* { let $u := (v:px($pt) + 1) * $scale (: [-1,1]=>[0,$scale] :) let $v := (v:py($pt) + 1) * math:pi() (: [-1,1]=>[0,2π] :) return coordinates:elliptic($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) }
Function: circular
declare function circular($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function circular($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:circular( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $scale := $parameters("scale") return ann:f("mut:circular", function($pt as xs:double*) as xs:double* { let $u := v:px($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) let $v := v:py($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) return coordinates:circular($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) }
Function: parabolic
declare function parabolic($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function parabolic($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:parabolic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $scale := $parameters("scale") let $symmetric := $parameters("symmetric") return if ($symmetric) then ( ann:f("mut:parabolic", function($pt as xs:double*) as xs:double* { let $u := v:px($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) let $v := v:py($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) return coordinates:parabolic($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) ) else ( ann:f("mut:parabolic", function($pt as xs:double*) as xs:double* { let $u := (v:px($pt) + 1) * $scale (: [-1,1]=>[0,$scale] :) let $v := (v:py($pt) + 1) * $scale (: [-1,1]=>[0,$scale] :) return coordinates:parabolic($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) ) }
Function: sphere
declare function sphere($weight as xs:double,
$parameters as map(xs:string,item()*)) as map(*)
declare function sphere($weight as xs:double, $parameters as map(xs:string,item()*)) as map(*)
Params
- weight as xs:double
- parameters as map(xs:string,item()*)
Returns
- map(*)
declare function this:sphere( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $radius := $parameters("radius") return ann:f("mut:sphere", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $latitude := math:asin($y div $radius) let $circle-radius := $radius * math:cos($latitude) let $sin-longitude := $x div $circle-radius let $longitude := math:asin($sin-longitude) + math:pi() div 2 return ( $weight * $longitude * $radius div math:pi(), $weight * $y ) }, ($weight, $parameters) ) }
Original Source Code
xquery version "3.1"; (:~ : Mutation functions: point to point in the bi-unit square [-1,1]x[-1,1] : The functions are set up to allow them to be selected generically from : a mapping table (as in the fractal flame code) or applied directly. : : Parameters: : Each parameterized function has a parameter with its name which is a map : its parameters. e.g. "mutation.blob" holds parameters for the "blob" function : See Scott Draves & Erik Reckase "The Fractal Flame Algorithm" for specifics. : These can be used to provide default parameter settings for each function. : In addition, the functions are given a weight parameter, which some of : them use. In the fractal flame component this is set to the function weight : in the selection tables. But see this:mutation() for defaulting. : : Randomizers: : : Copyright© Mary Holstege 2020-2023 : CC-BY (https://creativecommons.org/licenses/by/4.0/) : @custom:Status Stable, subject to additions :) module namespace this="http://mathling.com/art/mutations"; import module namespace core="http://mathling.com/art/core" at "../art/core.xqy"; import module namespace config="http://mathling.com/core/config" at "../core/config.xqy"; import module namespace util="http://mathling.com/core/utilities" at "../core/utilities.xqy"; import module namespace f="http://mathling.com/core/callable" at "../core/callable.xqy"; import module namespace rand="http://mathling.com/core/random" at "../core/random.xqy"; import module namespace dist="http://mathling.com/type/distribution" at "../types/distributions.xqy"; import module namespace errors="http://mathling.com/core/errors" at "../core/errors.xqy"; import module namespace v="http://mathling.com/core/vector" at "../core/vector.xqy"; import module namespace box="http://mathling.com/geometric/rectangle" at "../geo/rectangle.xqy"; import module namespace wrapper="http://mathling.com/type/wrapper" at "../types/wrapper.xqy"; import module namespace geom="http://mathling.com/geometric" at "../geo/euclidean.xqy"; import module namespace ann="http://mathling.com/geometric/mutation" at "../geo/mutation.xqy"; import module namespace point="http://mathling.com/geometric/point" at "../geo/point.xqy"; import module namespace affine="http://mathling.com/geometric/affine" at "../geo/affine.xqy"; import module namespace coordinates="http://mathling.com/geometric/coordinates" at "../geo/coordinates.xqy"; import module namespace noise="http://mathling.com/noise/modifiers" at "../noise/modifiers.xqy"; import module namespace perlin="http://mathling.com/noise/perlin" at "../noise/perlin.xqy"; declare namespace art="http://mathling.com/art"; declare namespace map="http://www.w3.org/2005/xpath-functions/map"; declare namespace array="http://www.w3.org/2005/xpath-functions/array"; declare namespace math="http://www.w3.org/2005/xpath-functions/math"; declare variable $this:URI as xs:string := "http://mathling.com/art/mutations"; declare function this:rendering-parameters( $canvas as map(xs:string,item()*), $algorithm-parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { map {} }; declare function this:algorithm-parameters( $resolution as xs:string, $canvas as map(xs:string, item()*) ) as map(xs:string,item()*) { map { "description": "Mutation functions", "mutation.weights": map {}, "mutation.blob": map { "high": 0.75, "low": 0.25, "waves": 7 }, "mutation.PDJ": map { "a": 0.9, "b": 0.75, "c": 0.9, "d": 0.75 }, "mutation.fan2": map { "x": 0.1, "y": -0.1 }, "mutation.rings2": map { "val": 0.5 }, "mutation.perspective": map { "angle": util:radians(30), "dist": 0.75 }, "mutation.juliaN": map { "power": 0.5, "dist": 0.4 }, "mutation.juliaScope": map { "power": 0.5, "dist": 0.4 }, "mutation.radialBlur": map { "angle": util:radians(20) }, "mutation.pie": map { "slices": 7, "rotation": util:radians(20), "thickness": 0.2 }, "mutation.ngon": map { "power": 0.3, "sides": 7, "corners": 4, "circle": 0.3 }, "mutation.curl": map { "c1": 0.8, "c2": 0.7 }, "mutation.rectangles": map { "x": 0.25, "y": -0.1 }, "mutation.flower": map { "holes": 0.5, "petals": 3 }, "mutation.supershape": map { "holes": 0.5, "m": 3, "rnd": 0.5, "n1": 20.0, "n2": 10.0, "n3": 10.0 }, "mutation.conic": map { "holes": 0.5, "eccentricity": 0.5 }, "mutation.parabola": map { "width": 1.0, "height": 1.0 }, "mutation.bent2": map { "x": 2.0, "y": 0.5, "at": 0.0 }, "mutation.disc2": map { "twist": 0.0, "rot": 0.0 }, "mutation.drift": map { "x.min": 0, "x.max": 0.03, "y.min": 0, "y.max": 0.01 }, "mutation.translate": map { "tx": 0.01, "ty": 0.01 }, "mutation.shear": map { "sx": 0.87, "sy": 0.87 }, "mutation.shear-x": map { "sx": 0.87 }, "mutation.shear-y": map { "sy": 0.87 }, "mutation.rotate": map { "angle": 90 }, "mutation.sinusoidal": map { "kx": 1, "ky": 1 }, "mutation.pillow": map { "depth": 0.5, "shrink": 1.0 }, "mutation.flowfield": map { "noise": perlin:noise2-vector(perlin:context()), "step-size": 0.05 }, "mutation.bipolar": map { "extent": 1.0 }, "mutation.elliptic": map { "scale": 1.0 }, "mutation.circular": map { "scale": 1.0 }, "mutation.parabolic": map { "scale": 1.0, "symmetric": false() }, "mutation.sphere": map { "radius": 1.0 } } }; (:~ : colophon() : Standard component colophon : : @param $parameters: active parameters for component :) declare function this:colophon($parameters as map(xs:string,item()*)) as xs:string? { () }; (:~ : metadata() : Standard component metadata : : @param $canvas: canvas component is operating over : @param $randomizers: active randomizers for component : @param $parameters: active parameters for component :) declare function this:metadata( $canvas as map(xs:string,item()*), $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) { () }; declare variable $this:MUTATIONS as xs:string* := ( "div2", "bump_x_div2", "bump_y_div2", "translate", "shear", "shear-x", "shear-y", "reflect", "identity", "rotate", "sinusoidal", "spherical", "swirl", "horseshoe", "polar", "hankerchief", "heart", "disc", "spiral", "hyperbolic", "diamond", "ex", "julia", "bent", "fisheye", "exponential", "power", "cosine", "blob", "PDJ", "fan2", "rings2", "eyefish", "bubble", "cylinder", "perspective", "noise", "juliaN", "juliaScope", "blur", "gaussian", "radialBlur", "pie", "ngon", "curl", "rectangles", "supershape", "flower", "conic", "parabola", "bent2", "arch", "tangent", "square", "rays", "blade", "secant", "twintrian", "cross", "disc2", "drift", "crumple", "pillow", "flowfield", "bipolar", "elliptic", "circular", "parabolic", "sphere" ); declare variable $this:FOREGROUND-MUTATIONS as xs:string* := ( "div2", "bump_x_div2", "bump_y_div2", "shear", "shear-x", "shear-y", "reflect", "identity", "rotate", "sinusoidal", "spherical", "swirl", "horseshoe", "polar", "hankerchief", "heart", "disc", "spiral", "hyperbolic", "diamond", "ex", "bent", "fisheye", "exponential", "power", "cosine", "blob", "PDJ", "fan2", "rings2", "eyefish", "bubble", "cylinder", "perspective", "ngon", "curl", "rectangles", "bent2", "tangent", "secant", "cross", "drift", "crumple", "pillow", "flowfield", "bipolar", "elliptic", "circular", "sphere" ); declare variable $this:BACKGROUND-MUTATIONS as xs:string* := ( "julia", "juliaN", "flower", "conic", "parabola", "noise", "juliaScope", "blur", "gaussian", "radialBlur", "pie", "supershape", "arch", "square", "blade", "rays", "twintrian", "disc2", "translate", "parabolic" ); declare function this:randomizers( $canvas as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { map { "mutation.n-composed": dist:zipf(1.7, 3), "mutation.mutations": dist:uniform-index-of($this:FOREGROUND-MUTATIONS), (: Function parameter randomizers :) "mutation.blob.high": dist:uniform(0.8, 1.2), "mutation.blob.low": dist:uniform(0.2, 0.7), "mutation.blob.waves": dist:uniform(2, 7)=>dist:cast("integer"), "mutation.PDJ.a": dist:uniform(-3.0, 3.0), "mutation.PDJ.b": dist:uniform(-3.0, 3.0), "mutation.PDJ.c": dist:uniform(-3.0, 3.0), "mutation.PDJ.d": dist:uniform(-3.0, 3.0), "mutation.fan2.x": dist:uniform(-1.0, 1.0), "mutation.fan2.y": dist:uniform(-1.0, 1.0), "mutation.rings2.val": dist:uniform(0.0, 2.0), "mutation.perspective.angle": dist:uniform(0.0, 1.0), (: radians :) "mutation.perspective.dist": dist:uniform(1.0, 3.0), "mutation.juliaN.power": dist:uniform(2, 7)=>dist:cast("integer"), "mutation.juliaN.dist": dist:constant(1.0), "mutation.juliaScope": dist:uniform(2, 7)=>dist:cast("integer"), "mutation.juliaScope.dist": dist:constant(1.0), "mutation.radialBlur.angle": dist:uniform(-1.0, 1.0), (: radians :) "mutation.pie.slices": dist:uniform(0, 10)=>dist:cast("integer"), "mutation.pie.rotation": dist:uniform(-2.0*math:pi(), 2.0*math:pi()), (: radians :) "mutation.pie.thickness": dist:uniform(0.0, 1.0), "mutation.ngon.power": dist:uniform(1.0, 4.0), "mutation.ngon.sides": dist:uniform(3, 13)=>dist:cast("integer"), "mutation.ngon.corners": dist:uniform(0.0, 3.0)=>dist:post-multiplier(1.5), (: should be ngon.circle value :) "mutation.ngon.circle": dist:uniform(0.0, 3.0), "mutation.curl.c1": dist:uniform(0.0, 1.0), "mutation.curl.c2": dist:uniform(0.0, 1.0), "mutation.rectangles.x": dist:uniform(0.0, 1.0), "mutation.rectangles.y": dist:uniform(0.0, 1.0), "mutation.supershape.holes": dist:constant(0.0), "mutation.supershape.m": dist:uniform(0, 6)=>dist:cast("integer"), "mutation.supershape.rnd": dist:uniform(0.0, 1.0), "mutation.supershape.n1": dist:uniform(0.0, 40.0), "mutation.supershape.n2": dist:uniform(0.0, 20.0), "mutation.supershape.n3": dist:uniform(0.0, 20.0), (: really = n2 :) "mutation.flower.holes": dist:uniform(0.0, 1.0), "mutation.flower.petals": dist:uniform(0.0, 4.0), "mutation.conic.holes": dist:uniform(0.0, 1.0), "mutation.conic.eccentricity": dist:uniform(0.0, 1.0), "mutation.parabola.height": dist:uniform(0.5, 1.5), "mutation.parabola.width": dist:uniform(0.5, 1.5), "mutation.bent2.at": dist:uniform(-1.0, 1.0), "mutation.bent2.x": dist:uniform(-1.5, 1.5), "mutation.bent2.y": dist:uniform(-1.5, 1.5), "mutation.disc2.twist": dist:uniform(-0.5, 0.5), "mutation.disc2.rot": dist:uniform(-0.5, 0.5), "mutation.drift.x.min": dist:constant(0.0), "mutation.drift.x.max": dist:uniform(0.01, 0.05), "mutation.drift.y.min": dist:constant(0.0), "mutation.drift.y.max": dist:uniform(0.01, 0.03), "mutation.rotate.angle": dist:normal(90, 20)=>dist:cast("integer"), (: degrees :) "mutation.sinusoidal.kx": dist:poisson(4.5)=>dist:min(0.5), "mutation.sinusoidal.ky": dist:poisson(4.5)=>dist:min(0.5), "mutation.translate.tx": dist:normal(0.0, 0.3), "mutation.translate.ty": dist:normal(0.0, 0.3), "mutation.shear.sx": dist:uniform(0.0, 1.5), "mutation.shear.sy": dist:uniform(0.0, 1.5), "mutation.shear-x.sx": dist:uniform(0.0, 1.5), "mutation.shear-y.sy": dist:uniform(0.0, 1.5), "mutation.pillow.depth": dist:uniform(0.25, 1.0), "mutation.pillow.shrink": dist:uniform(1.0, 3.0), "mutation.flowfield.step-size": dist:normal(0.05, 0.001)=>dist:min(0)=>dist:max(0.2), "mutation.bipolar.extent": dist:uniform(1.0, 4.0), "mutation.elliptic.scale": dist:uniform(0.5, 2.5), "mutation.circular.scale": dist:uniform(0.5, 3.5), "mutation.parabolic.scale": dist:uniform(0.5, 2.0), "mutation.parabolic.symmetric": dist:flip(50), "mutation.sphere.radius": dist:normal(1.0, 0.1)=>dist:min(0.5)=>dist:max(1.5) } }; (:~ : scaled() : Map a point on the canvas to a point in the bi-unit square, apply the : function, and map it back out. (The functions generally only work : properly on bi-unit square.) :) declare function this:scaled( $f as item(), $canvas as map(xs:string,item()*) ) as map(*) { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $width := box:width($canvas) let $height := box:height($canvas) let $fn := ann:function($f) return if (ann:is-mutation-point($f)) then ( ann:f("mut:scaled", function($point as map(xs:string,item()*)) as map(xs:string,item()*) { let $p := $fn( point:point( 2 * (point:px($point) - $width div 2) div $width, 2 * (point:py($point) - $height div 2) div $height ) ) return ( point:point( $width * (point:px($p) + 1) div 2, $height * (point:py($p) + 1) div 2 )=>point:snap() ) }, $f ) ) else ( ann:f("mut:scaled", function($point as xs:double*) as xs:double* { let $p := $fn( ( 2 * (v:px($point) - $width div 2) div $width, 2 * (v:py($point) - $height div 2) div $height ) ) return ( ( $width * (v:px($p) + 1) div 2, $height * (v:py($p) + 1) div 2 )=>v:snap() ) }, $f ) ) }; (:~ : as-point() : Pass through to make a point-as-point function, converting from vector :) declare function this:as-point( $f as item() ) as item() { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $fn := ann:function($f) return ( if (ann:is-mutation-vector($f)) then ( ann:f(util:function-name($f), function($point as map(xs:string,item()*)) as map(xs:string,item()*) { point:vector($fn(point:pcoordinates($point))) } ) ) else ( $f ) ) }; (:~ : as-vector() : Pass through to make a vector-to-vector function, converting from point-to-point :) declare function this:as-vector( $f as item() ) as item() { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $fn := ann:function($f) return ( if (ann:is-mutation-point($f)) then ( ann:f(util:function-name($f), function($point as xs:double*) as xs:double* { point:pcoordinates($fn(point:vector($point))) } ) ) else ( $f ) ) }; (:~ : mutation() : Get the function definition by name, fetch its corresponding parameter : bundle from the parameters, and return the resulting function. : The function will be one of the functions in this namespace. :) declare function this:mutation( $name as xs:string, $parameters as map(xs:string,item()*) ) as map(*) { let $as-point := ends-with($name,"+point") let $name := if ($as-point) then substring-before($name,"+point") else $name let $f := function-lookup(QName($this:URI, "this:"||$name), 2) let $parms := ($parameters("mutation."||$name), map {})[1] let $weight := if (exists($parameters("mutation.weights"))) then ($parameters("mutation.weights")($name), 1.0)[1] else 1.0 return ( if ($as-point) then $f($weight, $parms)=>this:as-point() else $f($weight, $parms) ) }; (:~ : mutation() : Get the function definition by name, and construct the corresponding : parameter bundle by overriding default parameters with randomized values. : Return a wrapper of the resulting function with the dynamic values. : The function will be one of the functions in this namespace. :) declare function this:random-mutation( $name as xs:string, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { let $as-point := ends-with($name,"+point") let $name := if ($as-point) then substring-before($name,"+point") else $name let $f := function-lookup(QName($this:URI, "this:"||$name), 2) let $parms := util:merge-into(( ($parameters("mutation."||$name), map{})[1], for $key in map:keys($randomizers)[starts-with(., "mutation."||$name||".")] return ( map { substring-after($key, "mutation."||$name||"."): core:randomize($key, $randomizers) } ) )) let $weight := if (exists($parameters("mutation.weights"))) then ($parameters("mutation.weights")($name), 1.0)[1] else 1.0 return ( if ($as-point) then wrapper:wrapper($f($weight, $parms)=>this:as-point(), $parms) else wrapper:wrapper($f($weight, $parms), $parms) ) }; (:~ : mutation() : Get the function definition by name, fetch its corresponding parameter : bundle from the parameters, and return the resulting function. : The function will be one of the functions in this namespace. : Pass in the given weight. :) declare function this:mutation( $name as xs:string, $parameters as map(xs:string,item()*), $weight as xs:double ) as map(*) { let $as-point := ends-with($name,"+point") let $name := if ($as-point) then substring-before($name,"+point") else $name let $f := function-lookup(QName($this:URI, "this:"||$name), 2) let $parms := ($parameters("mutation."||$name), map {})[1] return ( if ($as-point) then $f($weight, $parms)=>this:as-point() else $f($weight, $parms) ) }; (:~ : compose() : Apply f then apply g :) declare function this:compose( $f as item(), $g as item() ) as map(*) { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), if (not(ann:is-mutation($g))) then errors:error("ML-BADARGS", ("g", $g)) else (), if (ann:is-mutation-vector($f) and ann:is-mutation-vector($g)) then ( let $fn := $f=>ann:function() let $gn := $g=>ann:function() return ( ann:f("mut.compose", function($point as xs:double*) as xs:double* { $fn($point)=>$gn() }, ($f, $g) ) ) ) else ( let $f := this:as-point($f) let $g := this:as-point($g) let $fn := $f=>ann:function() let $gn := $g=>ann:function() return ( ann:f("mut.compose", function($point as map(xs:string,item()*)) as map(xs:string,item()*) { $fn($point)=>$gn() }, ($f, $g) ) ) ) }; (:~ : compose() : Apply functions in order :) declare function this:compose( $fs as item()* ) as map(*) { if (some $f in $fs satisfies not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("fs", $fs)) else (), if (every $f in $fs satisfies ann:is-mutation-vector($f)) then ( let $fns := $fs!ann:function(.) return ( ann:f("mut:compose", function($point as xs:double*) as xs:double* { fold-left($fns, $point, function($point as xs:double*, $fn as function(*)) as xs:double* { $fn($point) } ) }, $fs ) ) ) else ( let $fs := $fs!this:as-point(.) let $fns := $fs!ann:function(.) return ( ann:f("mut:compose", function($point as map(xs:string,item()*)) as map(xs:string,item()*) { fold-left($fns, $point, function($point as map(xs:string,item()*), $fn as function(*)) as map(xs:string,item()*) { $fn($point) } ) }, $fs ) ) ) }; (:~ : mutations() : Return the composite mutation function corresponding to a compound name. : e.g. eyefish·swirl = compose(eyefish(), swirl()) with appropriate parameters : If canvas is present, scale to/from the canvas. :) declare function this:mutations( $mutations as xs:string, $canvas as map(xs:string,item()*)?, $parameters as map(xs:string,item()*) ) as map(*) { let $mutation-kinds := tokenize($mutations, "·")[. ne ''] return ( if ($mutations="none") then ( this:none(0, map{}) ) else if ($mutations="none+point") then ( this:none(0, map{})=>this:as-point() ) else if (empty($canvas)) then ( if (count($mutation-kinds)=1) then ( this:mutation($mutation-kinds, $parameters) ) else ( this:compose( for $fname in $mutation-kinds return ( this:mutation($fname, $parameters) ) ) ) ) else ( this:scaled( if (count($mutation-kinds)=1) then ( this:mutation($mutation-kinds, $parameters) ) else ( this:compose( for $fname in $mutation-kinds return ( this:mutation($fname, $parameters) ) ) ) , $canvas ) ) ) }; (:~ : mutations() : Return the composite mutation function corresponding to a compound name : in a wrapper : e.g. eyefish·swirl = compose(eyefish(), swirl()) with appropriate parameters : If canvas is present, scale to/from the canvas. : If $mutations="random" pick a random mutation with random parameters : If $mutations starts with "random", randomize the rest of the mutation names :) declare function this:mutations( $mutations as xs:string, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { if ($mutations="random") then ( this:random-random-mutations(false(), $canvas, $randomizers, $parameters) ) else if ($mutations="random+point") then ( this:random-random-mutations(true(), $canvas, $randomizers, $parameters) ) else if (starts-with($mutations, "random·")) then ( this:random-mutations(substring-after($mutations, "random·"), $canvas, $randomizers, $parameters) ) else ( wrapper:wrapper( this:mutations($mutations, $canvas, $parameters), map {} ) ) }; (:~ : random-mutations() : Return the composite mutation function corresponding to a compound name. : e.g. eyefish·swirl = compose(eyefish(), swirl()) with appropriate randomized : parameters : If canvas is present, scale to/from the canvas. : Returns a wrapper of the function with the dynamic values :) declare function this:random-mutations( $mutations as xs:string, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { let $mutation-kinds := tokenize($mutations, "·")[. ne ''] return ( if ($mutations="none") then ( wrapper:wrapper( this:none(0, map{}), map {} ) ) else if ($mutations="none+point") then ( wrapper:wrapper( this:none(0, map{})=>this:as-point(), map {} ) ) else if (empty($canvas)) then ( if (count($mutation-kinds)=1) then ( this:random-mutation($mutation-kinds, $randomizers, $parameters) ) else ( let $wrappers := for $fname in $mutation-kinds return ( this:random-mutation($fname, $randomizers, $parameters) ) return ( wrapper:wrapper( this:compose(for $wrapper in $wrappers return wrapper:body($wrapper)), util:merge-into(( for $fname at $i in $mutation-kinds return ( map { "mutation."||$fname: wrapper:dynamics($wrappers[$i]) } ) )) ) ) ) ) else ( let $wrappers := for $fname in $mutation-kinds return ( this:random-mutation($fname, $randomizers, $parameters) ) return ( wrapper:wrapper( this:scaled( if (count($mutation-kinds)=1) then ( wrapper:body($wrappers) ) else ( this:compose(for $wrapper in $wrappers return wrapper:body($wrapper)) ), $canvas ), util:merge-into(( for $fname at $i in $mutation-kinds return ( map { "mutation."||$fname: wrapper:dynamics($wrappers[$i]) } ) )) ) ) ) ) }; declare function this:random-random-mutations( $as-point as xs:boolean, $canvas as map(xs:string,item()*)?, $randomizers as map(xs:string,item()*), $parameters as map(xs:string,item()*) ) as map(xs:string,item()*) { let $n-composed as xs:integer := core:randomize("mutation.n-composed", $randomizers) let $name as xs:string := (if ($n-composed = 0) then "none" else ( string-join( distinct-values( core:randomize($n-composed, (), "mutation.mutations", $randomizers) ), "·" ) ))|| (if ($as-point) then "+point" else "") return ( this:random-mutations($name, $canvas, $randomizers, $parameters) ) }; (:~ : trace() : Tracing pass-through for mutation function :) declare function this:trace( $f as item() ) as map(*) { if (not(ann:is-mutation($f))) then errors:error("ML-BADARGS", ("f", $f)) else (), let $fn := ann:function($f) return ( if (ann:is-mutation-point($f)) then ( ann:f(util:function-name($f), function ($point as map(xs:string,item()*)) as map(xs:string,item()*) { $fn($point)=>trace(util:quote($f)||"("||point:quote($point)||")") } ) ) else ( ann:f(util:function-name($f), function ($point as xs:double*) as xs:double* { $fn($point)=>trace(util:quote($f)||"("||v:quote($point)||")") } ) ) ) }; (:======================================================================: : Specific mutation functions :======================================================================:) declare function this:none( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("no-op", function ($pt as xs:double*) as xs:double* { $pt } ) }; (: : Notation conventions: : r = √x²+y² : θ = arctan(x/y) : φ = arctan(y/x) : Ψ = rand(uniform(0,1)) : Ω = rand(0|π) : Λ = rand(0|1) : Not handling dependent/parametric variations right now :) declare function this:div2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:div2", function($pt as xs:double*) as xs:double* { ($weight * v:px($pt) div 2, $weight * v:py($pt) div 2) }, ($weight, $parameters) ) }; declare function this:bump_x_div2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bump_x_div2", function($pt as xs:double*) as xs:double* { ($weight * (v:px($pt)+1) div 2, $weight * v:py($pt) div 2) }, ($weight, $parameters) ) }; declare function this:bump_y_div2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bump_y_div2", function($pt as xs:double*) as xs:double* { ($weight * v:px($pt) div 2, $weight * (v:py($pt)+1) div 2) }, ($weight, $parameters) ) }; declare function this:translate( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $tx as xs:numeric := $parameters("tx") let $ty as xs:numeric := $parameters("ty") return ( ann:f("mut:translate", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:translation2($tx, $ty))=>v:times($weight) }, ($weight, $parameters) ) ) }; declare function this:shear( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $sx as xs:numeric := $parameters("sx") let $sy as xs:numeric := $parameters("sy") return ( ann:f("mut:shear", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:shearing2($sx, $sy))=>v:times($weight) }, ($weight, $parameters) ) ) }; declare function this:shear-x( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $sx as xs:numeric := $parameters("sx") return ( ann:f("mut:shear-x", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:shearing2($sx, 0))=>v:times($weight) }, ($weight, $parameters) ) ) }; declare function this:shear-y( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $sy as xs:numeric := $parameters("sy") return ( ann:f("mut:shear-y", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:shearing2(0, $sy))=>v:times($weight) }, ($weight, $parameters) ) ) }; declare function this:reflect( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:reflect", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:reflection2($point:ORIGIN))=>v:times($weight) }, ($weight, $parameters) ) }; declare function this:identity( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:identity", function($pt as xs:double*) as xs:double* { $pt=>v:times($weight) }, ($weight, $parameters) ) }; declare function this:rotate( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $angle as xs:numeric := $parameters("angle") return ( ann:f("mut:rotate", function($pt as xs:double*) as xs:double* { $pt=>affine:affine2(affine:rotation2($angle))=>v:times($weight) }, ($weight, $parameters) ) ) }; declare function this:sinusoidal( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $kx as xs:numeric := $parameters("kx") let $ky as xs:numeric := $parameters("ky") return ( ann:f("mut:sinusoidal", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ($weight * math:sin($kx * $x), $weight * math:sin($ky * $y)) }, ($weight, $parameters) ) ) }; declare function this:spherical( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:spherical", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y return if ($r2=0) then ($weight * $x div ($r2+1), $weight * $y div ($r2+1)) else ($weight * $x div $r2, $weight * $y div $r2) }, ($weight, $parameters) ) }; declare function this:swirl( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:swirl", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y return ( $weight * ($x*math:sin($r2) - $y*math:cos($r2)), $weight * ($x*math:cos($r2) + $y*math:sin($r2)) ) }, ($weight, $parameters) ) }; declare function this:horseshoe( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:horseshoe", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return if ($r=0) then ($weight*($x - $y)*($x + $y) div ($r+1), $weight*2*$x*$y div ($r+1)) else ($weight*($x - $y)*($x + $y) div $r, $weight*2*$x*$y div $r) }, ($weight, $parameters) ) }; declare function this:polar( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:polar", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ($weight * $θ div math:pi(), $weight * ($r - 1)) }, ($weight, $parameters) ) }; declare function this:hankerchief( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:hankerchief", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ($weight * $r*math:sin($θ + $r), $weight * $r*math:cos($θ - $r)) }, ($weight, $parameters) ) }; declare function this:heart( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:heart", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ($weight * $r*math:sin($θ*$r), $weight * $r*-math:cos($θ*$r)) }, ($weight, $parameters) ) }; declare function this:disc( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:disc", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ( $weight * ($θ div math:pi()) * math:sin($θ*$r), $weight * ($θ div math:pi()) * math:cos($θ*$r) ) }, ($weight, $parameters) ) }; declare function this:spiral( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:spiral", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return if ($r = 0) then ( $weight * (math:cos($θ) + math:sin($r)) div ($r+1), $weight * (math:sin($θ) - math:cos($r)) div ($r+1) ) else ( (math:cos($θ) + math:sin($r)) div $r, (math:sin($θ) - math:cos($r)) div $r ) }, ($weight, $parameters) ) }; declare function this:hyperbolic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:hyperbolic", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return if ($r = 0) then ($weight * math:sin($θ) div ($r + 1), $weight * $r * math:cos($θ)) else ($weight * math:sin($θ) div $r, $weight * $r * math:cos($θ)) }, ($weight, $parameters) ) }; declare function this:diamond( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:diamond", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) return ( $weight * math:sin($θ) * math:cos($r), $weight * math:cos($θ) * math:sin($r) ) }, ($weight, $parameters) ) }; declare function this:ex( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:ex", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $p0 := math:sin($θ + $r) let $p1 := math:cos($θ - $r) return ( $weight * $r*($p0*$p0*$p0 + $p1*$p1*$p1), $weight * $r*($p0*$p0*$p0 - $p1*$p1*$p1) ) }, ($weight, $parameters) ) }; declare function this:julia( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:julia", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $root_r := math:sqrt(math:sqrt($x*$x + $y*$y)) let $θ := math:atan2($x,$y) let $Ω := if (rand:flip(50)) then 0 else math:pi() return ( $weight * $root_r * math:cos($θ div 2 + $Ω), $weight * $root_r * math:sin($θ div 2 + $Ω) ) }, ($weight, $parameters) ) }; declare function this:bent( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bent", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( if ($x ge 0 and $y ge 0) then $pt else if ($x lt 0 and $y ge 0) then ($weight * 2*$x, $weight * $y) else if ($x ge 0 and $y lt 0) then ($weight * $x, $weight * $y div 2) else (: x lt 0 and y lt 0 :) ($weight * 2*$x, $weight * $y div 2) ) }, ($weight, $parameters) ) }; declare function this:fisheye( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:fisheye", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return ( $weight * (2 div ($r + 1)) * $y, $weight * (2 div ($r + 1)) * $x ) }, ($weight, $parameters) ) }; declare function this:exponential( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:exponential", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * math:exp($x - 1)*math:cos(math:pi()*$y), $weight * math:exp($x - 1)*math:sin(math:pi()*$y) ) }, ($weight, $parameters) ) }; declare function this:power( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:power", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($x,$y) let $r := math:sqrt($x*$x + $y*$y) let $rexp := math:pow($r, math:sin($θ)) return ($weight * $rexp*math:cos($θ), $weight * $rexp*math:sin($θ)) }, ($weight, $parameters) ) }; declare function this:cosine( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:cosine", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * math:cos(math:pi()*$x)*util:cosh($y), $weight * math:sin(math:pi()*$x)*util:sinh($y) ) }, ($weight, $parameters) ) }; declare function this:blob( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("high") let $p2 as xs:numeric := $parameters("low") let $p3 as xs:numeric := $parameters("waves") return ( ann:f("mut:blob", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $factor := $r*($p2 + (($p1 - $p2) div 2)*(math:sin($p3*$θ)+1)) return ( $weight * $factor*math:cos($θ), $weight * $factor*math:sin($θ) ) }, ($weight, $parameters) ) ) }; declare function this:PDJ( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("a") let $p2 as xs:numeric := $parameters("b") let $p3 as xs:numeric := $parameters("c") let $p4 as xs:numeric := $parameters("d") return ( ann:f("mut:PDJ", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * (math:sin($p1*$y) - math:cos($p2*$x)), $weight * (math:sin($p3*$x) - math:cos($p4*$y)) ) }, ($weight, $parameters) ) ) }; declare function this:fan2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $fan2_x := $parameters("x") let $p1 as xs:numeric := math:pi()*($fan2_x)*($fan2_x) let $p2 as xs:numeric := $parameters("y") return ( ann:f("mut:fan2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $t := $θ + $p2 - $p1*util:trunc(2*$θ*$p2 div $p1) return if ($t gt $p1 div 2) then ( ( $weight * $r * math:sin($θ - $p1 div 2), $weight * $r * math:cos($θ - $p1 div 2) ) ) else ( ( $weight * $r * math:sin($θ + $p1 div 2), $weight * $r * math:cos($θ + $p1 div 2) ) ) }, ($weight, $parameters) ) ) }; declare function this:rings2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $rings2_val := $parameters("val") let $p as xs:numeric := $rings2_val*$rings2_val return ( ann:f("mut:rings2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($x,$y) let $t := $r - 2*util:trunc(($r + $p) div (2*$p)) + $r*(1-$p) return ($weight * $t * math:sin($θ), $weight * $t * math:cos($θ)) }, ($weight, $parameters) ) ) }; declare function this:eyefish( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:eyefish", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $factor := 2 div ($r + 1) return ($weight * $factor * $x, $weight * $factor * $y) }, ($weight, $parameters) ) }; declare function this:bubble( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:bubble", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y let $factor := 4 div ($r2 + 4) return ($weight * $factor * $x, $weight * $factor * $y) }, ($weight, $parameters) ) }; declare function this:cylinder( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:cylinder", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ($weight * math:sin($x), $weight * $y) }, ($weight, $parameters) ) }; declare function this:perspective( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("angle") let $p2 as xs:numeric := $parameters("dist") return ( ann:f("mut:perspective", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y let $factor := $p2 div ($p2 - $y*math:sin($p1)) return ( $weight * $factor * $x, $weight * $factor * $y * math:cos($p1) ) }, ($weight, $parameters) ) ) }; declare function this:noise( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:noise", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ( $weight * $Ψ1 * $x * math:cos(2*math:pi()*$Ψ2), $weight * $Ψ1 * $y * math:sin(2*math:pi()*$Ψ2) ) }, ($weight, $parameters) ) }; declare function this:juliaN( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("power") let $p2 as xs:numeric := $parameters("dist") return ( ann:f("mut:juliaN", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $p3 as xs:numeric := util:trunc(abs($p1)*$Ψ) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $t := ($φ + 2*math:pi()*$p3) div $p1 let $factor := math:pow($r, $p2 div $p1) return ( $weight * $factor * math:cos($t), $weight * $factor * math:sin($t) ) }, ($weight, $parameters) ) ) }; declare function this:juliaScope( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("power") let $p2 as xs:numeric := $parameters("dist") return ( ann:f("mut:juliaScope", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $p3 as xs:numeric := util:trunc(abs($p1)*$Ψ) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $Λ := if (rand:flip(50)) then 0 else 1 let $t := ($Λ*$φ + 2*math:pi()*$p3) div $p1 let $factor := math:pow($r, $p2 div $p1) return ( $weight * $factor * math:cos($t), $weight * $factor * math:sin($t) ) }, ($weight, $parameters) ) ) }; declare function this:blur( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:blur", function($pt as xs:double*) as xs:double* { let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ( $weight * $Ψ1 * math:cos(2*math:pi()*$Ψ2), $weight * $Ψ1 * math:sin(2*math:pi()*$Ψ2) ) }, ($weight, $parameters) ) }; declare function this:gaussian( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:gaussian", function($pt as xs:double*) as xs:double* { (: Q&D approximation for Gaussian distribution :) let $Ψ := for $i in 1 to 5 return rand:uniform(0.0, 1.0) let $factor := sum($Ψ[position()<=4]) - 2 return ( $weight * $factor * math:cos(2*math:pi()*$Ψ[5]), $weight * $factor * math:sin(2*math:pi()*$Ψ[5]) ) }, ($weight, $parameters) ) }; declare function this:radialBlur( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("angle") * (math:pi() div 2) let $ν36 as xs:numeric := $weight return ( ann:f("mut:radialBlur", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $Ψ := for $i in 1 to 4 return rand:uniform(0.0, 1.0) let $t1 := $ν36 * (sum($Ψ) - 2) let $t2 := $φ + $t1*math:sin($p1) let $t3 := $t1 * math:cos($p1) - 1 return ( $weight * ($r*math:cos($t2) + $t3*$x) div $ν36, $weight * ($r*math:sin($t2) + $t3*$y) div $ν36 ) }, ($weight, $parameters) ) ) }; declare function this:pie( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("slices") let $p2 as xs:numeric := $parameters("rotation") let $p3 as xs:numeric := $parameters("thickness") return ( ann:f("mut:pie", function($pt as xs:double*) as xs:double* { let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) let $Ψ3 := rand:uniform(0.0, 1.0) let $t1 := util:trunc($Ψ1*$p1 + 0.5) let $t2 := $p2 + (2*math:pi() div $p1)*($t1 + $Ψ2*$p3) return ($weight * $Ψ3*math:cos($t2), $weight * $Ψ3*math:sin($t2)) }, ($weight, $parameters) ) ) }; declare function this:ngon( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("power") let $p2 as xs:numeric := $parameters("sides") let $p3 as xs:numeric := $parameters("corners") let $p4 as xs:numeric := $parameters("circle") return ( ann:f("mut:ngon", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $φ := math:atan2($y,$x) let $t3 := $φ - $p2*floor($φ div $p2) let $t4 := if ($t3 gt $p2 div 2) then $t3 else $t3 - $p2 let $k := ($p3 * ((1 div math:cos($t4)) - 1) + $p4) div math:pow($r, $p1) return ($weight * $k*$x, $weight * $k*$y) }, ($weight, $parameters) ) ) }; declare function this:curl( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("c1") let $p2 as xs:numeric := $parameters("c2") return ( ann:f("mut:curl", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $t1 := 1 + $p1*$x + $p2*($x*$x - $y*$y) let $t2 := $p1*$y + 2*$p2*$x*$y let $inv-factor := $t1*$t1 + $t2*$t2 let $factor := if ($inv-factor = 0) then 1 div ($inv-factor + 1) else 1 div $inv-factor return ( $weight * $factor*($x*$t1 + $y*$t2), $weight * $factor*($y*$t1 - $x*$t2) ) }, ($weight, $parameters) ) ) }; declare function this:rectangles( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $p1 as xs:numeric := $parameters("x") let $p2 as xs:numeric := $parameters("y") return ( ann:f("mut:rectangles", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return ( $weight * ((2*floor($x div $p1) + 1)*$p1 - $x), $weight * ((2*floor($y div $p2) + 1)*$p2 - $y) ) }, ($weight, $parameters) ) ) }; declare function this:supershape( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $holes as xs:numeric := $parameters("holes") let $m as xs:numeric := $parameters("m") let $n1 as xs:numeric := $parameters("n1") let $n2 as xs:numeric := $parameters("n1") let $n3 as xs:numeric := $parameters("n1") let $rnd as xs:numeric := $parameters("rnd") let $m_over_4 := $m div 4.0 let $neg1_over_n1 := -1.0 div $n1 return ( ann:f("mut:supershape", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($y,$x) let $α := $m_over_4 * $θ + math:pi() div 4.0 let $t1 := math:pow(abs(math:sin($α)), $n2) let $t2 := math:pow(abs(math:cos($α)), $n3) let $Ψ1 := rand:uniform(0.0, 1.0) let $factor := ( ($rnd*$Ψ1 + (1.0 - $rnd)*$r - $holes) * math:pow($t1 + $t2, $neg1_over_n1) ) div $r return ( ($weight * $factor * $x, $weight * $factor * $y) ) }, ($weight, $parameters) ) ) }; declare function this:flower( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $holes as xs:numeric := $parameters("holes") let $petals as xs:numeric := $parameters("petals") return ( ann:f("mut:flower", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($y,$x) let $Ψ1 := rand:uniform(0.0, 1.0) let $r := $weight * ($Ψ1 - $holes) * math:cos($petals * $θ) return ( ($r * math:cos($θ), $r * math:sin($θ)) ) }, ($weight, $parameters) ) ) }; declare function this:conic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $holes as xs:numeric := $parameters("holes") let $eccentricity as xs:numeric := $parameters("eccentricity") return ( ann:f("mut:conic", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($y,$x) let $Ψ1 := rand:uniform(0.0, 1.0) let $r := $weight * ($Ψ1 - $holes) * $eccentricity div (1 + $eccentricity * math:cos($θ)) return ( ($r * math:cos($θ), $r * math:sin($θ)) ) }, ($weight, $parameters) ) ) }; declare function this:parabola( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $width as xs:numeric := $parameters("width") let $height as xs:numeric := $parameters("height") return ( ann:f("mut:parabola", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $θ := math:atan2($y,$x) let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ( ( $weight * $height * math:sin($r) * math:sin($r) * $Ψ1, $weight * $width * math:cos($r) * $Ψ2 ) ) }, ($weight, $parameters) ) ) }; declare function this:bent2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $at as xs:numeric := $parameters("at") let $bendx as xs:numeric := $parameters("x") let $bendy as xs:numeric := $parameters("y") return ( ann:f("mut:bent2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $x := if ($x < $at) then $x * $bendx else $x let $y := if ($y < $at) then $y * $bendy else $y return ( ($weight * $x, $weight * $y) ) }, ($weight, $parameters) ) ) }; declare function this:arch( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν41 as xs:numeric := $weight return ( ann:f("mut:arch", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $sin := math:sin($Ψ*math:pi()*$ν41) return ( $weight * $sin, $weight * $sin*$sin div math:cos($Ψ*math:pi()*$ν41) ) }, ($weight, $parameters) ) ) }; declare function this:tangent( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:tangent", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) return if (math:cos($y) = 0) then ($weight, $weight * math:tan($y)) else ($weight * math:sin($x) div math:cos($y), $weight * math:tan($y)) }, ($weight, $parameters) ) }; declare function this:square( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:square", function($pt as xs:double*) as xs:double* { let $Ψ1 := rand:uniform(0.0, 1.0) let $Ψ2 := rand:uniform(0.0, 1.0) return ($weight * ($Ψ1 - 0.5), $weight * ($Ψ2 - 0.5)) }, ($weight, $parameters) ) }; declare function this:rays( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν44 as xs:numeric := $weight return ( ann:f("mut:rays", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $x := v:px($pt) let $y := v:py($pt) let $r2 := $x*$x + $y*$y + 1.0E-7 let $factor := math:tan($Ψ*math:pi()*$ν44) div $r2 return ( $weight * $factor*math:cos($x), $weight * $factor*math:sin($y) ) }, ($weight, $parameters) ) ) }; declare function this:blade( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν45 as xs:numeric := $weight return ( ann:f("mut:blade", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return ( $weight * ($x*(math:cos($Ψ*$r*$ν45) + math:sin($Ψ*$r*$ν45))), $weight * ($x*(math:cos($Ψ*$r*$ν45) - math:sin($Ψ*$r*$ν45))) ) }, ($weight, $parameters) ) ) }; declare function this:secant( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν46 as xs:numeric := $weight return ( ann:f("mut:secant", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) return if (math:cos($r*$ν46)=0) then ( $weight * $x, $weight * (1 + 1.0 div math:cos($r*$ν46)) ) else ( $weight * $x, $weight * (-1 + 1.0 div math:cos($r*$ν46)) ) }, ($weight, $parameters) ) ) }; declare function this:twintrian( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $ν47 as xs:numeric := $weight return ( ann:f("mut:twintrian", function($pt as xs:double*) as xs:double* { let $Ψ := rand:uniform(0.0, 1.0) let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $t := math:log10(math:sin($Ψ*$r*$ν47)*math:sin($Ψ*$r*$ν47)) + math:cos($Ψ*$r*$ν47) return ( $weight * $x * $t, $weight * $x * ($t - math:pi()*math:sin($Ψ*$r*$ν47)) ) }, ($weight, $parameters) ) ) }; declare function this:cross( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:cross", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $d := $x*$x - $y*$y let $factor := math:sqrt(1.0 div ($d*$d + 1.0E-7)) return ($weight * $factor * $x, $weight * $factor * $y) }, ($weight, $parameters) ) }; declare function this:disc2( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $twist as xs:numeric := $parameters("twist") let $rot as xs:numeric := $parameters("rot") let $pirot := $rot * math:pi() let $sintwist := math:sin($twist) let $costwist := math:cos($twist) let $high := $twist > 2*math:pi() let $low := $twist < -2*math:pi() let $sinadd := if ($high) then $sintwist * (1 + $twist - 2*math:pi()) else if ($low) then $sintwist * (1 + $twist + 2*math:pi()) else $sintwist let $cosadd := if ($high) then $costwist * (1 + $twist - 2*math:pi()) else if ($low) then $costwist * (1 + $twist + 2*math:pi()) else $costwist return ( ann:f("mut:disc2", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $θ := math:atan2($y,$x) let $t := $rot * math:pi() * ($x + $y) let $r := $weight * $θ div math:pi() return ($r * (math:sin($t) + $cosadd), $r * (math:cos($t) + $sinadd)) }, ($weight, $parameters) ) ) }; declare function this:drift( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $dx1 as xs:numeric := $parameters("x.min") let $dy1 as xs:numeric := $parameters("y.min") let $dx2 as xs:numeric? := $parameters("x.max") let $dy2 as xs:numeric? := $parameters("y.max") let $x-range as map(xs:string,item()*) := if (empty($dx2) or $dx1=$dx2) then dist:constant($dx1) else dist:uniform($dx1, $dx2) let $y-range as map(xs:string,item()*) := if (empty($dy2) or $dy1=$dy2) then dist:constant($dy1) else dist:uniform($dy1, $dy2) return ( ann:f("mut:drift", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) + rand:randomize($x-range) let $y := v:py($pt) + rand:randomize($y-range) return ($weight * $x, $weight * $y) }, ($weight, $parameters) ) ) }; declare function this:crumple( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { ann:f("mut:crumple", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r := math:sqrt($x*$x + $y*$y) let $rfold := abs(0.5 - $r) let $θ := math:atan2($x,$y) return ( ($weight * $rfold * math:cos($θ), $weight * $rfold * math:sin($θ)) ) }, ($weight, $parameters) ) }; (: Default depth=0.5, shrink=1; invert that to get a flange :) declare function this:pillow( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $depth as xs:numeric := $parameters("depth") let $shrink as xs:numeric := $parameters("shrink") let $d2 as xs:numeric := $depth * $depth return ( ann:f("mut:pillow", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $r2 := abs($d2 - $x*$x + $y*$y) let $θ := math:atan2($x,$y) let $factor := $shrink div ($r2 + 1) return ( ($weight * $factor * $x, $weight * $factor * $y) ) }, ($weight, $parameters) ) ) }; declare function this:flowfield( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $noise as function(*) := $parameters("noise")=>noise:as-vector()=>f:function() let $step as xs:numeric := $parameters("step-size") return ( ann:f("mut:flowfield", function($pt as xs:double*) as xs:double* { let $θ := $noise($pt) * 180 + 180 return v:destination($pt, $θ, $step) }, ($weight, $parameters) ) ) }; declare function this:bipolar( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $extent := $parameters("extent") return ann:f("mut:bipolar", function($pt as xs:double*) as xs:double* { let $u := (v:px($pt) + 1) * math:pi() (: [-1,1]=>[0,2π) :) let $v := v:py($pt) * $extent (: [-1,1] => [-extent,extent] :) return coordinates:bipolar($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) }; declare function this:elliptic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $scale := $parameters("scale") return ann:f("mut:elliptic", function($pt as xs:double*) as xs:double* { let $u := (v:px($pt) + 1) * $scale (: [-1,1]=>[0,$scale] :) let $v := (v:py($pt) + 1) * math:pi() (: [-1,1]=>[0,2π] :) return coordinates:elliptic($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) }; declare function this:circular( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $scale := $parameters("scale") return ann:f("mut:circular", function($pt as xs:double*) as xs:double* { let $u := v:px($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) let $v := v:py($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) return coordinates:circular($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) }; declare function this:parabolic( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $scale := $parameters("scale") let $symmetric := $parameters("symmetric") return if ($symmetric) then ( ann:f("mut:parabolic", function($pt as xs:double*) as xs:double* { let $u := v:px($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) let $v := v:py($pt) * $scale (: [-1,1]=>[-$scale,$scale] :) return coordinates:parabolic($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) ) else ( ann:f("mut:parabolic", function($pt as xs:double*) as xs:double* { let $u := (v:px($pt) + 1) * $scale (: [-1,1]=>[0,$scale] :) let $v := (v:py($pt) + 1) * $scale (: [-1,1]=>[0,$scale] :) return coordinates:parabolic($u, $v)=>point:pcoordinates() }, ($weight, $parameters) ) ) }; (: Surface of a sphere :) declare function this:sphere( $weight as xs:double, $parameters as map(xs:string,item()*) ) as map(*) { let $radius := $parameters("radius") return ann:f("mut:sphere", function($pt as xs:double*) as xs:double* { let $x := v:px($pt) let $y := v:py($pt) let $latitude := math:asin($y div $radius) let $circle-radius := $radius * math:cos($latitude) let $sin-longitude := $x div $circle-radius let $longitude := math:asin($sin-longitude) + math:pi() div 2 return ( $weight * $longitude * $radius div math:pi(), $weight * $y ) }, ($weight, $parameters) ) };