10

I'm trying to create a calculator which calculates the area of a simple quadrilateral. I know that every quadrilateral can be split into two triangles, and I should be able to calculate the area in two parts no matter what. I am able to do this in math, but I don't know how to implement it to Python.

Here's my quadrilateral class:

class Quadrilateral(Shape):
   def __init__(self, name):
       # in clockwise order: angles[0], sides[0], angles[1], sides[1], ...
       self.sides = [5] * 4
       self.angles = [90] * 4
       super().__init__(self, name)

Now what I need is to implement a method get_area() which calculates the area of my quadrilateral, but I have no idea how.

Here's how I would do it with a paper and a pen:

Area of a quadrilateral

Basically I would only need to know two angles and three sides to be able to use this technique to calculate the area, but let's not worry about that. For now, I know all the angles and all the sides, how do I calculate the area?

  • 2
    It might be a better approach to use 2D points instead angles and side-lengthes. It could result in an invalid data-set when modifieng one side but not adjusting the corresponding data. Using 2D points, the relations (angle and side-length) are implicit. – Niklas R Apr 03 '13 at 14:02
  • upvote for an awesome pic! – Gerrat Apr 03 '13 at 14:06
  • 1
    @Gerrat Paint for the win, yay! –  Apr 03 '13 at 14:09

3 Answers3

5

Just access the sides and angles directly in the two lists you have:

import math

area1 = 0.5 * self.sides[0] * self.sides[1] * math.sin(math.radians(self.angles[1]))
area2 = 0.5 * self.sides[2] * self.sides[3] * math.sin(math.radians(self.angles[3]))
area = area1 + area2

Given your example as sides = [3, 5, 5, 4] and angles = [90, 95, 75, 100], the area then is:

>>> import math
>>> sides = [3, 5, 5, 4]
>>> angles = [90, 95, 75, 100]
>>> area1 = 0.5 * sides[0] * sides[1] * math.sin(math.radians(angles[1]))
>>> area2 = 0.5 * sides[2] * sides[3] * math.sin(math.radians(angles[3]))
>>> area1 + area2
17.31953776581017
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yeah this is what I thought too and I tried it, but it's giving some REALLY weird results. In your example too, think about the sides `[3, 5, 5, 4]` and area being only `0.060806449423319364`? Not possible. –  Apr 03 '13 at 14:06
  • 5
    No. `math.sin` calculates in radians rather than degrees! – core1024 Apr 03 '13 at 14:09
  • @core1024 Ahh, feel stupid now, of course... How do I convert it? –  Apr 03 '13 at 14:11
  • 2
    Thanks guys, getting the correct results now! :) I should accept that core1024's comment lol :D –  Apr 03 '13 at 14:13
2

Based on https://en.wikipedia.org/wiki/Brahmagupta%27s_formula

see https://www.geeksforgeeks.org/maximum-area-quadrilateral/

def maxArea (a , b , c , d ): 

    # Calculating the semi-perimeter 
    # of the given quadilateral 
    semiperimeter = (a + b + c + d) / 2

    # Applying Brahmagupta's formula to 
    # get maximum area of quadrilateral 
    return math.sqrt((semiperimeter - a) *
                    (semiperimeter - b) *
                    (semiperimeter - c) * 
                    (semiperimeter - d)) 
Wolfgang Fahl
  • 15,016
  • 11
  • 93
  • 186
0

A better solution would be Gaussian quadrature. See page 17-10:

http://www.colorado.edu/engineering/cas/courses.d/IFEM.d/IFEM.Ch17.d/IFEM.Ch17.pdf

duffymo
  • 305,152
  • 44
  • 369
  • 561