Given the n + 1 vertices x[0], y[0] .. x[N], y[N] of a simple polygon described in a clockwise direction, then the polygon's area can be calculated by:

abs( (sum(x[0]*y[1] + ... x[n-1]*y[n]) + x[N]*y[0]) -
     (sum(x[1]*y[0] + ... x[n]*y[n-1]) + x[0]*y[N])
   ) / 2
(Where abs returns the absolute value)

Task

Write a function/method/routine to use the the Shoelace formula to calculate the area of the polygon described by the ordered points:

     (3,4), (5,11), (12,8), (9,5), and (5,6) 



Show the answer here, on this page.




 
with(ArrayTools):
 
module Point()
 option object;
 local x := 0;
 local y := 0;
 
 export getX::static := proc(self::Point, $)
  return self:-x;
 end proc;
 
 export getY::static := proc(self::Point, $)
  return self:-y
 end proc;
 
 export ModuleApply::static := proc()
  Object(Point, _passed);
 end proc;
 
 export ModuleCopy::static := proc(new::Point, proto::Point, X, Y, $)
  new:-x := X;
  new:-y := Y;
 end proc;
 
 export ModulePrint::static := proc(self::Point)
  return cat("(", self:-x, ",", self:-y, ")");
 end proc;
end module:
 
module Polygon()
 option object;
 local vertices := Array([Point(0,0)]);
 
 export getVertices::static := proc(self::Polygon)
  return self:-vertices;
 end proc;
 
 export area::static := proc(self::Polygon)
  local i, N := ArrayNumElems(self:-vertices);
  local total := getX(self:-vertices[N]) * getY(self:-vertices[1]) - getX(self:-vertices[1]) * getY(self:-vertices[N]);
  total += map(`+`, seq(getX(self:-vertices[i]) * getY(self:-vertices[i+1]), i = 1..(N-1))) - map(`+`, seq(getX(self:-vertices[i+1]) * getY(self:-vertices[i]), i = 1..(N-1)));
  return abs(total / 2);
 end proc;
 
 export ModuleApply::static := proc()
  Object(Polygon, _passed);
 end proc;
 
 export ModuleCopy::Static := proc(new::Polygon, proto::Polygon, Ps, $)
  new:-vertices := Ps;
 end proc;
 
 export ModulePrint::static := proc(self::Polygon)
  return self:-vertices;
 end proc;
end module:
 
P1 := Polygon(Array([Point(3,4), Point(5,11), Point(12,8), Point(9,5), Point(5,6)])):
area(P1);                                                                                               
 