# http://mathling.com/geometric/coordinates library module

http://mathling.com/geometric/coordinates

Coordinate system mappings

Copyright© Mary Holstege 2021-2023

CC-BY (https://creativecommons.org/licenses/by/4.0/)

Status: New

### Imports

http://mathling.com/core/utilitiesimport module namespace util="http://mathling.com/core/utilities" at "../core/utilities.xqy"http://mathling.com/geometric/curve

import module namespace curve="http://mathling.com/geometric/curve" at "../geo/curves.xqy"http://mathling.com/geometric/affine

import module namespace affine="http://mathling.com/geometric/affine" at "../geo/affine.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__: bipolar

declare function bipolar($u as xs:double,
$v as xs:double) as map(xs:string,item()*)

__Function__: bipolar

declare function bipolar($u as xs:double, $v as xs:double) as map(xs:string,item()*)

Bipolar coordinates

x = sinh(v) / (cosh(v) - cos(u))

y = sin(u) / (cosh(v) - cos(u))

for 0 <= u < 2π; -∞ < v < ∞

Make parametric in t; v=f(t) + c

##### Params

- u as xs:double
- v as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:bipolar( $u as xs:double, $v as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($v) - math:cos($u) let $x := util:sinh($v) div $divisor let $y := math:sin($u) div $divisor return ( point:point($x, $y) ) }

####
__Function__: bipolar

declare function bipolar($t as xs:double,
$f as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: bipolar

declare function bipolar($t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

Bipolar coordinates

x = a sinh(v) / (cosh(v) - cos(u))

y = a sin(u) / (cosh(v) - cos(u))

for 0 <= u < 2π; -∞ < v < ∞

Make parametric in u=t; v=f(t) + c

Which allows a nice sliced rendering via curve:multi-plot()

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:bipolar( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:bipolar($t, $f($t) + $c) }

####
__Function__: circular

declare function circular($u as xs:double,
$v as xs:double) as map(xs:string, item()*)

__Function__: circular

declare function circular($u as xs:double, $v as xs:double) as map(xs:string, item()*)

Circular coordinates:

Elliot Tanis and Lee Kuivinen, Circular Coordinates and Computer Drawn

Designs. Mathematics Magazine. Vol 52 No 3. May, 1979:

Coordinates with two perpendicular axes U and V where each point on the

axes is center of circle through origin; (u,v) is intersection of

circle whose center is at u on horizontal axis w/ circle whose center v

is on vertical axis.

(s,t) =>

s = g(u) = 2uv²/(u²+v²)

t = h(u) = 2u²v/(u²+v²)

##### Params

- u as xs:double
- v as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:circular( $u as xs:double, $v as xs:double ) as map(xs:string, item()*) { let $divisor := $u*$u + $v*$v let $x := (2*$u*$v*$v) div $divisor let $y := (2*$u*$u*$v) div $divisor return point:point($x, $y) }

####
__Function__: circular

declare function circular($t as xs:double,
$f as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: circular

declare function circular($t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

Circular coordinates:

Elliot Tanis and Lee Kuivinen, Circular Coordinates and Computer Drawn

Designs. Mathematics Magazine. Vol 52 No 3. May, 1979:

Coordinates with two perpendicular axes U and V where each point on the

axes is center of circle through origin; (u,v) is intersection of

circle whose center is at u on horizontal axis w/ circle whose center v

is on vertical axis.

(s,t) =>

s = g(u) = 2uv²/(u²+v²)

t = h(u) = 2u²v/(u²+v²)

Make parametric in t: u=t, v=f(t) + c

Which allows a nice sliced rendering, e.g.

curve:multi-plot(n-points, n-slices,

function($t, $c) { coord:circular($t, $f, $c) },

$t-extent, $t-symmetric,

$do-spline

)

https://www.johndcook.com/blog/2020/11/09/some-mathematical-art/

Given f(t) compute

x(t) = 2t(f(t))²/(t²+(f(t))²)

y(t) = 2t²f(t)/(t²+(f(t))²)

where f(t) = d(t) + c for x = -10, -9, -8 etc.

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:circular( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:circular($t, $f($t) + $c) }

####
__Function__: parabolic

declare function parabolic($u as xs:double,
$v as xs:double) as map(xs:string,item()*)

__Function__: parabolic

declare function parabolic($u as xs:double, $v as xs:double) as map(xs:string,item()*)

parabolic()

Parabolic coordinates

x = uv

y = 1/2(v² - u²)

##### Params

- u as xs:double
- v as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:parabolic( $u as xs:double, $v as xs:double ) as map(xs:string,item()*) { point:point( $u * $v, ($v*$v - $u*$u) div 2 ) }

####
__Function__: parabolic

declare function parabolic($t as xs:double,
$f as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: parabolic

declare function parabolic($t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:parabolic( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:parabolic($t, $f($t) + $c) }

####
__Function__: elliptic

declare function elliptic($u as xs:double,
$v as xs:double) as map(xs:string,item()*)

__Function__: elliptic

declare function elliptic($u as xs:double, $v as xs:double) as map(xs:string,item()*)

elliptic()

Elliptic coordinates

x = cosh u cos v

y = sinh u sin v

u >= 0, 0 <= v <= 2π

##### Params

- u as xs:double
- v as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:elliptic( $u as xs:double, $v as xs:double ) as map(xs:string,item()*) { point:point( util:cosh($u) * math:cos($v), util:sinh($u) * math:sin($v) ) }

####
__Function__: elliptic

declare function elliptic($t as xs:double,
$f as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: elliptic

declare function elliptic($t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:elliptic( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:elliptic($t, $f($t) + $c) }

####
__Function__: affine2

declare function affine2($u as xs:double,
$v as xs:double,
$matrix as xs:double*) as map(xs:string,item()*)

__Function__: affine2

declare function affine2($u as xs:double, $v as xs:double, $matrix as xs:double*) as map(xs:string,item()*)

affine2()

Affine coordinates

(x, y) = affine2((u, v))

##### Params

- u as xs:double
- v as xs:double
- matrix as xs:double*

##### Returns

- map(xs:string,item()*)

declare function this:affine2( $u as xs:double, $v as xs:double, $matrix as xs:double* (: 2D affine matrix :) ) as map(xs:string,item()*) { point:vector( affine:affine2(($u, $v), $matrix) ) }

####
__Function__: affine2

declare function affine2($t as xs:double,
$f as function(xs:double) as xs:double,
$c as xs:double,
$matrix as xs:double*) as map(xs:string,item()*)

__Function__: affine2

declare function affine2($t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double, $matrix as xs:double*) as map(xs:string,item()*)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- c as xs:double
- matrix as xs:double*

##### Returns

- map(xs:string,item()*)

declare function this:affine2( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double, $matrix as xs:double* ) as map(xs:string,item()*) { this:affine2($t, $f($t) + $c, $matrix) }

####
__Function__: curvilinear2

declare function curvilinear2($u as xs:double,
$v as xs:double,
$ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

__Function__: curvilinear2

declare function curvilinear2($u as xs:double, $v as xs:double, $ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

curvilinear2()

Curvilinear coordinates

##### Params

- u as xs:double
- v as xs:double
- ptmap as function(xs:double*)asxs:double*

##### Returns

- map(xs:string,item()*)

declare function this:curvilinear2( $u as xs:double, $v as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { point:vector( $ptmap(($u, $v)) ) }

####
__Function__: curvilinear2

declare function curvilinear2($t as xs:double,
$f as function(xs:double) as xs:double,
$c as xs:double,
$ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

__Function__: curvilinear2

declare function curvilinear2($t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double, $ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- c as xs:double
- ptmap as function(xs:double*)asxs:double*

##### Returns

- map(xs:string,item()*)

declare function this:curvilinear2( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { this:curvilinear2($t, $f($t) + $c, $ptmap) }

####
__Function__: bipolar-cylindrical

declare function bipolar-cylindrical($u as xs:double,
$v as xs:double,
$w as xs:double) as map(xs:string,item()*)

__Function__: bipolar-cylindrical

declare function bipolar-cylindrical($u as xs:double, $v as xs:double, $w as xs:double) as map(xs:string,item()*)

bipolar-cylindical()

x = sinh(v)/(cosh(v) - cos(u))

y = sin(u)/(cosh(v) - cos(u))

z = w

##### Params

- u as xs:double
- v as xs:double
- w as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:bipolar-cylindrical( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($v) - math:cos($u) return ( point:point( util:sinh($v) div $divisor, math:sin($u) div $divisor, $w ) ) }

####
__Function__: bipolar-cylindrical

declare function bipolar-cylindrical($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: bipolar-cylindrical

declare function bipolar-cylindrical($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

bipolar-cylindical()

Make parametric in t

u = t, v = f(t), w = g(t)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:bipolar-cylindrical( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:bipolar-cylindrical($t, $f($t) + $c, $g($t)) }

####
__Function__: bispherical

declare function bispherical($u as xs:double,
$v as xs:double,
$w as xs:double) as map(xs:string,item()*)

__Function__: bispherical

declare function bispherical($u as xs:double, $v as xs:double, $w as xs:double) as map(xs:string,item()*)

bispherical()

x = (sin(v)/(cosh(u)-cos(v)))*cos(w)

y = (sin(v)/(cosh(u)-cos(v)))*sin(w)

z = sinh(u)/(cosh(u)-cos(v)))

##### Params

- u as xs:double
- v as xs:double
- w as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:bispherical( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($u) - math:cos($v) return ( point:point( (math:sin($v) div $divisor)*math:cos($w), (math:sin($v) div $divisor)*math:sin($w), util:sinh($u) div $divisor ) ) }

####
__Function__: bispherical

declare function bispherical($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: bispherical

declare function bispherical($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

bispherical()

Make parametric in t

u = t, v = f(t), w = g(t)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:bispherical( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:bispherical($t, $f($t) + $c, $g($t)) }

####
__Function__: toroidal

declare function toroidal($u as xs:double,
$v as xs:double,
$w as xs:double) as map(xs:string,item()*)

__Function__: toroidal

declare function toroidal($u as xs:double, $v as xs:double, $w as xs:double) as map(xs:string,item()*)

toroidal()

x = (sinh(u)/(cosh(u)-cos(v)))*cos(w)

y = (sinh(u)/(cosh(u)-cos(v)))*sin(w)

z = sin(v)/(cosh(u)-cos(v))

##### Params

- u as xs:double
- v as xs:double
- w as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:toroidal( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($u) - math:cos($v) return ( point:point( (util:sinh($u) div $divisor)*math:cos($w), (util:sinh($u) div $divisor)*math:sin($w), math:sin($v) div $divisor ) ) }

####
__Function__: toroidal

declare function toroidal($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: toroidal

declare function toroidal($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

toroidal()

Make parametric in t

u = t, v = f(t), w = g(t)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:toroidal( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:toroidal($t, $f($t) + $c, $g($t)) }

####
__Function__: ellipsoidal

declare function ellipsoidal($u as xs:double,
$v as xs:double,
$w as xs:double,
$abc as xs:double*) as map(xs:string,item()*)

__Function__: ellipsoidal

declare function ellipsoidal($u as xs:double, $v as xs:double, $w as xs:double, $abc as xs:double*) as map(xs:string,item()*)

ellipsoidal()

x = a u sin(v)cos(w)

y = b u sin(v)sin(w)

z = c u cos(v)

u > 0; 0 <= v <= π; 0 <= w <= 2π

##### Params

- u as xs:double
- v as xs:double
- w as xs:double
- abc as xs:double*

##### Returns

- map(xs:string,item()*)

declare function this:ellipsoidal( $u as xs:double, $v as xs:double, $w as xs:double, $abc as xs:double* ) as map(xs:string,item()*) { let $ak := ($abc[1], 1)[1] let $bk := ($abc[2], 1)[1] let $ck := ($abc[3], 1)[1] return ( point:point( $ak * $u * math:sin($v) * math:cos($w), $bk * $u * math:sin($v) * math:sin($w), $ck * $u * math:cos($v) ) ) }

####
__Function__: ellipsoidal

declare function ellipsoidal($u as xs:double,
$v as xs:double,
$w as xs:double) as map(xs:string,item()*)

__Function__: ellipsoidal

declare function ellipsoidal($u as xs:double, $v as xs:double, $w as xs:double) as map(xs:string,item()*)

##### Params

- u as xs:double
- v as xs:double
- w as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:ellipsoidal( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { this:ellipsoidal($u, $v, $w, (1.0, 1.0, 1.0)) (: A unit sphere, actually :) }

####
__Function__: ellipsoidal

declare function ellipsoidal($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double,
$abc as xs:double*) as map(xs:string,item()*)

__Function__: ellipsoidal

declare function ellipsoidal($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $abc as xs:double*) as map(xs:string,item()*)

ellipsoidal()

Make parametric in t

u = t, v = f(t), w = g(t)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double
- abc as xs:double*

##### Returns

- map(xs:string,item()*)

declare function this:ellipsoidal( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $abc as xs:double* ) as map(xs:string,item()*) { this:ellipsoidal($t, $f($t) + $c, $g($t), $abc) }

####
__Function__: spherical

declare function spherical($u as xs:double,
$v as xs:double,
$w as xs:double) as map(xs:string,item()*)

__Function__: spherical

declare function spherical($u as xs:double, $v as xs:double, $w as xs:double) as map(xs:string,item()*)

spherical()

x = u sin(v)cos(w)

y = u sin(v)sin(w)

z = u cos(v)

u > 0; 0 <= v <= π; 0 <= w <= 2π

##### Params

- u as xs:double
- v as xs:double
- w as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:spherical( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { point:point( $u * math:sin($v) * math:cos($w), $u * math:sin($v) * math:sin($w), $u * math:cos($v) ) }

####
__Function__: spherical

declare function spherical($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double) as map(xs:string,item()*)

__Function__: spherical

declare function spherical($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double) as map(xs:string,item()*)

spherical()

Make parametric in t

u = t, v = f(t), w = g(t)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double

##### Returns

- map(xs:string,item()*)

declare function this:spherical( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:spherical($t, $f($t) + $c, $g($t)) }

####
__Function__: affine3

declare function affine3($u as xs:double,
$v as xs:double,
$w as xs:double,
$matrix as xs:double*) as map(xs:string,item()*)

__Function__: affine3

declare function affine3($u as xs:double, $v as xs:double, $w as xs:double, $matrix as xs:double*) as map(xs:string,item()*)

affine3()

Affine coordinates

(x, y) = affine((u, v))

##### Params

- u as xs:double
- v as xs:double
- w as xs:double
- matrix as xs:double*

##### Returns

- map(xs:string,item()*)

declare function this:affine3( $u as xs:double, $v as xs:double, $w as xs:double, $matrix as xs:double* (: 3D affine matrix :) ) as map(xs:string,item()*) { point:vector( affine:affine3(($u, $v, $w), $matrix) ) }

####
__Function__: affine3

declare function affine3($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double,
$matrix as xs:double*) as map(xs:string,item()*)

__Function__: affine3

declare function affine3($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $matrix as xs:double*) as map(xs:string,item()*)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double
- matrix as xs:double*

##### Returns

- map(xs:string,item()*)

declare function this:affine3( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $matrix as xs:double* ) as map(xs:string,item()*) { this:affine3($t, $f($t) + $c, $g($t), $matrix) }

####
__Function__: curvilinear3

declare function curvilinear3($u as xs:double,
$v as xs:double,
$w as xs:double,
$ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

__Function__: curvilinear3

declare function curvilinear3($u as xs:double, $v as xs:double, $w as xs:double, $ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

curvilinear3()

Curvilinear coordinates

##### Params

- u as xs:double
- v as xs:double
- w as xs:double
- ptmap as function(xs:double*)asxs:double*

##### Returns

- map(xs:string,item()*)

declare function this:curvilinear3( $u as xs:double, $v as xs:double, $w as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { point:vector( $ptmap(($u, $v, $w)) ) }

####
__Function__: curvilinear3

declare function curvilinear3($t as xs:double,
$f as function(xs:double) as xs:double,
$g as function(xs:double) as xs:double,
$c as xs:double,
$ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

__Function__: curvilinear3

declare function curvilinear3($t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $ptmap as function(xs:double*) as xs:double*) as map(xs:string,item()*)

##### Params

- t as xs:double
- f as function(xs:double)asxs:double
- g as function(xs:double)asxs:double
- c as xs:double
- ptmap as function(xs:double*)asxs:double*

##### Returns

- map(xs:string,item()*)

declare function this:curvilinear3( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { this:curvilinear3($t, $f($t) + $c, $g($t), $ptmap) }

####
__Function__: stereographic

declare function stereographic($pt as map(xs:string,item()*)*) as map(xs:string,item()*)

__Function__: stereographic

declare function stereographic($pt as map(xs:string,item()*)*) as map(xs:string,item()*)

stereographic()

Stereographic mapping from sphere to plane.

Point is expected to be on unit sphere, so you'll need to do some scaling

and translating. (See geom:stereographic())

##### Params

- pt as map(xs:string,item()*)*

##### Returns

- map(xs:string,item()*)

declare function this:stereographic( $pt as map(xs:string,item()*)* ) as map(xs:string,item()*) { point:point( point:px($pt) div (1 - point:pz($pt)), point:py($pt) div (1 - point:pz($pt)) ) }

####
__Function__: stereographic3D

declare function stereographic3D($pt as map(xs:string,item()*)*) as map(xs:string,item()*)

__Function__: stereographic3D

declare function stereographic3D($pt as map(xs:string,item()*)*) as map(xs:string,item()*)

stereographic3D()

Inverse stereographic mapping. Returns 3D point on unit sphere, so you'll

need to do some scaling and translating (see geom:stereographic3D())

##### Params

- pt as map(xs:string,item()*)*

##### Returns

- map(xs:string,item()*)

declare function this:stereographic3D( $pt as map(xs:string,item()*)* ) as map(xs:string,item()*) { let $divisor := 1 + point:px($pt)*point:px($pt) + point:py($pt)*point:py($pt) return point:point( 2 * point:px($pt) div $divisor, 2 * point:py($pt) div $divisor, (-1 + point:px($pt)*point:px($pt) + point:py($pt)*point:py($pt)) div $divisor ) }

### Original Source Code

xquery version "3.1"; (:~ : Coordinate system mappings : : Copyright© Mary Holstege 2021-2023 : CC-BY (https://creativecommons.org/licenses/by/4.0/) : @since December 2022 : @custom:Status New :) module namespace this="http://mathling.com/geometric/coordinates"; import module namespace config="http://mathling.com/core/config" at "../core/config.xqy"; import module namespace errors="http://mathling.com/core/errors" at "../core/errors.xqy"; import module namespace util="http://mathling.com/core/utilities" at "../core/utilities.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 curve="http://mathling.com/geometric/curve" at "../geo/curves.xqy"; 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"; (:~ : Bipolar coordinates : x = sinh(v) / (cosh(v) - cos(u)) : y = sin(u) / (cosh(v) - cos(u)) : for 0 <= u < 2π; -∞ < v < ∞ : Make parametric in t; v=f(t) + c :) declare function this:bipolar( $u as xs:double, $v as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($v) - math:cos($u) let $x := util:sinh($v) div $divisor let $y := math:sin($u) div $divisor return ( point:point($x, $y) ) }; (:~ : Bipolar coordinates : x = a sinh(v) / (cosh(v) - cos(u)) : y = a sin(u) / (cosh(v) - cos(u)) : for 0 <= u < 2π; -∞ < v < ∞ : Make parametric in u=t; v=f(t) + c : Which allows a nice sliced rendering via curve:multi-plot() :) declare function this:bipolar( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:bipolar($t, $f($t) + $c) }; (:~ : Circular coordinates: : Elliot Tanis and Lee Kuivinen, Circular Coordinates and Computer Drawn : Designs. Mathematics Magazine. Vol 52 No 3. May, 1979: : : Coordinates with two perpendicular axes U and V where each point on the : axes is center of circle through origin; (u,v) is intersection of : circle whose center is at u on horizontal axis w/ circle whose center v : is on vertical axis. : : (s,t) => : s = g(u) = 2uv²/(u²+v²) : t = h(u) = 2u²v/(u²+v²) :) declare function this:circular( $u as xs:double, $v as xs:double ) as map(xs:string, item()*) { let $divisor := $u*$u + $v*$v let $x := (2*$u*$v*$v) div $divisor let $y := (2*$u*$u*$v) div $divisor return point:point($x, $y) }; (:~ : Circular coordinates: : Elliot Tanis and Lee Kuivinen, Circular Coordinates and Computer Drawn : Designs. Mathematics Magazine. Vol 52 No 3. May, 1979: : : Coordinates with two perpendicular axes U and V where each point on the : axes is center of circle through origin; (u,v) is intersection of : circle whose center is at u on horizontal axis w/ circle whose center v : is on vertical axis. : : (s,t) => : s = g(u) = 2uv²/(u²+v²) : t = h(u) = 2u²v/(u²+v²) : Make parametric in t: u=t, v=f(t) + c : Which allows a nice sliced rendering, e.g. : curve:multi-plot(n-points, n-slices, : function($t, $c) { coord:circular($t, $f, $c) }, : $t-extent, $t-symmetric, : $do-spline : ) : : https://www.johndcook.com/blog/2020/11/09/some-mathematical-art/ : Given f(t) compute : x(t) = 2t(f(t))²/(t²+(f(t))²) : y(t) = 2t²f(t)/(t²+(f(t))²) : where f(t) = d(t) + c for x = -10, -9, -8 etc. :) declare function this:circular( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:circular($t, $f($t) + $c) }; (:~ : parabolic() : Parabolic coordinates : x = uv : y = 1/2(v² - u²) :) declare function this:parabolic( $u as xs:double, $v as xs:double ) as map(xs:string,item()*) { point:point( $u * $v, ($v*$v - $u*$u) div 2 ) }; declare function this:parabolic( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:parabolic($t, $f($t) + $c) }; (:~ : elliptic() : Elliptic coordinates : x = cosh u cos v : y = sinh u sin v : u >= 0, 0 <= v <= 2π :) declare function this:elliptic( $u as xs:double, $v as xs:double ) as map(xs:string,item()*) { point:point( util:cosh($u) * math:cos($v), util:sinh($u) * math:sin($v) ) }; declare function this:elliptic( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:elliptic($t, $f($t) + $c) }; (:~ : affine2() : Affine coordinates : (x, y) = affine2((u, v)) :) declare function this:affine2( $u as xs:double, $v as xs:double, $matrix as xs:double* (: 2D affine matrix :) ) as map(xs:string,item()*) { point:vector( affine:affine2(($u, $v), $matrix) ) }; declare function this:affine2( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double, $matrix as xs:double* ) as map(xs:string,item()*) { this:affine2($t, $f($t) + $c, $matrix) }; (:~ : curvilinear2() : Curvilinear coordinates :) declare function this:curvilinear2( $u as xs:double, $v as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { point:vector( $ptmap(($u, $v)) ) }; declare function this:curvilinear2( $t as xs:double, $f as function(xs:double) as xs:double, $c as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { this:curvilinear2($t, $f($t) + $c, $ptmap) }; (:=== 3D ===:) (:~ : bipolar-cylindical() : x = sinh(v)/(cosh(v) - cos(u)) : y = sin(u)/(cosh(v) - cos(u)) : z = w :) declare function this:bipolar-cylindrical( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($v) - math:cos($u) return ( point:point( util:sinh($v) div $divisor, math:sin($u) div $divisor, $w ) ) }; (:~ : bipolar-cylindical() : Make parametric in t : u = t, v = f(t), w = g(t) :) declare function this:bipolar-cylindrical( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:bipolar-cylindrical($t, $f($t) + $c, $g($t)) }; (:~ : bispherical() : x = (sin(v)/(cosh(u)-cos(v)))*cos(w) : y = (sin(v)/(cosh(u)-cos(v)))*sin(w) : z = sinh(u)/(cosh(u)-cos(v))) :) declare function this:bispherical( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($u) - math:cos($v) return ( point:point( (math:sin($v) div $divisor)*math:cos($w), (math:sin($v) div $divisor)*math:sin($w), util:sinh($u) div $divisor ) ) }; (:~ : bispherical() : Make parametric in t : u = t, v = f(t), w = g(t) :) declare function this:bispherical( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:bispherical($t, $f($t) + $c, $g($t)) }; (:~ : toroidal() : x = (sinh(u)/(cosh(u)-cos(v)))*cos(w) : y = (sinh(u)/(cosh(u)-cos(v)))*sin(w) : z = sin(v)/(cosh(u)-cos(v)) :) declare function this:toroidal( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { let $divisor := util:cosh($u) - math:cos($v) return ( point:point( (util:sinh($u) div $divisor)*math:cos($w), (util:sinh($u) div $divisor)*math:sin($w), math:sin($v) div $divisor ) ) }; (:~ : toroidal() : Make parametric in t : u = t, v = f(t), w = g(t) :) declare function this:toroidal( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:toroidal($t, $f($t) + $c, $g($t)) }; (:~ : ellipsoidal() : x = a u sin(v)cos(w) : y = b u sin(v)sin(w) : z = c u cos(v) : u > 0; 0 <= v <= π; 0 <= w <= 2π :) declare function this:ellipsoidal( $u as xs:double, $v as xs:double, $w as xs:double, $abc as xs:double* ) as map(xs:string,item()*) { let $ak := ($abc[1], 1)[1] let $bk := ($abc[2], 1)[1] let $ck := ($abc[3], 1)[1] return ( point:point( $ak * $u * math:sin($v) * math:cos($w), $bk * $u * math:sin($v) * math:sin($w), $ck * $u * math:cos($v) ) ) }; declare function this:ellipsoidal( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { this:ellipsoidal($u, $v, $w, (1.0, 1.0, 1.0)) (: A unit sphere, actually :) }; (:~ : ellipsoidal() : Make parametric in t : u = t, v = f(t), w = g(t) :) declare function this:ellipsoidal( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $abc as xs:double* ) as map(xs:string,item()*) { this:ellipsoidal($t, $f($t) + $c, $g($t), $abc) }; (:~ : spherical() : x = u sin(v)cos(w) : y = u sin(v)sin(w) : z = u cos(v) : u > 0; 0 <= v <= π; 0 <= w <= 2π :) declare function this:spherical( $u as xs:double, $v as xs:double, $w as xs:double ) as map(xs:string,item()*) { point:point( $u * math:sin($v) * math:cos($w), $u * math:sin($v) * math:sin($w), $u * math:cos($v) ) }; (:~ : spherical() : Make parametric in t : u = t, v = f(t), w = g(t) :) declare function this:spherical( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double ) as map(xs:string,item()*) { this:spherical($t, $f($t) + $c, $g($t)) }; (:~ : affine3() : Affine coordinates : (x, y) = affine((u, v)) :) declare function this:affine3( $u as xs:double, $v as xs:double, $w as xs:double, $matrix as xs:double* (: 3D affine matrix :) ) as map(xs:string,item()*) { point:vector( affine:affine3(($u, $v, $w), $matrix) ) }; declare function this:affine3( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $matrix as xs:double* ) as map(xs:string,item()*) { this:affine3($t, $f($t) + $c, $g($t), $matrix) }; (:~ : curvilinear3() : Curvilinear coordinates :) declare function this:curvilinear3( $u as xs:double, $v as xs:double, $w as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { point:vector( $ptmap(($u, $v, $w)) ) }; declare function this:curvilinear3( $t as xs:double, $f as function(xs:double) as xs:double, $g as function(xs:double) as xs:double, $c as xs:double, $ptmap as function(xs:double*) as xs:double* ) as map(xs:string,item()*) { this:curvilinear3($t, $f($t) + $c, $g($t), $ptmap) }; (: 2D <=> 3D :) (:~ : stereographic() : Stereographic mapping from sphere to plane. : Point is expected to be on unit sphere, so you'll need to do some scaling : and translating. (See geom:stereographic()) :) declare function this:stereographic( $pt as map(xs:string,item()*)* ) as map(xs:string,item()*) { point:point( point:px($pt) div (1 - point:pz($pt)), point:py($pt) div (1 - point:pz($pt)) ) }; (:~ : stereographic3D() : Inverse stereographic mapping. Returns 3D point on unit sphere, so you'll : need to do some scaling and translating (see geom:stereographic3D()) :) declare function this:stereographic3D( $pt as map(xs:string,item()*)* ) as map(xs:string,item()*) { let $divisor := 1 + point:px($pt)*point:px($pt) + point:py($pt)*point:py($pt) return point:point( 2 * point:px($pt) div $divisor, 2 * point:py($pt) div $divisor, (-1 + point:px($pt)*point:px($pt) + point:py($pt)*point:py($pt)) div $divisor ) };