Extension:MathFunctions

From MediaWiki.org

Jump to: navigation, search

           

Manual on MediaWiki Extensions
List of MediaWiki Extensions
Crystal Clear action run.png
MathFunctions

Release status: beta

Implementation  Parser function
Description Enhances parser with mathematical functions
Author(s)  Matěj GrabovskýTalk
Last Version  0.6 (2008-10-29)
MediaWiki  >= 1.11.0
License No license specified
Download see below

check usage (experimental)

Contents

[edit] What can this extension do?

MathFunctions enhances MediaWiki parser with mathematical functions sin, cos, tan, sqrt and others. This extension also adds ability to convert numbers between numerical bases and ability convert radians to degrees and reverse.

[edit] Usage

This extension can be used as any other parser functions extension, for example: {{#asin:514}} or {{#log:2513|11}}.

[edit] Geo distance

On October 29, 2008 the Geo distance function was added (thanks to Pnelnik). This function calculates distance between two points on the Earth. Result is in kilometres.

{{ #geodistance: point 1 Northern °|point 1 Eastern °|point 2 Northern °|point 2 Eastern ° }}

It is compatible with the results returned by the geocode function. For points that are south of the equator the northern degrees will be negative and similarly for points that are west of the Greenwich meridian, the eastern degrees will be negative.
It uses the following assumptions

  • The earth is a perfect sphere, the fact the earth is slightly flattened at the poles is ignored.
  • The altitude is ignored, the distance reported is the distance along the earth surface at sea level.
  • It is exactly 10,000 km from the equator to either pole, let this be R

Internally the function will convert the angles from degrees to radians, we'll call the angles in radians N1, E1, N2, E2. Then we work out the straight line distance through the earth between the two points:

D_through = R * sqrt { (cos(N1)*sin(E1) - cos(N2)*sin(E2))^2 + (cos(N1)*cos(E1) - cos(N2)*cos(E2))^2 + ( sin(N1) - sin(N2))^2 } 

and the distance along the surface is

D_surface = 2 * R * asin ( D_through / [ 2 * R ] )

[edit] Download instructions

Just copy the code from code section and paste it to a file, that save to your extensions directory as MathFunctions.php.

[edit] Installation

To install this extension, add the following at the end (but before closing delimiter ?>) of your LocalSettings.php:

# MathFunctions extension
require_once( "$IP/extensions/MathFunctions.php" );

[edit] Code

<?php
$wgExtensionCredits['parserhook'][] = array(
         'name' => "MathFunctions",
         'description' => "Enhances parser with mathematical functions",
         'version' => "0.6.1 - March 10, 2009",
         'author' => "Mat&#283;j Grabovsk&#253;, Pnelnik",
         'url' => "http://www.mediawiki.org/wiki/Extension:MathFunctions",
);
$wgExtensionFunctions[] = 'wfMathFunctions_Setup';
$wgHooks['LanguageGetMagic'][] = 'wfMathFunctions_Magic';
 
function wfMathFunctions_Setup() {
    global $wgParser;
 
    $wgParser->setFunctionHook( 'sin', 'efMathFunctionsSin_Render' );
    $wgParser->setFunctionHook( 'asin', 'efMathFunctionsAsin_Render' );
    $wgParser->setFunctionHook( 'cos', 'efMathFunctionsCos_Render' );
    $wgParser->setFunctionHook( 'acos', 'efMathFunctionsAcos_Render' );
    $wgParser->setFunctionHook( 'tan', 'efMathFunctionsTan_Render' );
    $wgParser->setFunctionHook( 'atan', 'efMathFunctionsAtan_Render' );
    $wgParser->setFunctionHook( 'atan2', 'efMathFunctionsAtan2_Render' );
    $wgParser->setFunctionHook( 'pow', 'efMathFunctionsPow_Render' );
    $wgParser->setFunctionHook( 'log', 'efMathFunctionsLog_Render' );
    $wgParser->setFunctionHook( 'sqrt', 'efMathFunctionsSqrt_Render' );
    $wgParser->setFunctionHook( 'deg2rad', 'efMathFunctionsDeg2rad_Render' );
    $wgParser->setFunctionHook( 'rad2deg', 'efMathFunctionsRad2deg_Render' );
    $wgParser->setFunctionHook( 'baseconvert', 'efMathFunctionsBaseconvert_Render' );
    $wgParser->setFunctionHook( 'geodistance', 'efMathFunctionsGeoDistance_Render' );
}
 
function wfMathFunctions_Magic( &$magicWords, $langCode ) {
    switch ( $langCode ) {
         default:
              $magicWords['sin']         = array( 0, 'sin' );
              $magicWords['asin']        = array( 0, 'asin' );
              $magicWords['cos']         = array( 0, 'cos' );
              $magicWords['acos']        = array( 0, 'acos' );
              $magicWords['tan']         = array( 0, 'tan' );
              $magicWords['atan']        = array( 0, 'atan' );
              $magicWords['atan2']       = array( 0, 'atan2' );
              $magicWords['pow']         = array( 0, 'pow' );
              $magicWords['log']         = array( 0, 'log' );
              $magicWords['sqrt']        = array( 0, 'sqrt' );
              $magicWords['deg2rad']     = array( 0, 'deg2rad' );
              $magicWords['rad2deg']     = array( 0, 'rad2deg' );
              $magicWords['baseconvert'] = array( 0, 'baseconvert' );
              $magicWords['geodistance'] = array( 0, 'geodistance' );
    }
 
    return true;
}
 
function efMathFunctionsSin_Render( &$parser, $n ) {
    return sin( $n );
}
 
function efMathFunctionsAsin_Render( &$parser, $n ) {
    return asin( $n );
}
 
function efMathFunctionsCos_Render( &$parser, $n ) {
    return cos( $n );
}
 
function efMathFunctionsAcos_Render( &$parser, $n ) {
    return acos( $n );
}
 
function efMathFunctionsTan_Render( &$parser, $n ) {
    return tan( $n );
}
 
function efMathFunctionsAtan_Render( &$parser, $n ) {
    return atan( $n );
}
 
function efMathFunctionsAtan2_Render( &$parser, $x, $y ) {
    return atan2( $x, $y );
}
 
function efMathFunctionsPow_Render( &$parser, $base, $exp = 2 ) {
    return pow( $base, $exp );
}
 
function efMathFunctionsLog_Render( &$parser, $n, $base = 10 ) {
    return log( $n, $base );
}
 
function efMathFunctionsSqrt_Render( &$parser, $n ) {
    return sqrt( $n );
}
 
function efMathFunctionsDeg2rad_Render( &$parser, $n ) {
    return deg2rad( $n );
}
 
function efMathFunctionsRad2deg_Render( &$parser, $n ) {
    return rad2deg( $n );
}
 
function efMathFunctionsBaseconvert_Render( &$parser, $n, $from, $to ) {
    return base_convert( $n, $from, $to );
}
 
function efMathFUnctionsGeoDistance_Render( &$parser, $pos1_northDeg, $pos1_eastDeg, $pos2_northDeg, $pos2_eastDeg ) {
	$degToRadFactor = M_PI / 180;
	$radiusOfEarthKm = 20000 / M_PI;
 
	$northRad1 = $pos1_northDeg * $degToRadFactor;		$eastRad1 = $pos1_eastDeg * $degToRadFactor;
	$northRad2 = $pos2_northDeg * $degToRadFactor;		$eastRad2 = $pos2_eastDeg * $degToRadFactor;
 
	$cosNorth1 = cos( $northRad1 );						$cosEast1 = cos( $eastRad1 );
	$cosNorth2 = cos( $northRad2 );						$cosEast2 = cos( $eastRad2 );
 
	$sinNorth1 = sin( $northRad1 );						$sinEast1 = sin( $eastRad1 );
	$sinNorth2 = sin( $northRad2 );						$sinEast2 = sin( $eastRad2 );
 
	$term1 = $cosNorth1 * $sinEast1 - $cosNorth2 * $sinEast2;
	$term2 = $cosNorth1 * $cosEast1 - $cosNorth2 * $cosEast2;
	$term3 = $sinNorth1 - $sinNorth2;
 
	$distThruSquared = $term1 * $term1 + $term2 * $term2 + $term3 * $term3;
 
	$surfaceDistance = 2 * $radiusOfEarthKm * asin( sqrt( $distThruSquared ) / 2 );
 
	return $surfaceDistance;
}

[edit] See also