| Author | Dave Jarvis <email> |
|---|---|
| Date | 2014-08-24 23:41:58 GMT-0700 |
| Commit | bdbae1dbb9923877f4dc3e8444c9495c4bc99cdf |
| Parent | 5150f7b |
| Delta | 459 lines added, 147 lines removed, 312-line increase |
|---|
| <xsl:include href="math.xsl"/> | ||
| - | ||
| -<!-- Pie wedge colours based on this hue. --> | ||
| -<xsl:variable name="base_colour" select="'46A5E5'"/> | ||
| - | ||
| -<!-- Pie wedge stroke colour. --> | ||
| -<xsl:variable name="stroke_colour" select="'white'"/> | ||
| +<xsl:include href="colour.xsl"/> | ||
| <!-- Pie chart width and height. --> | ||
| transform="translate({$radius},{$radius})" | ||
| d="M 0 0 L {$x1r} {$y1r} A {$r} {$r} 0 {$sweep} 0 {$x2r} {$y2r} Z"/> | ||
| -</xsl:template> | ||
| - | ||
| -<!-- | ||
| - | Creates a colour for a particular pie wedge. | ||
| - | | ||
| - | http://en.wikipedia.org/wiki/HSL_and_HSV | ||
| - +--> | ||
| -<xsl:template name="fill"> | ||
| - <!-- Current wedge number for generating a colour. --> | ||
| - <xsl:param name="wedge"/> | ||
| - <!-- Total number of wedges in the pie. --> | ||
| - <xsl:param name="wedges"/> | ||
| - <!-- RGB colour in hexadecimal. --> | ||
| - <xsl:param name="colour"/> | ||
| - | ||
| - <!-- Derive the colour decimal values from $colour's HEX code. --> | ||
| - <xsl:variable name="r"> | ||
| - <xsl:call-template name="hex2dec"> | ||
| - <xsl:with-param name="hex" | ||
| - select="substring( $colour, 1, 2 )"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - <xsl:variable name="g"> | ||
| - <xsl:call-template name="hex2dec"> | ||
| - <xsl:with-param name="hex" | ||
| - select="substring( $colour, 3, 2 )"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - <xsl:variable name="b"> | ||
| - <xsl:call-template name="hex2dec"> | ||
| - <xsl:with-param name="hex" | ||
| - select="substring( $colour, 5, 2 )"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - | ||
| - <xsl:variable name="alpha" | ||
| - select="(2 * $r - $g - $b) * 0.5"/> | ||
| - <xsl:variable name="beta" | ||
| - select="0.86602540378 * ($g - $b)"/> | ||
| - | ||
| - <xsl:variable name="base_hue"> | ||
| - <xsl:call-template name="atan2"> | ||
| - <xsl:with-param name="x" select="$alpha"/> | ||
| - <xsl:with-param name="y" select="$beta"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - | ||
| - <xsl:variable name="chroma"> | ||
| - <xsl:call-template name="sqrt"> | ||
| - <xsl:with-param name="n" | ||
| - select="($alpha * $alpha) + ($beta * $beta)"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - | ||
| - <xsl:variable name="value"> | ||
| - <xsl:variable name="max_rg"> | ||
| - <xsl:call-template name="max"> | ||
| - <xsl:with-param name="a" select="$r"/> | ||
| - <xsl:with-param name="b" select="$g"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - <xsl:variable name="max_gb"> | ||
| - <xsl:call-template name="max"> | ||
| - <xsl:with-param name="a" select="$g"/> | ||
| - <xsl:with-param name="b" select="$b"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - <xsl:call-template name="max"> | ||
| - <xsl:with-param name="a" select="$max_rg"/> | ||
| - <xsl:with-param name="b" select="$max_gb"/> | ||
| - </xsl:call-template> | ||
| - </xsl:variable> | ||
| - | ||
| - <!-- Calculate the wedge hue from the base colour. --> | ||
| - <xsl:variable name="h_rotate" | ||
| - select="($base_hue + ((240 div $wedges) * $wedge) mod 240)"/> | ||
| - <xsl:variable name="h_prime" | ||
| - select="$h_rotate div 60.0"/> | ||
| - <xsl:variable name="h_mod" | ||
| - select="$h_prime mod 2 - 1"/> | ||
| - <xsl:variable name="h_abs" | ||
| - select="($h_mod >= 0) * $h_mod - not($h_mod >= 0) * $h_mod"/> | ||
| - | ||
| - <xsl:variable name="c" select="$chroma"/> | ||
| - <xsl:variable name="x" select="$c * (1 - $h_abs)"/> | ||
| - <xsl:variable name="m" select="$value - $c"/> | ||
| - | ||
| - <xsl:variable name="cm" select="round( $c + $m )"/> | ||
| - <xsl:variable name="xm" select="round( $x + $m )"/> | ||
| - <xsl:variable name="zm" select="round( 0 + $m )"/> | ||
| - | ||
| - <xsl:text>rgb(</xsl:text> | ||
| - <xsl:choose> | ||
| - <xsl:when test="0 <= $h_prime and $h_prime < 1"> | ||
| - <xsl:value-of select="concat( $cm, ',', $xm, ',', $zm )"/> | ||
| - </xsl:when> | ||
| - <xsl:when test="1 <= $h_prime and $h_prime < 2"> | ||
| - <xsl:value-of select="concat( $xm, ',', $cm, ',', $zm )"/> | ||
| - </xsl:when> | ||
| - <xsl:when test="2 <= $h_prime and $h_prime < 3"> | ||
| - <xsl:value-of select="concat( $zm, ',', $cm, ',', $xm )"/> | ||
| - </xsl:when> | ||
| - <xsl:when test="3 <= $h_prime and $h_prime < 4"> | ||
| - <xsl:value-of select="concat( $zm, ',', $xm, ',', $cm )"/> | ||
| - </xsl:when> | ||
| - <xsl:when test="4 <= $h_prime and $h_prime < 5"> | ||
| - <xsl:value-of select="concat( $xm, ',', $zm, ',', $cm )"/> | ||
| - </xsl:when> | ||
| - <xsl:when test="5 <= $h_prime and $h_prime < 6"> | ||
| - <xsl:value-of select="concat( $cm, ',', $zm, ',', $xm )"/> | ||
| - </xsl:when> | ||
| - <xsl:otherwise> | ||
| - <xsl:value-of select="concat( $r, ',', $g, ',', $b )"/> | ||
| - </xsl:otherwise> | ||
| - </xsl:choose> | ||
| - <xsl:text>)</xsl:text> | ||
| </xsl:template> | ||
| +<?xml version="1.0"?> | ||
| +<!-- | ||
| + | The MIT License | ||
| + | | ||
| + | Copyright 2014 White Magic Software, Inc. | ||
| + | | ||
| + | Permission is hereby granted, free of charge, to any person | ||
| + | obtaining a copy of this software and associated documentation | ||
| + | files (the "Software"), to deal in the Software without | ||
| + | restriction, including without limitation the rights to use, | ||
| + | copy, modify, merge, publish, distribute, sublicense, and/or | ||
| + | sell copies of the Software, and to permit persons to whom the | ||
| + | Software is furnished to do so, subject to the following | ||
| + | conditions: | ||
| + | | ||
| + | The above copyright notice and this permission notice shall be | ||
| + | included in all copies or substantial portions of the Software. | ||
| + | | ||
| + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| + | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
| + | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| + | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| + | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
| + | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| + | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| + | OTHER DEALINGS IN THE SOFTWARE. | ||
| + +--> | ||
| +<xsl:stylesheet version="1.0" | ||
| + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | ||
| + | ||
| +<!-- Reference white (X, Y, and Z components) --> | ||
| +<xsl:variable name="X_r" select="0.950456"/> | ||
| +<xsl:variable name="Y_r" select="1.000000"/> | ||
| +<xsl:variable name="Z_r" select="1.088754"/> | ||
| +<xsl:variable name="LAB_EPSILON" select="216.0 div 24389.0"/> | ||
| +<xsl:variable name="LAB_K" select="24389.0 div 27.0"/> | ||
| + | ||
| +<!-- Pie wedge colours based on this hue. --> | ||
| +<xsl:variable name="base_colour" select="'46A5E5'"/> | ||
| + | ||
| +<!-- Pie wedge stroke colour. --> | ||
| +<xsl:variable name="stroke_colour" select="'white'"/> | ||
| + | ||
| +<!-- | ||
| + | Creates a colour for a particular pie wedge. | ||
| + | | ||
| + | http://en.wikipedia.org/wiki/HSL_and_HSV | ||
| + +--> | ||
| +<xsl:template name="fill"> | ||
| + <!-- Current wedge number for generating a colour. --> | ||
| + <xsl:param name="wedge"/> | ||
| + <!-- Total number of wedges in the pie. --> | ||
| + <xsl:param name="wedges"/> | ||
| + <!-- RGB colour in hexadecimal. --> | ||
| + <xsl:param name="colour"/> | ||
| + | ||
| + <!-- Derive the colour decimal values from $colour's HEX code. --> | ||
| + <xsl:variable name="r"> | ||
| + <xsl:call-template name="hex2dec"> | ||
| + <xsl:with-param name="hex" | ||
| + select="substring( $colour, 1, 2 )"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="g"> | ||
| + <xsl:call-template name="hex2dec"> | ||
| + <xsl:with-param name="hex" | ||
| + select="substring( $colour, 3, 2 )"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="b"> | ||
| + <xsl:call-template name="hex2dec"> | ||
| + <xsl:with-param name="hex" | ||
| + select="substring( $colour, 5, 2 )"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <!-- | ||
| + | Convert RGB to XYZ, using nominal range for RGB. | ||
| + | http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html | ||
| + +--> | ||
| + <xsl:variable name="r_n" select="$r div 255" /> | ||
| + <xsl:variable name="g_n" select="$g div 255" /> | ||
| + <xsl:variable name="b_n" select="$b div 255" /> | ||
| + | ||
| + <!-- | ||
| + | Assume colours are in sRGB. | ||
| + | http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html | ||
| + --> | ||
| + <xsl:variable name="x" | ||
| + select=".4124564 * $r_n + .3575761 * $g_n + .1804375 * $b_n"/> | ||
| + <xsl:variable name="y" | ||
| + select=".2126729 * $r_n + .7151522 * $g_n + .0721750 * $b_n"/> | ||
| + <xsl:variable name="z" | ||
| + select=".0193339 * $r_n + .1191920 * $g_n + .9503041 * $b_n"/> | ||
| + | ||
| + <!-- | ||
| + | Convert XYZ to L*a*b. | ||
| + | http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html | ||
| + +--> | ||
| + <xsl:variable name="if_x"> | ||
| + <xsl:call-template name="lab_f"> | ||
| + <xsl:with-param name="xyz_n" select="$x div $X_r"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="if_y"> | ||
| + <xsl:call-template name="lab_f"> | ||
| + <xsl:with-param name="xyz_n" select="$y div $Y_r"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="if_z"> | ||
| + <xsl:call-template name="lab_f"> | ||
| + <xsl:with-param name="xyz_n" select="$z div $Z_r"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="lab_l" select="(116.0 * $if_y) - 16.0"/> | ||
| + <xsl:variable name="lab_a" select="500.0 * ($if_x - $if_y)"/> | ||
| + <xsl:variable name="lab_b" select="200.0 * ($if_y - $if_z)"/> | ||
| + | ||
| + <!-- | ||
| + | Convert L*a*b to LCH. | ||
| + +--> | ||
| + <xsl:variable name="lch_l" select="$lab_l"/> | ||
| + | ||
| + <xsl:variable name="lch_c"> | ||
| + <xsl:call-template name="sqrt"> | ||
| + <xsl:with-param name="n" select="($lab_a * $lab_a) + ($lab_b * $lab_b)"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="lch_h"> | ||
| + <xsl:call-template name="atan2"> | ||
| + <xsl:with-param name="x" select="$lab_b"/> | ||
| + <xsl:with-param name="y" select="$lab_a"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <!-- lch_l, lch_c, and lch_h are now set; rotate the hue. --> | ||
| + <xsl:variable name="lch_wedge_h" select="(360.0 div $wedges) * $wedge"/> | ||
| + | ||
| + <!-- | ||
| + | Convert wedge's hue-adjusted LCH to L*a*b. | ||
| + | http://www.brucelindbloom.com/index.html?Eqn_LCH_to_Lab.html | ||
| + +--> | ||
| + <xsl:variable name="lab_sin_h"> | ||
| + <xsl:call-template name="sine"> | ||
| + <xsl:with-param name="degrees" select="$lch_wedge_h"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="lab_cos_h"> | ||
| + <xsl:call-template name="cosine"> | ||
| + <xsl:with-param name="degrees" select="$lch_wedge_h"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="final_lab_l" select="$lch_l"/> | ||
| + <xsl:variable name="final_lab_a" select="$lch_c * $lab_cos_h"/> | ||
| + <xsl:variable name="final_lab_b" select="$lch_c * $lab_sin_h"/> | ||
| + | ||
| + <!-- | ||
| + | Convert L*a*b to XYZ. | ||
| + | http://www.brucelindbloom.com/index.html?Eqn_Lab_to_XYZ.html | ||
| + +--> | ||
| + <xsl:variable name="of_y" select="($final_lab_l + 16.0) div 116.0"/> | ||
| + <xsl:variable name="of_x" select="($final_lab_a div 500.0) + $of_y"/> | ||
| + <xsl:variable name="of_z" select="$of_y - ($final_lab_b div 200.0)"/> | ||
| + | ||
| + <xsl:variable name="of_x_pow"> | ||
| + <xsl:call-template name="power"> | ||
| + <xsl:with-param name="base" select="$of_x"/> | ||
| + <xsl:with-param name="exponent" select="3"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="of_z_pow"> | ||
| + <xsl:call-template name="power"> | ||
| + <xsl:with-param name="base" select="$of_z"/> | ||
| + <xsl:with-param name="exponent" select="3"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="ox_r"> | ||
| + <xsl:choose> | ||
| + <xsl:when test="$of_x_pow > $LAB_EPSILON"> | ||
| + <xsl:value-of select="$of_x_pow"/> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:value-of select="((116.0 * $of_x) - 16.0) div $LAB_K"/> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="oy_r"> | ||
| + <xsl:choose> | ||
| + <xsl:when test="$final_lab_l > ($LAB_K * $LAB_EPSILON)"> | ||
| + <xsl:call-template name="power"> | ||
| + <xsl:with-param name="base" | ||
| + select="($final_lab_l + 16.0) div 116.0"/> | ||
| + <xsl:with-param name="exponent" | ||
| + select="3"/> | ||
| + </xsl:call-template> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:value-of select="$final_lab_l div $LAB_K"/> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| + </xsl:variable> | ||
| + <xsl:variable name="oz_r"> | ||
| + <xsl:choose> | ||
| + <xsl:when test="$of_z_pow > $LAB_EPSILON"> | ||
| + <xsl:value-of select="$of_z_pow"/> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:value-of select="((116.0 * $of_z) - 16.0) div $LAB_K"/> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="X" select="$ox_r * $X_r"/> | ||
| + <xsl:variable name="Y" select="$oy_r * $Y_r"/> | ||
| + <xsl:variable name="Z" select="$oz_r * $Z_r"/> | ||
| + | ||
| + <!-- | ||
| + | Convert XYZ to sRGB. | ||
| + | | ||
| + | http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html | ||
| + +--> | ||
| + <xsl:variable name="R" | ||
| + select="3.2404542 * $X + -1.5371385 * $Y + -0.4985314 * $Z"/> | ||
| + <xsl:variable name="G" | ||
| + select="-0.9692660 * $X + 1.8760108 * $Y + 0.0415560 * $Z"/> | ||
| + <xsl:variable name="B" | ||
| + select="0.0556434 * $X + -0.2040259 * $Y + 1.0572252 * $Z"/> | ||
| + | ||
| + <!-- Round the result. --> | ||
| + <xsl:variable name="R_r" select="round( $R * 255 )"/> | ||
| + <xsl:variable name="G_r" select="round( $G * 255 )"/> | ||
| + <xsl:variable name="B_r" select="round( $B * 255 )"/> | ||
| + | ||
| + <xsl:text>rgb(</xsl:text> | ||
| + <xsl:value-of select="concat( $R_r, ',', $G_r, ',', $B_r )"/> | ||
| + <xsl:text>)</xsl:text> | ||
| +</xsl:template> | ||
| + | ||
| +<xsl:template name="lab_f"> | ||
| + <xsl:param name="xyz_n"/> | ||
| + | ||
| + <xsl:choose> | ||
| + <xsl:when test="$xyz_n > $LAB_EPSILON"> | ||
| + <xsl:call-template name="nthroot"> | ||
| + <xsl:with-param name="index" select="3"/> | ||
| + <xsl:with-param name="radicand" select="$xyz_n"/> | ||
| + </xsl:call-template> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:value-of select="($LAB_K * $xyz_n + 16.0) div 116.0" /> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Returns $x, ensuring $x is between -100 and 100. --> | ||
| +<xsl:template name="constrain"> | ||
| + <xsl:param name="x"/> | ||
| + <xsl:param name="max" select="100"/> | ||
| + <xsl:choose> | ||
| + <xsl:when test="$x > $max"> | ||
| + <xsl:value-of select="$max"/> | ||
| + </xsl:when> | ||
| + <xsl:when test="$x < -$max"> | ||
| + <xsl:value-of select="-$max"/> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:value-of select="$x"/> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Converts a two-digit hexadecimal number to decimal. --> | ||
| +<xsl:template name="hex2dec"> | ||
| + <xsl:param name="hex"/> | ||
| + | ||
| + <xsl:variable name="digits" select="'0123456789ABCDEF'"/> | ||
| + <xsl:variable name="X" select="substring( $hex, 1, 1 )"/> | ||
| + <xsl:variable name="Y" select="substring( $hex, 2, 1 )"/> | ||
| + <xsl:variable name="Xval" | ||
| + select="string-length(substring-before($digits,$X))"/> | ||
| + <xsl:variable name="Yval" | ||
| + select="string-length(substring-before($digits,$Y))"/> | ||
| + <xsl:value-of select="16 * $Xval + $Yval"/> | ||
| +</xsl:template> | ||
| + | ||
| +</xsl:stylesheet> | ||
| xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | ||
| -<xsl:variable name="PI">3.14159265358979323846</xsl:variable> | ||
| +<xsl:variable name="PI">3.14159265358979323846264338327950</xsl:variable> | ||
| +<xsl:variable name="PHI">1.61803398874989484820458683436564</xsl:variable> | ||
| +<xsl:variable name="PIDIV2" select="$PI div 2.0"/> | ||
| +<xsl:variable name="ROOT_PRECISION" select="0.00001"/> | ||
| -<!-- Find the square root of a number (n). --> | ||
| +<!-- Calculates square root of n. --> | ||
| <xsl:template name="sqrt"> | ||
| <!-- Number to root. --> | ||
| <xsl:param name="n" select="0"/> | ||
| <!-- Used internally. --> | ||
| <xsl:param name="try" select="1"/> | ||
| <!-- Maximum number of iterations (decreases recursively). --> | ||
| - <xsl:param name="iter" select="20"/> | ||
| + <xsl:param name="iter" select="17"/> | ||
| <!-- Nate Austin's implementation using Newton's method --> | ||
| <!-- | ||
| - | Calculates sin(x) using: | ||
| + | Calculates sin(x) as: | ||
| | x(1 - (x^2/2*3)(1 - (x^2/4*5)(1 - (x^2/6*7)))) | ||
| + | https://www.wolframalpha.com/input/?i=expand+sin(x) | ||
| +--> | ||
| <xsl:template name="sine"> | ||
| <!-- Degrees (should be between 0 and 360). --> | ||
| <xsl:param name="degrees"/> | ||
| - <!-- Used internally to convert degrees to radians. --> | ||
| + <!-- Convert degrees to radians when degrees are used. --> | ||
| <xsl:param name="rad" select="$degrees * $PI div 180"/> | ||
| <!-- Maximum number of iterations (decreases recursively). --> | ||
| </xsl:template> | ||
| -<!-- Calculates the normalized arc tangent form. --> | ||
| +<!-- | ||
| + | Calculates cos(x) as: | ||
| + | sine($PIDIV2 - $rad) | ||
| + +--> | ||
| +<xsl:template name="cosine"> | ||
| + <!-- Degrees (should be between 0 and 360). --> | ||
| + <xsl:param name="degrees"/> | ||
| + <!-- Convert degrees to radians when degrees are used. --> | ||
| + <xsl:param name="rad" select="$degrees * $PI div 180"/> | ||
| + <xsl:call-template name="sine"> | ||
| + <xsl:with-param name="rad" select="$PIDIV2 - $rad" /> | ||
| + </xsl:call-template> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Calculates: normalized arc tangent form --> | ||
| <xsl:template name="atan2"> | ||
| <xsl:param name="y"/> | ||
| <xsl:param name="x"/> | ||
| <!-- | ||
| | http://lists.apple.com/archives/PerfOptimization-dev/2005/Jan/msg00051.html | ||
| ! http://permalink.gmane.org/gmane.text.xml.xslt.extensions/840 | ||
| +--> | ||
| - <xsl:variable name="PIBY2" select="$PI div 2.0"/> | ||
| <xsl:choose> | ||
| <xsl:when test="$x = 0.0"> | ||
| <xsl:choose> | ||
| <xsl:when test="($y > 0.0)"> | ||
| - <xsl:value-of select="$PIBY2"/> | ||
| + <xsl:value-of select="$PIDIV2"/> | ||
| </xsl:when> | ||
| <xsl:when test="($y < 0.0)"> | ||
| - <xsl:value-of select="-$PIBY2"/> | ||
| + <xsl:value-of select="-$PIDIV2"/> | ||
| </xsl:when> | ||
| <xsl:otherwise> | ||
| <xsl:choose> | ||
| <xsl:when test="($absZ < 1.0)"> | ||
| - <xsl:variable name="f1Z" select="$z div (1.0 + 0.28*$z*$z)"/> | ||
| + <xsl:variable name="f1Z" | ||
| + select="$z div (1.0 + 0.28*$z*$z)"/> | ||
| <xsl:choose> | ||
| <xsl:when test="($x < 0.0) and ($y < 0.0)"> | ||
| <xsl:otherwise> | ||
| <xsl:variable name="f2Z" | ||
| - select="$PIBY2 - ($z div ($z*$z + 0.28))"/> | ||
| + select="$PIDIV2 - ($z div ($z*$z + 0.28))"/> | ||
| <xsl:choose> | ||
| <xsl:when test="($y < 0.0)"> | ||
| <xsl:param name="a"/> | ||
| <xsl:param name="b"/> | ||
| - | ||
| - <xsl:if test="$a >= $b"><xsl:value-of select="$a"/></xsl:if> | ||
| - <xsl:if test="$a < $b"><xsl:value-of select="$b"/></xsl:if> | ||
| + | ||
| + <xsl:choose> | ||
| + <xsl:when test="$a > $b"><xsl:value-of select="$a"/></xsl:when> | ||
| + <xsl:otherwise><xsl:value-of select="$b"/></xsl:otherwise> | ||
| + </xsl:choose> | ||
| </xsl:template> | ||
| -<!-- Converts a two-digit hexadecimal number to decimal. --> | ||
| -<xsl:template name="hex2dec"> | ||
| - <xsl:param name="hex"/> | ||
| +<!-- Calculates: radicand^(1/index) --> | ||
| +<!-- http://www.shodor.org/unchem/math/newton/ --> | ||
| +<xsl:template name="nthroot"> | ||
| + <xsl:param name="index"/> | ||
| + <xsl:param name="radicand"/> | ||
| + <!-- Initial guess --> | ||
| + <xsl:param name="guess" select="1 + (($radicand - 1) div $index)"/> | ||
| - <xsl:variable name="digits" select="'0123456789ABCDEF'"/> | ||
| - <xsl:variable name="X" select="substring( $hex, 1, 1 )"/> | ||
| - <xsl:variable name="Y" select="substring( $hex, 2, 1 )"/> | ||
| - <xsl:variable name="Xval" | ||
| - select="string-length(substring-before($digits,$X))"/> | ||
| - <xsl:variable name="Yval" | ||
| - select="string-length(substring-before($digits,$Y))"/> | ||
| - <xsl:value-of select="16 * $Xval + $Yval"/> | ||
| + <xsl:variable name="approx"> | ||
| + <xsl:call-template name="nthroot_approx"> | ||
| + <xsl:with-param name="guess" select="$guess"/> | ||
| + <xsl:with-param name="index" select="$index"/> | ||
| + <xsl:with-param name="radicand" select="$radicand"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="derivative"> | ||
| + <xsl:call-template name="nthroot_derivative"> | ||
| + <xsl:with-param name="guess" select="$guess"/> | ||
| + <xsl:with-param name="index" select="$index"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="newGuess" select="$guess - $approx div $derivative"/> | ||
| + <xsl:variable name="difference" select="$newGuess - $guess"/> | ||
| + <xsl:variable name="precision" select="$guess * $ROOT_PRECISION"/> | ||
| + | ||
| + <xsl:variable name="abs_difference"> | ||
| + <xsl:call-template name="abs"> | ||
| + <xsl:with-param name="x" select="$difference"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:variable name="abs_precision"> | ||
| + <xsl:call-template name="abs"> | ||
| + <xsl:with-param name="x" select="$precision"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:choose> | ||
| + <xsl:when test="$abs_difference < $abs_precision"> | ||
| + <xsl:value-of select="$newGuess"/> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:call-template name="nthroot"> | ||
| + <xsl:with-param name="index" select="$index"/> | ||
| + <xsl:with-param name="radicand" select="$radicand"/> | ||
| + <xsl:with-param name="guess" select="$newGuess"/> | ||
| + </xsl:call-template> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Calculates: (guess ^ index) - radicand --> | ||
| +<xsl:template name="nthroot_approx"> | ||
| + <xsl:param name="guess"/> | ||
| + <xsl:param name="index"/> | ||
| + <xsl:param name="radicand"/> | ||
| + | ||
| + <xsl:variable name="power"> | ||
| + <xsl:call-template name="power"> | ||
| + <xsl:with-param name="base" select="$guess"/> | ||
| + <xsl:with-param name="exponent" select="$index"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:value-of select="$power - $radicand"/> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Calculates: index * (guess ^ (index - 1)) --> | ||
| +<xsl:template name="nthroot_derivative"> | ||
| + <xsl:param name="guess"/> | ||
| + <xsl:param name="index"/> | ||
| + | ||
| + <xsl:variable name="power"> | ||
| + <xsl:call-template name="power"> | ||
| + <xsl:with-param name="base" select="$guess"/> | ||
| + <xsl:with-param name="exponent" select="($index - 1)"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + | ||
| + <xsl:value-of select="$index * $power"/> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Calculates: base ^ exponent (whole number exponents) --> | ||
| +<xsl:template name="power"> | ||
| + <xsl:param name="base"/> | ||
| + <xsl:param name="exponent"/> | ||
| + <xsl:choose> | ||
| + <xsl:when test="$exponent = 0"> | ||
| + <xsl:value-of select="1"/> | ||
| + </xsl:when> | ||
| + <xsl:otherwise> | ||
| + <xsl:variable name="t"> | ||
| + <xsl:call-template name="power"> | ||
| + <xsl:with-param name="base" select="$base"/> | ||
| + <xsl:with-param name="exponent" select="$exponent - 1"/> | ||
| + </xsl:call-template> | ||
| + </xsl:variable> | ||
| + <xsl:value-of select="$base * $t"/> | ||
| + </xsl:otherwise> | ||
| + </xsl:choose> | ||
| +</xsl:template> | ||
| + | ||
| +<!-- Calculates: |x| --> | ||
| +<!-- http://en.wikipedia.org/wiki/Absolute_value --> | ||
| +<xsl:template name="abs"> | ||
| + <xsl:param name="x"/> | ||
| + <xsl:value-of select="($x >= 0) * $x - not($x >= 0) * $x"/> | ||
| </xsl:template> | ||
| <value>$ CAD</value> | ||
| </header> | ||
| + <!-- | ||
| + <data> | ||
| + <name>Pig</name> | ||
| + <value>211124</value> | ||
| + </data> | ||
| + <data> | ||
| + <name>Cow</name> | ||
| + <value>121554</value> | ||
| + </data> | ||
| + <data> | ||
| + <name>Cat</name> | ||
| + <value>221554</value> | ||
| + </data> | ||
| + <data> | ||
| + <name>Dog</name> | ||
| + <value>92455</value> | ||
| + </data> | ||
| + <data> | ||
| + <name>Horse</name> | ||
| + <value>71554</value> | ||
| + </data> | ||
| + <data> | ||
| + <name>Sheep</name> | ||
| + <value>102455</value> | ||
| + </data> | ||
| + --> | ||
| <data> | ||
| <name>Salaries and Employee Benefits</name> |