Exercise 2.5

{-
Area of a shape: compute by adding up the trapezoidal areas
formed by pair of vertices with the x-axis.
This can (correctly) be negative when x2 > x1.
-}
 
axisTrapezoidArea :: Vertex -> Vertex -> Float
axisTrapezoidArea (x1, y1) (x2, y2) = (x1 - x2) * (y1 + y2) * 0.5
 
area :: Shape -> Float
area (Polygon (v1:vs)) = polyArea v1 vs
    where polyArea v (vnext:vs') = axisTrapezoidArea v vnext
                                   + polyArea vnext vs'
          polyArea vlast [] = axisTrapezoidArea vlast v1

Wrapping the head of a list in this way is more idiomatically done with

list ++ [head list]

rather than pattern matching the end of the list. However, at this stage in the book, we’re Haskell newbies.

4 Responses to “Exercise 2.5”

  1. fero says:

    It’s not working! Try area (Polygon [(7,0),(4,0),(4,5),(0,5)]) -> 2.5 but should be 17.5 (with triangle solution from book)

  2. fero says:

    Actually I don’t know how to solve it. I have almos the same solution, I found that it is wrong so I am in search of correct one:)

  3. admin says:

    Fero, your Polygon [(7,0),(4,0),(4,5),(0,5)] is self-crossing. This algorithm is inadequate for self-crossing polygons, but it is correct for concave polygons.

  4. fero says:

    Thanks Ben, you are right. When I swap last two vertexes – area (Polygon [(7,0),(4,0),(0,5),(4,5)]) , it will not be a self-crossing polygon and it works as expected.

Leave a Reply