Shoelace formula for polygonal area: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Perl 6}}: Add a Perl 6 example)
m (→‎{{header|Perl 6}}: minor simplification)
Line 47: Line 47:


<lang perl6>sub area-by-shoelace(@p) {
<lang perl6>sub area-by-shoelace(@p) {
(^@p).map({@p[$_;0] * @p[($_+1)%@p;1] - @p[$_;1] * @p[($_+1)%@p;0]}).sum.abs / 2
@p.push: @p[0];
(^@p.end).map({@p[$_;0] * @p[$_+1;1] - @p[$_;1] * @p[$_+1;0]}).sum.abs / 2
}
}



Revision as of 21:48, 9 August 2017

Shoelace formula for polygonal area is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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.


ALGOL 68

<lang algol68>BEGIN

   # returns the area of the polygon defined by the points p using the Shoelace formula #
   OP  AREA = ( [,]REAL p )REAL:
       BEGIN
           [,]REAL points = p[ AT 1, AT 1 ]; # normalise array bounds to start at 1 #
           IF 2 UPB points /= 2 THEN
               # the points do not have 2 coordinates #
               -1
           ELSE
               REAL   result := 0;
               INT    n       = 1 UPB points;
               IF n > 1 THEN
                   # there at least two points #
                   []REAL x   = points[ :, 1 ];
                   []REAL y   = points[ :, 2 ];
                   FOR i TO 1 UPB points - 1 DO
                       result +:= x[ i     ] * y[ i + 1 ];
                       result -:= x[ i + 1 ] * y[ i     ]
                   OD;
                   result     +:= x[ n ] * y[ 1 ];
                   result     -:= x[ 1 ] * y[ n ]
               FI;
               ( ABS result ) / 2
           FI
       END # AREA # ;
   # test case as per the task #
   print( ( fixed( AREA [,]REAL( ( 3.0, 4.0 ), ( 5.0, 11.0 ), ( 12.0, 8.0 ), ( 9.0, 5.0 ), ( 5.0, 6.0 ) ), -6, 2 ), newline ) )

END </lang>

Output:
 30.00

Perl 6

Works with: Rakudo version 2017.07

<lang perl6>sub area-by-shoelace(@p) {

   (^@p).map({@p[$_;0] * @p[($_+1)%@p;1] - @p[$_;1] * @p[($_+1)%@p;0]}).sum.abs / 2

}

say area-by-shoelace( [ (3,4), (5,11), (12,8), (9,5), (5,6) ] );</lang>

Output:
30

Python

<lang python>>>> def area_by_shoelace(x, y):

   "Assumes x,y points go around the polygon in one direction"
   return abs( sum(i * j for i, j in zip(x,             y[1:] + y[:1]))
              -sum(i * j for i, j in zip(x[1:] + x[:1], y            ))) / 2

>>> points = [(3,4), (5,11), (12,8), (9,5), (5,6)] >>> x, y = zip(*points) >>> area_by_shoelace(x, y) 30.0 >>> </lang>