In this article I will demonstrate how to calculate the area of any quadrilateral, or four-sided figure, in Python using Bretschneider's Formula.

This article is the second of three showing various ways of calculating the areas of quadrilaterals in Python.

## The Project

This project consists of the following files:

- bretschneidersformula.py
- main.py

The files can be downloaded as a zip file, or you can clone/download the Github repository if you prefer.

Source Code Links

## Bretschneider's Formula

Using Bretschneider's Formula we can calculate the area of any quadrilateral if we know the lengths of its sides and two opposite angles. This is the formula as presented in the Wikipedia article.

In this formula *a*, *b*, *c* and *d* are the lengths of the sides, and *α* and *γ* (the Greek letters *alpha* and *gamma*) are either of the two pairs of opposite angles. We also need the semiperimeter *s* or half-perimeter which we can easily calculate from the four sides.

The formula looks a bit complicated but all we need to untangle it and implement it in Python are the math.cos and math.sqrt functions as well as a bit of simple arithmetic.

## Example Quadrilaterals

The diagrams below illustrate the two quadrilaterals I will be using in the code. They are both made up of two triangles whose sides are Pythagorean Triples as this makes it easier to find the areas of the quadrilaterals by working out the areas of the triangles and adding them together.

## The Code

Firstly let's look at the calculate_area function which implements Bretschneider's Formula.

bretschneidersformula.py

from functools import reduce

import math

def calculate_area(sides, opposite_angles_degrees):

'''

Calculate the area of a quadrilateral using Bretschneider's Formula

from the lengths of the sides and either pair of OPPOSITE angles.

Arguments:-

sides - list in format [a,b,c,d]

opposite_angles_degrees - list in format [a1,a2]

'''

semiperimeter = sum(sides) / 2

product_semiperimeter_minus_sides = (semiperimeter - sides[0]) * \

(semiperimeter - sides[1]) * \

(semiperimeter - sides[2]) * \

(semiperimeter - sides[3])

product_sides = reduce((lambda x, y: x * y), sides)

sum_of_radians = math.radians(opposite_angles_degrees[0]) + math.radians(opposite_angles_degrees[1])

cos_squared = ( math.cos(sum_of_radians / 2 ) ) **2

area = math.sqrt(product_semiperimeter_minus_sides - product_sides * cos_squared)

return area

As you can see from the docstring the arguments are:

- sides - list in format [a,b,c,d]
- opposite_angles_degrees - list in format [a1,a2]

The formula is broken down into several stages.

Firstly we calculate semiperimeter (*s* in the formula) which is simply the sum of the sides divided by 2.

Then we calculate product_semiperimeter_minus_sides which is this bit of the formula.

Next up is product_sides, or the product of the lengths of the sides shown as *abcd* in the formula.

Then we calculate sum_of_radians which is this part of the formula. Notice that we convert degrees to radians here as math.cos needs radians.

The final intermediate value is cos_squared which is this part of the formula (with *α* + *γ* already calculated).

Finally we can use the four intermediate values to calculate the area of the quadrilateral.

Now we just need some code to try out the calculate_area function.

main.py

import bretschneiderformula

def main():

print("---------------------------------------")

print("| codedrome.com |")

print("| Calculating Areas of Quadrilaterals |")

print("| With Bretschneider's Formula |")

print("---------------------------------------\n")

quadrilateral_1 = {

"sides": [8, 17, 12, 9],

"opposite_angles_degrees": [61.92751306, 90.0],

# OR

# "opposite_angles_degrees": [143.1301024, 64.94238459],

"area": 0

}

quadrilateral_1["area"] = bretschneiderformula.calculate_area(quadrilateral_1["sides"], quadrilateral_1["opposite_angles_degrees"])

print(quadrilateral_1)

#------------------------------------------------------

quadrilateral_2 = {

"sides": [9, 15, 5, 13],

"opposite_angles_degrees": [53.13010235, 67.38013505],

# OR

# "opposite_angles_degrees": [112.6198649, 126.8698976],

"area": 0

}

quadrilateral_2["area"] = bretschneiderformula.calculate_area(quadrilateral_2["sides"], quadrilateral_2["opposite_angles_degrees"])

print(quadrilateral_2)

main()

The two dictionaries quadrilateral_1 and quadrilateral_2 are initialized with lists containing the lengths of the four sides and opposite angles of the two example quadrilaterals shown above. There are also area values initialized to 0.

The area values are then set with a calls to calculate_area, and finally the dictionaries are printed.

## Running the Program

Now let's run the program like this:

python3 main.py

This is the output.

Program Output

---------------------------------------

| codedrome.com |

| Calculating Areas of Quadrilaterals |

| With Bretschneider's Formula |

---------------------------------------

{'sides': [8, 17, 12, 9], 'opposite_angles_degrees': [61.92751306, 90.0], 'area': 113.99999999890288}

{'sides': [9, 15, 5, 13], 'opposite_angles_degrees': [53.13010235, 67.38013505], 'area': 83.99999999759844}

As you can see we have lost a very tiny amount of precision but I hope you can live with that!

In the final article of this trilogy I will show how to calculate the area of a quadrilateral from the coordinates of its corners.