http://mathling.com/shape library module
http://mathling.com/shape
Common shape operations.
Copyright© Mary Holstege 2022-2023
CC-BY (https://creativecommons.org/licenses/by/4.0/)
Status: Active
Imports
http://mathling.com/core/utilitiesimport module namespace util="http://mathling.com/core/utilities" at "../core/utilities.xqy"http://mathling.com/geometric/rectangle
import module namespace box="http://mathling.com/geometric/rectangle" at "../geo/rectangle.xqy"http://mathling.com/geometric
import module namespace geom="http://mathling.com/geometric" at "../geo/euclidean.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"http://mathling.com/geometric/point
import module namespace point="http://mathling.com/geometric/point" at "../geo/point.xqy"
Functions
Function: scale-and-center
declare function scale-and-center($shapes as map(xs:string,item()*)*,
$canvas as map(xs:string,item()*)) as map(xs:string,item()*)*
declare function scale-and-center($shapes as map(xs:string,item()*)*, $canvas as map(xs:string,item()*)) as map(xs:string,item()*)*
scale-and-center()
Scale the shapes and center them in the canvas so that they fill it.
You may need to snap or decimalize the results.
Params
- shapes as map(xs:string,item()*)*: sequence of shapes
- canvas as map(xs:string,item()*): space to fill
Returns
- map(xs:string,item()*)*: the scaled and shifted shapes
declare function this:scale-and-center( $shapes as map(xs:string,item()*)*, $canvas as map(xs:string,item()*) ) as map(xs:string,item()*)* { let $ccenter := box:center($canvas) let $bb := geom:bounding-box(geom:vertices($shapes)) let $center := box:center($bb) let $scaling := min(( box:width($canvas) div box:width($bb), box:height($canvas) div box:height($bb) )) return ( $shapes=>geom:mutate( function ($pt as map(xs:string,item()*)) as map(xs:string,item()*) { $pt=> geom:translate(-point:px($center),-point:py($center))=> geom:scale($scaling)=> geom:translate(point:px($ccenter), point:py($ccenter)) } ) ) }
Function: center
declare function center($shapes as map(xs:string,item()*)*,
$canvas as map(xs:string,item()*)) as map(xs:string,item()*)*
declare function center($shapes as map(xs:string,item()*)*, $canvas as map(xs:string,item()*)) as map(xs:string,item()*)*
center()
Center the shapes in the canvas without scaling.
You may need to snap or decimalize the results.
Params
- shapes as map(xs:string,item()*)*: sequence of shapes
- canvas as map(xs:string,item()*): space in which to center
Returns
- map(xs:string,item()*)*: the shifted shapes
declare function this:center( $shapes as map(xs:string,item()*)*, $canvas as map(xs:string,item()*) ) as map(xs:string,item()*)* { let $ccenter := box:center($canvas) let $bb := geom:bounding-box(geom:vertices($shapes)) let $center := box:center($bb) return ( $shapes=>geom:translate( point:px($ccenter) - point:px($center), point:py($ccenter) - point:py($center) ) ) }
Original Source Code
xquery version "3.1"; (:~ : Common shape operations. : : Copyright© Mary Holstege 2022-2023 : CC-BY (https://creativecommons.org/licenses/by/4.0/) : @since June 2023 : @custom:Status Active :) module namespace this="http://mathling.com/shape"; import module namespace errors="http://mathling.com/core/errors" at "../core/errors.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 geom="http://mathling.com/geometric" at "../geo/euclidean.xqy"; import module namespace point="http://mathling.com/geometric/point" at "../geo/point.xqy"; import module namespace box="http://mathling.com/geometric/rectangle" at "../geo/rectangle.xqy"; declare namespace svg="http://www.w3.org/2000/svg"; 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"; (:~ : scale-and-center() : Scale the shapes and center them in the canvas so that they fill it. : You may need to snap or decimalize the results. : : @param $shapes: sequence of shapes : @param $canvas: space to fill : @return the scaled and shifted shapes :) declare function this:scale-and-center( $shapes as map(xs:string,item()*)*, $canvas as map(xs:string,item()*) ) as map(xs:string,item()*)* { let $ccenter := box:center($canvas) let $bb := geom:bounding-box(geom:vertices($shapes)) let $center := box:center($bb) let $scaling := min(( box:width($canvas) div box:width($bb), box:height($canvas) div box:height($bb) )) return ( $shapes=>geom:mutate( function ($pt as map(xs:string,item()*)) as map(xs:string,item()*) { $pt=> geom:translate(-point:px($center),-point:py($center))=> geom:scale($scaling)=> geom:translate(point:px($ccenter), point:py($ccenter)) } ) ) }; (:~ : center() : Center the shapes in the canvas without scaling. : You may need to snap or decimalize the results. : : @param $shapes: sequence of shapes : @param $canvas: space in which to center : @return the shifted shapes :) declare function this:center( $shapes as map(xs:string,item()*)*, $canvas as map(xs:string,item()*) ) as map(xs:string,item()*)* { let $ccenter := box:center($canvas) let $bb := geom:bounding-box(geom:vertices($shapes)) let $center := box:center($bb) return ( $shapes=>geom:translate( point:px($ccenter) - point:px($center), point:py($ccenter) - point:py($center) ) ) };