Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A JavaScript Implementation of the Surveyor's Formula

0.00/5 (No votes)
17 Mar 2006 5  
An article presenting a JavaScript implementation of the Surveyor's formula for calculating the area of any polygon.

Polygon Area and Perimeter Calculator Form

Introduction

Calculating the area (and perimeter) of polygons is an important task in nearly all branches of science and technology, including engineering, mathematics, computer science, and bioinformatics. This article provides a brief overview of the Surveyor�s formula, and presents a JavaScript implementation that allows the area of arbitrary polygons to be calculated using a form contained in a Web page. Using this JavaScript implementation, a user can easily calculate the areas of more interesting, unusual, and challenging polygons. The code also allows the polygon's perimeter to be calculated using no additional data.

Background

Many practical applications of science and technology (including engineering, mathematics, computer science, and bioinformatics) require calculating the area of regular and irregular polygons. For example, an engineer may be required to calculate the area of an unusual shape in order to determine that shape's moment of inertia, a mathematician may want the area between the x-axis and an experimentally determined curve, a computer scientist may be need the area of some program-generated graphics object, or a bioinformatician may be interested in the area of a cell displayed in a digital image.

A polygon is planar figure having three or more sides. The triangle, square, trapezoid, and parallelogram are familiar polygons. More generally, the closed shape produced by any sequence of three or more line segments connected end-to-end is also a polygon. The sides of a polygon are called edges, and the points where the edges meet are called vertices.

As a student of elementary mathematics, algebra, or geometry, you were probably taught to apply standard formulas to calculate the areas of regular polygons such as the equilateral triangle, square, pentagon, and hexagon. You also likely learned how to calculate the areas of simpler irregular polygons such as triangles, rectangles, trapezoids, and parallelograms. These kinds of problems are important because examples of both regular and irregular polygons can be found in nature. When faced with the problem of finding the area of a more complicated polygon that did not match one of these standard shapes, you were probably taught to decompose that complicated polygon into two or more simpler shapes whose areas could then be found using standard formulas.

Here is an image of an irregular polygon. How would you go about finding the area of this figure?

In order to apply the standard formulas, the lengths, widths, or heights of the simpler shapes must be found, and in all but the most trivial problems, that process ultimately requires finding the coordinates of each vertex, then using those coordinates to calculate the required distances. When this procedure is performed by hand, ample opportunities arise to unintentionally introduce computational errors and arrive at an incorrect answer.

However, if the polygon's vertex coordinates can easily be found (perhaps by reading them from a scaled figure), or if those coordinates are otherwise available, no decomposition is required, and the polygon�s area may be calculated exactly using the Surveyor�s formula.

If the polygon is described by a set of n vertices that are labeled P0, P1, ..., Pn-1 and are identified in a counterclockwise manner from any initial vertex, and if each Pk has coordinates (xk,yk), the Surveyor�s formula may simply be written as:

A = (x0y1 + x1y2 + ... + xn-1y0 - y0x1 - y1x2 - ... - yn-1x0) / 2

If we assign Pn = P0, and if the increments dxk and dyk are measured to the next vertex,

dyk = yk+1 - yk, dxk = xk+1 - xk

The Surveyor's formula can also be written as:

A = x0dy0 - y0dx0 + x1dy1 - y1dx1 + ... + xn-1dyn-1 - yn-1dxn-1

To implement the Surveyor's formula in JavaScript, we will write a function to read and store the number of vertices and the x and y coordinates for each vertex, a second function to calculate and return the polygon's enclosed area, a third function to calculate and return the polygon's perimeter, and a fourth function that serves as an event handler and controls the overall process.

Implementation and Code

The following JavaScript/HTML code defines a document that contains a form allowing a user to specify a polygon's shape by entering the number of vertices and each vertex�s coordinates. The form contains a Calculate button that, when clicked, executes the JavaScript function named handleCalculate(). That function, in turn, calls the functions readUserData(), calculateArea(), calculatePerimeter(), and displayCoordinates() to read the user�s input, parse the coordinate values, calculate the polygon�s area and perimeter, and display the results using the specified number of decimal digits. In this sample, up to 10 vertices may be entered. If more vertices are involved, additional table rows with textboxes having IDs X10, X11, ..., must be added to the form's table. The number of vertices will be read and the additional vertices will be read, stored, and processed.

For test and demonstration purposes, the form also contains a button labeled Load Vertices that, when clicked, executes the JavaScript function named loadVertices(). That function reads the number of vertices requested, calculates the x and y coordinates for a sequence of vertices representing a polygon inscribed on a unit circle, and loads those values into the form. Increasing the number of vertices and recalculating the inscribed polygon�s area and perimeter will demonstrate generating numerical values for the inscribed polygon's area and perimeter that approach those of a unit circle.

<html>
<head>
  <title>Polygon Area and Perimeter</title>

  <style>
  <!--
    body {background-color:#FF9900;}
    table {background-color:#FF9900;}
    .content {width:800px; background-color:white; padding:10px;}
  -->
  </style>

  <script language="JavaScript">

    // Two coordinate arrays

    var x = new Array();
    var y = new Array();
    var vertices;
    var digits;
    var area;
    var perimeter;
    
    function readUserData()
    {
        // Read the number of vertices

        vertices = parseInt( document.getElementById("VERTICES").value );
        if( (vertices < 3) || (vertices > 10 ) ) {
            alert( "Vertices must be >= 3 and <= 10" );
            return;
        }

        // Read the value of displayed digits

        digits = parseInt( document.getElementById("DIGITS").value );
        if( digits < 0 ) {
            alert( "Digits must be > 0" );
            return;
        }

        // Read and store the vertex x and y values

        for( k = 0; k < vertices; k++ ) {
            x[k] = parseFloat( document.getElementById("X"+k).value );
            y[k] = parseFloat( document.getElementById("Y"+k).value );
        }
        
        // Copy the values x[0] and y[0]

        // to the values x[vertices] and y[vertices]

        // to simplfy the area and perimeter calculations

        x[vertices] = x[0];
        y[vertices] = y[0];
    }

    function calculateArea()
    {
        // Calculate the area of a polygon

        // using the data stored

        // in the arrays x and y

        area = 0.0;
        for( k = 0; k < vertices; k++ ) {
            xDiff = x[k+1] - x[k];
            yDiff = y[k+1] - y[k];
            area = area + x[k] * yDiff - y[k] * xDiff;
        }
        area = 0.5 * area;
    }

    function calculatePerimeter()
    {
        // Calculate the perimeter

        // of a polygon using the data stored

        // in the arrays x and y

        perimeter = 0.0 
        for( k = 0; k < vertices; k++ ) {
            xDiff = x[k+1] - x[k];
            yDiff = y[k+1] - y[k];
            perimeter = perimeter + 
                        Math.pow( xDiff*xDiff + 
                        yDiff*yDiff, 0.5 );
        }
    }

    function displayCoordinates()
    {
        for( k = 0; k < vertices; k++ ) {
            document.getElementById("X"+(k)).value = 
                               x[k].toFixed(digits);
            document.getElementById("Y"+(k)).value = 
                               y[k].toFixed(digits);
        }
    }

    function handleCalculate()
    {
        readUserData();
        calculateArea();
        calculatePerimeter(); 
    
        // Display the x and y values using

        // the specified number of decimal digits

        displayCoordinates();
    
        // Display the calculated results

        document.getElementById("AREA").value = 
                          area.toFixed(digits);
        document.getElementById("PERIMETER").value = 
                          perimeter.toFixed(digits);
    }

    function loadVertices()
    {
        // Clear the form data, if any

        for( k = 0; k < 10; k++ ) {
            document.getElementById("X"+k).value = "";
            document.getElementById("Y"+k).value = "";
        }
        document.getElementById("AREA").value = "";
        document.getElementById("PERIMETER").value = ""; 
    
        // Read the number of vertices

        vertices = parseInt( document.getElementById("VERTICES").value ); 
        if( (vertices < 3) || (vertices > 10 ) ) {
            alert( "Vertices must be >= 3 and <= 10" );
            return;
        }
    
        // Read the value of displayed digits

        digits = parseInt(document.getElementById("DIGITS").value );
        if( digits < 0 ) {
            alert( "Digits must be > 0" );
            return;
        }

        // Assign and display each vertex's x and y values

        angle = 2 * Math.PI / vertices;
        for( k = 0; k < vertices; k++ ) {
            xvalue = 0.5 * Math.cos( angle * k );
            yvalue = 0.5 * Math.sin( angle * k );
    
            document.getElementById("X"+k).value = 
                           xvalue.toFixed(digits);
            document.getElementById("Y"+k).value = 
                           yvalue.toFixed(digits); 
        }
    }
  </script>
</head>

<body>
<div align="center">
<div class="content">
<form>
<table border="2" cellspacing="0" 
         cellpadding="2" style="border-collapse: collapse">
<tr>
<td colspan="4">
<p align="center">
<img border="0" src="Polygon.gif" width="80" 
      height="60" align="center"><font size="5">Polygon 
Area and Perimeter Calculator</font></td>
</tr>
<tr>
<td colspan="2">Number of Vertices 
<input type="text" id="VERTICES" 
          size="5" value="3"></td>
<td colspan="2">Displayed Decimal Digits 
<input type="text" size="5" id="DIGITS" 
                      value="3"></td>
</tr>
<tr>
<td align="center">Vertex</td>
<td colspan="2" align="left">X Value</td>
<td align="left">Y Value</td>
</tr>
<tr>
<td align="center">1</td>
<td colspan="2"><input type="text" 
               id="X0" size="20"></td>
<td><input type="text" id="Y0" size="20"></td>
</tr>
<tr>
<td align="center">2</td>
<td colspan="2"><input type="text" 
             id="X1" size="20"></td>
<td><input type="text" id="Y1" size="20"></td>
</tr>
<tr>
<td align="center">3</td>
<td colspan="2"><input type="text" 
             id="X2" size="20"></td>
<td><input type="text" id="Y2" size="20"></td>
</tr>
<tr>
<td align="center">4</td>
<td colspan="2"><input type="text" 
            id="X3" size="20"></td>
<td><input type="text" id="Y3" size="20"></td>
</tr>
<tr>
<td align="center">5</td>
<td colspan="2"><input type="text" 
           id="X4" size="20"></td>
<td><input type="text" id="Y4" size="20"></td>
</tr>
<tr>
<td align="center">6</td>
<td colspan="2"><input type="text" 
          id="X5" size="20"></td>
<td><input type="text" id="Y5" size="20"></td>
</tr>
<tr>
<td align="center">7</td>
<td colspan="2"><input type="text" 
         id="X6" size="20"></td>
<td><input type="text" id="Y6" size="20"></td>
</tr>
<tr>
<td align="center">8</td>
<td colspan="2"><input type="text" 
         id="X7" size="20"></td>
<td><input type="text" id="Y7" size="20"></td>
</tr>
<tr>
<td align="center">9</td>
<td colspan="2"><input type="text" 
         id="X8" size="20"></td>
<td><input type="text" id="Y8" size="20"></td>
</tr>
<tr>
<td align="center">10</td>
<td colspan="2"><input type="text" 
         id="X9" size="20"></td>
<td><input type="text" id="Y9" size="20"></td>
</tr>
<tr>
<td align="right">Perimeter  </td>
<td colspan="2"><input type="text" 
         id="PERIMETER" size="20"></td>
<td> </td>
</tr>
<tr>
<td align="right">Area </td>
<td colspan="2"><input type="text" 
         id="AREA" size="20"></td>
<td> </td>
</tr>
<tr>
<td align="center"><input type="button" 
    value="Calculate" onClick="handleCalculate()"></td>
<td colspan="2" align="center">
<input type="button" value="Load Vertices" 
    onClick="loadVertices()"></td>
<td align="center">
<input type="reset" value="Reset"></td>
</tr>
</table>

<p align="left"><b>Instructions</b></p>

<p align="left">To calculate the area and perimeter 
of an arbitrary polygon, begin by numbering 
the polygon's vertices starting at 1, 
proceeding in a counter-clockwise manner. 
Enter the number of vertices in the form below, 
then enter each vertex's x and y values. After entering 
the required data, click the Calculate button 
to obtain the polygon's area and perimeter. 
As written, the calculator can process up to 10 vertices.</p>

<p align="left">To calculate the area 
and perimeter of a regular polygon inscribed in a 
circle having a radius of 1.0, enter 
the number of vertices in the form below, 
then click the Load Vertices button. 
A set of vertex coordinates will 
automatically be loaded. </p>

<p align="left">After clicking 
the Calculate or Load Vertices buttons, the coordinate values, 
area and perimeter will displayed using the specified number of 
decimal digits. The coordinate values 
displayed are those used to calculate the 
area and perimeter, so changing the 
displayed decimal digits may change the x 
and y coordinate values and may result 
in the calculation of different values 
for the polygon's area and perimeter. 
For many practical problems of interest, results 
calculated and displayed using 3 decimal digits are adequate.</p>

<p align="left">Clicking the Reset button 
will erase the form's content and set the number of 
vertices and displayed decimal digits to 3.</p>

</form>
</div>
</div>
</body>
</html>

A Sample Problem

The surveyor�s formula provides an easy, efficient, and unified method for calculating the area of any polygon. It is an often-overlooked alternative technique for calculating the area of any polygon. Using the HTML document above, the area and perimeter of this polygon may easily be found.

Table 1 contains a set of sample data for an irregular polygon having 10 vertices. The polygon�s shape is shown in Figure 1. The area of this relatively simple polygon is not easily obtainable by decomposing the polygon into simpler, more familiar shapes.

Using the HTML document listed above, the area of this polygon is easily found to be 3.188 and the perimeter to be 7.772.

Table 1: Coordinates of an irregular polygon

x

y

1.305

0

0.567

0.412

0.458

1.408

-0.384

1.182

-0.99

0.72

-1.03

0

-1.061

-0.771

-0.229

-0.704

0.275

-0.848

0.476

-0.346

1.305

0

Figure 1: An irregular polygon

History

  • 03-16-2006:
    • Original article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here