Click here to Skip to main content
Click here to Skip to main content

A JavaScript Implementation of the Surveyor's Formula

, 17 Mar 2006
Rate this:
Please Sign up or sign in to vote.
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&nbsp; </td>
<td colspan="2"><input type="text" 
         id="PERIMETER" size="20"></td>
<td>&nbsp;</td>
</tr>
<tr>
<td align="right">Area </td>
<td colspan="2"><input type="text" 
         id="AREA" size="20"></td>
<td>&nbsp;</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

Share

About the Author

dszarkow
Retired Top Software Tutor
United States United States
Don Szarkowicz retired after 18 years teaching introductory and advanced programming and application development courses for the Department of Computer Information Systems at Indiana University Northwest.
 
He currently operates Top Software Tutor, which offers affordable, personalized, one-on-one assistance for a broad range of computing projects, homework problems and other assignments involving popular programming languages, Web design and development techniques, and Microsoft Office applications
 
His technical interests include Web programming and C# using Visual Studio NET.
 
Don holds a Ph.D. in Electrical Engineering from the Illinois Institute of Technology, and an MBA from the University of Chicago. Don is also a registered Professional Engineer and an amateur radio operator (call sign KC9ALE).

Comments and Discussions

 
GeneralThank you! Pinmembervaximillian15-Oct-07 23:16 
QuestionSample Problem didn't compute??? Pinmemberhaggarace8-Oct-07 11:24 
AnswerRe: Sample Problem didn't compute??? Pinmemberdszarkow9-Oct-07 2:53 
AnswerRe: Sample Problem didn't compute??? Pinmemberhaggarace12-Oct-07 14:07 
GeneralThanks Don Pinmemberpdfield16-May-07 9:18 
GeneralPattern Matching Pinmembermbwelby20-Apr-07 16:04 
GeneralRe: Pattern Matching Pinmemberdszarkow21-Apr-07 2:58 
GeneralRe: Pattern Matching PinmemberDavidHume14-Oct-09 12:00 
QuestionWow,..... point outside polygon Pinmemberveraart5-Feb-07 22:59 
AnswerRe: Wow,..... point outside polygon Pinmemberdszarkow6-Feb-07 6:42 
GeneralRe: Wow,..... point outside polygon Pinmemberveraart6-Feb-07 21:33 
Generali like it PinmemberThe_Myth18-Mar-06 21:22 
GeneralRe: i like it Pinmemberdszarkow19-Mar-06 1:44 
GeneralI would have loved PinmemberJörgen Sigvardsson18-Mar-06 11:38 
GeneralRe: I would have loved Pinmemberdszarkow18-Mar-06 13:39 
GeneralRe: I would have loved PinmemberJörgen Sigvardsson18-Mar-06 14:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 17 Mar 2006
Article Copyright 2006 by dszarkow
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid