Shoelace formula for polygonal area: Difference between revisions
Shoelace formula for polygonal area (view source)
Revision as of 15:37, 5 February 2024
, 3 months ago→{{header|Wren}}: Changed to Wren S/H
PatGarrett (talk | contribs) (→{{header|360 Assembly}}: Section added) |
m (→{{header|Wren}}: Changed to Wren S/H) |
||
(72 intermediate revisions by 34 users not shown) | |||
Line 14:
Show the answer here, on this page.
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">F area_by_shoelace(x, y)
R abs(sum(zip(x, y[1..] [+] y[0.<1]).map((i, j) -> i * j))
-sum(zip(x[1..] [+] x[0.<1], y).map((i, j) -> i * j))) / 2
V points = [(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)]
V x = points.map(p -> p[0])
V y = points.map(p -> p[1])
print(area_by_shoelace(x, y))</syntaxhighlight>
{{out}}
<pre>
30
</pre>
=={{header|360 Assembly}}==
<
SHOELACE CSECT
USING SHOELACE,R15 base register
Line 41 ⟶ 59:
PG DC CL12' ' buffer
REGEQU
END SHOELACE</
{{out}}
<pre>
30
</pre>
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT"
PROC Area(INT ARRAY xs,ys BYTE count REAL POINTER res)
BYTE i,next
REAL x1,y1,x2,y2,tmp1,tmp2
IntToReal(0,res)
IntToReal(xs(0),x1) IntToReal(ys(0),y1)
FOR i=0 TO count-1
DO
next=i+1
IF next=count THEN
next=0
FI
IntToReal(xs(next),x2) IntToReal(ys(next),y2)
RealMult(x1,y2,tmp1)
RealAdd(res,tmp1,tmp2)
RealMult(x2,y1,tmp1)
RealSub(tmp2,tmp1,res)
RealAssign(x2,x1) RealAssign(y2,y1)
OD
RealAbs(res,tmp1)
IntToReal(2,tmp2)
RealDiv(tmp1,tmp2,res)
RETURN
PROC PrintPolygon(INT ARRAY xs,ys BYTE count)
BYTE i
FOR i=0 TO count-1
DO
PrintF("(%I,%I)",xs(i),ys(i))
IF i<count-1 THEN
Print(", ")
ELSE
PutE()
FI
OD
RETURN
PROC Test(INT ARRAY xs,ys BYTE count)
REAL res
Area(xs,ys,count,res)
Print("Polygon: ")
PrintPolygon(xs,ys,count)
Print("Area: ")
PrintRE(res) PutE()
RETURN
PROC Main()
INT ARRAY
xs(5)=[3 5 12 9 5],
ys(5)=[4 11 8 5 6]
Put(125) PutE() ;clear screen
Test(xs,ys,5)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Shoelace_formula_for_polygonal_area.png Screenshot from Atari 8-bit computer]
<pre>
Polygon: (3,4), (5,11), (12,8), (9,5), (5,6)
Area: 30
</pre>
=={{header|Ada}}==
{{works with|Ada|Ada|83}}
<syntaxhighlight lang="ada">with Ada.Text_IO;
procedure Shoelace_Formula_For_Polygonal_Area
is
type Point is record
x, y : Float;
end record;
type Polygon is array (Positive range <>) of Point;
function Shoelace(input : in Polygon) return Float
is
sum_1 : Float := 0.0;
sum_2 : Float := 0.0;
tmp : constant Polygon := input & input(input'First);
begin
for I in tmp'First .. tmp'Last - 1 loop
sum_1 := sum_1 + tmp(I).x * tmp(I+1).y;
sum_2 := sum_2 + tmp(I+1).x * tmp(I).y;
end loop;
return abs(sum_1 - sum_2) / 2.0;
end Shoelace;
my_polygon : constant Polygon :=
((3.0, 4.0),
(5.0, 11.0),
(12.0, 8.0),
(9.0, 5.0),
(5.0, 6.0));
begin
Ada.Text_IO.Put_Line(Shoelace(my_polygon)'Img);
end Shoelace_Formula_For_Polygonal_Area;</syntaxhighlight>
{{out}}
<pre> 3.00000E+01
</pre>
=={{header|ALGOL 60}}==
Optimized version:
'''begin'''
'''comment''' Shoelace formula for polygonal area - Algol 60;
'''real''' '''array''' x[1:33],y[1:33];
'''integer''' i,n;
'''real''' a;
ininteger(0,n);
'''for''' i:=1 '''step''' 1 '''until''' n '''do'''
'''begin'''
inreal(0,x[i]);
inreal(0,y[i])
'''end''';
x[i]:=x[1];
y[i]:=y[1];
a:=0;
'''for''' i:=1 '''step''' 1 '''until''' n '''do'''
a:=a+x[i]*y[i+1]-x[i+1]*y[i];
a:=abs(a/2.);
outreal(1,a)
'''end'''
{{out}}
<pre>
30.00
</pre>
Non-optimized version:
'''begin'''
'''comment''' Shoelace formula for polygonal area - Algol 60;
'''real''' '''array''' x[1:32],y[1:32];
'''integer''' i,j,n;
'''real''' a;
ininteger(0,n);
'''for''' i:=1 '''step''' 1 '''until''' n '''do'''
'''begin'''
inreal(0,x[i]); inreal(0,y[i])
'''end''';
a:=0;
'''for''' i:=1 '''step''' 1 '''until''' n '''do'''
'''begin'''
j:='''if''' i=n '''then''' 1 '''else''' i+1;
a:=a+x[i]*y[j]-x[j]*y[i]
'''end''';
a:=abs(a/2.);
outreal(1,a)
'''end'''
{{out}}
<pre>
30.00
</pre>
=={{header|ALGOL 68}}==
<
# returns the area of the polygon defined by the points p using the Shoelace formula #
OP AREA = ( [,]REAL p )REAL:
Line 77 ⟶ 257:
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
</syntaxhighlight>
{{out}}
<pre>
30.00
</pre>
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl">shoelace ← 2÷⍨|∘(((1⊃¨⊢)+.×1⌽2⊃¨⊢)-(1⌽1⊃¨⊢)+.×2⊃¨⊢)</syntaxhighlight>
{{out}}
<pre> shoelace (3 4) (5 11) (12 8) (9 5) (5 6)
30</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">define :point [x,y][]
shoelace: function [pts][
[leftSum, rightSum]: 0
loop 0..dec size pts 'i [
j: (i + 1) % size pts
'leftSum + pts\[i]\x * pts\[j]\y
'rightSum + pts\[j]\x * pts\[i]\y
]
return 0.5 * abs leftSum - rightSum
]
points: @[
to :point [3.0, 4.0]
to :point [5.0, 11.0]
to :point [12.0, 8.0]
to :point [9.0, 5.0]
to :point [5.0, 6.0]
]
print shoelace points</syntaxhighlight>
{{out}}
<pre>30.0</pre>
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">V := [[3, 4], [5, 11], [12, 8], [9, 5], [5, 6]]
n := V.Count()
for i, O in V
Sum += V[i, 1] * V[i+1, 2] - V[i+1, 1] * V[i, 2]
MsgBox % result := Abs(Sum += V[n, 1] * V[1, 2] - V[1, 1] * V[n, 2]) / 2</syntaxhighlight>
{{out}}
<pre>30.000000</pre>
=={{header|BASIC256}}==
<syntaxhighlight lang="basic256">arraybase 1
dim array = {{3,4}, {5,11}, {12,8}, {9,5}, {5,6}}
print "The area of the polygon = "; Shoelace(array)
end
function Shoelace(p)
sum = 0
for i = 1 to p[?][] -1
sum += p[i][1] * p[i +1][2]
sum -= p[i +1][1] * p[i][2]
next i
sum += p[i][1] * p[1][2]
sum -= p[1][1] * p[i][2]
return abs(sum) \ 2
end function</syntaxhighlight>
=={{header|C}}==
Reads the points from a file whose name is supplied via the command line, prints out usage if invoked incorrectly.
<syntaxhighlight lang="c">
#include<stdlib.h>
#include<stdio.h>
Line 133 ⟶ 376:
return 0;
}
</syntaxhighlight>
Input file, first line specifies number of points followed by the ordered vertices set with one vertex on each line.
<pre>
Line 148 ⟶ 391:
The polygon area is 30.000000 square units.
</pre>
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
namespace ShoelaceFormula {
using Point = Tuple<double, double>;
class Program {
static double ShoelaceArea(List<Point> v) {
int n = v.Count;
double a = 0.0;
for (int i = 0; i < n - 1; i++) {
a += v[i].Item1 * v[i + 1].Item2 - v[i + 1].Item1 * v[i].Item2;
}
return Math.Abs(a + v[n - 1].Item1 * v[0].Item2 - v[0].Item1 * v[n - 1].Item2) / 2.0;
}
static void Main(string[] args) {
List<Point> v = new List<Point>() {
new Point(3,4),
new Point(5,11),
new Point(12,8),
new Point(9,5),
new Point(5,6),
};
double area = ShoelaceArea(v);
Console.WriteLine("Given a polygon with vertices [{0}],", string.Join(", ", v));
Console.WriteLine("its area is {0}.", area);
}
}
}</syntaxhighlight>
{{out}}
<pre>Given a polygon with vertices [(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)],
its area is 30.</pre>
=={{header|C++}}==
{{trans|D}}
<
#include <tuple>
#include <vector>
Line 181 ⟶ 460:
auto ans = shoelace(points);
cout << ans << endl;
}</
{{out}}
<pre>30</pre>
=={{header|
<syntaxhighlight lang="cowgol">include "cowgol.coh";
typedef Coord is uint16; # floating point types are not supported
record Point is
x: Coord;
y: Coord;
end record;
sub shoelace(p: [Point], length: intptr): (area: Coord) is
var left: Coord := 0;
var right: Coord := 0;
var y0 := p.y;
var x0 := p.x;
while length > 1
var xp
var yp := p.y;
p := @next p;
right := right + yp * p.x;
length := length - 1;
end loop;
left := left + y0 * p.x;
right := right + x0 * p.y;
if left < right then
area := right - left;
else
area := left - right;
end if;
area := area / 2;
end sub;
var polygon: Point[] := {{3,4},{5,11},{12,8},{9,5},{5,6}};
print_i16(shoelace(&polygon[0], @sizeof polygon));
print_nl();</syntaxhighlight>
{{out}}
<pre>30</pre>
=={{header|D}}==
<
Point[] pnts = [{3,4}, {5,11}, {12,8}, {9,5}, {5,6}];
Line 251 ⟶ 536:
auto ans = shoelace(pnts);
assert(ans == 30);
}</
{{out}}
<pre>30</pre>
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
In keeping with the principles of modularity and reusability, the problem has been broken down into subroutines that can process any polygon. In other words, the subroutines don't just solve the area of one polygon; they can find the area of any polygon.
<syntaxhighlight lang="Delphi">
{Create a 2D vector type}
type T2DVector = record
X, Y: double;
end;
{Test polygon}
var Polygon: array [0..4] of T2DVector =
((X:3; Y:4), (X:5; Y:11), (X:12; Y:8), (X:9; Y:5), (X:5; Y:6));
function GetPolygonArea(Polygon: array of T2DVector): double;
{Return the area of the polygon }
{K = [(x1y2 + x2y3 + x3y4 + ... + xny1) - (x2y1 + x3y2 + x4y3 + ... + x1yn)]/2}
var I,Inx: integer;
var P1,P2: T2DVector;
var Sum1,Sum2: double;
begin
Result:=0;
Sum1:=0; Sum2:=0;
for I:=0 to Length(Polygon)-1 do
begin
{Vector back to the beginning}
if I=(Length(Polygon)-1) then Inx:=0
else Inx:=I+1;
P1:=Polygon[I];
P2:=Polygon[Inx];
Sum1:=Sum1 + P1.X * P2.Y;
Sum2:=Sum2 + P2.X * P1.Y;
end;
Result:=abs((Sum1 - Sum2)/2);
end;
procedure ShowPolygon(Poly: array of T2DVector; Memo: TMemo);
var I: integer;
var S: string;
begin
S:='';
for I:=0 to High(Poly) do
S:=S+Format('(%2.1F, %2.1F) ',[Poly[I].X, Poly[I].Y]);
Memo.Lines.Add(S);
end;
procedure ShowPolygonArea(Memo: TMemo);
var Area: double;
begin
ShowPolygon(Polygon,Memo);
Area:=GetPolygonArea(Polygon);
Memo.Lines.Add('Area: '+FloatToStrF(Area,ffFixed,18,2));
end;
</syntaxhighlight>
{{out}}
<pre>
(3.0, 4.0) (5.0, 11.0) (12.0, 8.0) (9.0, 5.0) (5.0, 6.0)
Area: 30.00
Elapsed Time: 3.356 ms.
</pre>
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
proc shoelace . p[][] res .
sum = 0
for i = 1 to len p[][] - 1
sum += p[i][1] * p[i + 1][2]
sum -= p[i + 1][1] * p[i][2]
.
sum += p[i][1] * p[1][2]
sum -= p[1][1] * p[i][2]
res = abs sum / 2
.
data[][] = [ [ 3 4 ] [ 5 11 ] [ 12 8 ] [ 9 5 ] [ 5 6 ] ]
shoelace data[][] res
print res
</syntaxhighlight>
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">
def shoelace(points) do
points
|> Enum.reduce({0, List.last(points)}, fn {x1, y1}, {sum, {x0, y0}} ->
{sum + (y0 * x1 - x0 * y1), {x1, y1}}
end)
|> elem(0)
|> div(2)
end
</syntaxhighlight>
=={{header|F_Sharp|F#}}==
<
// Shoelace formula for area of polygon. Nigel Galloway: April 11th., 2018
let fN(n::g) = abs(List.pairwise(n::g@[n])|>List.fold(fun n ((nα,gα),(nβ,gβ))->n+(nα*gβ)-(gα*nβ)) 0.0)/2.0
printfn "%f" (fN [(3.0,4.0); (5.0,11.0); (12.0,8.0); (9.0,5.0); (5.0,6.0)])</
{{out}}
<pre>
Line 267 ⟶ 650:
=={{header|Factor}}==
By constructing a <code>circular</code> from a sequence, we can index elements beyond the length of the sequence, wrapping around to the beginning. We can also change the beginning of the sequence to an arbitrary index. This allows us to use <code>2map</code> to cleanly obtain a sum.
<
IN: rosetta-code.shoelace
Line 283 ⟶ 666:
[ shoelace-sum ] 2bi@ - abs 2 / ;
input shoelace-area .</
{{out}}
<pre>
Line 293 ⟶ 676:
Except for the use of "END FUNCTION ''name'' instead of just END, and the convenient function SUM with array span expressions (so SUM(P) rather than a DO-loop to sum the elements of array P), both standardised with F90, this would be acceptable to F66, which introduced complex number arithmetic. Otherwise, separate X and Y arrays would be needed, but complex numbers seemed convenient seeing as (x,y) pairs are involved. But because the MODULE facility of F90 has not been used, routines invoking functions must declare the type of the function names, especially if the default types are unsuitable, as here. In function AREA, the x and y parts are dealt with together, but in AREASL they might be better as separate arrays, thus avoiding the DIMAG and DBLE functions to extract the x and y parts. Incidentally, the x and y parts can be interchanged and the calculation still works. Comparing the two resulting areas might give some indication of their accuracy.
If the MODULE protocol were used, the size of an array parameter is passed as a secret additional parameter accessible via the special function UBOUND, but otherwise it must be passed as an explicit parameter. A quirk of the compiler requires that N be declared before it appears in <code>DOUBLE COMPLEX P(N)</code> so as it is my practice to declare parameters in the order specified, here N comes before P. However, it is not clear whether specifying P(N) does much good (as in array index checking) as an alternative is to specify P(*) meaning merely that the array has one dimension, or even P(12345) to the same effect, with no attention to the actual numerical value. See for example [[Array_length#Fortran]] <
C Uses the mid-point rule for integration. Consider the line joining (x1,y1) to (x2,y2)
C The area under that line (down to the x-axis) is the y-span midpoint (y1 + y2)/2 times the width (x2 - x1)
Line 342 ⟶ 725:
A2 = AREASL(5,POINT)
WRITE (6,*) "A=",A1,A2
END</
Output: WRITE (6,*) means write to output unit six (standard output) with free-format (the *). Note the different sign convention.
Line 356 ⟶ 739:
===Fortran I===
In orginal FORTRAN 1957:
<
C SHOELACE FORMULA FOR POLYGONAL AREA
DIMENSION X(33),Y(33)
Line 367 ⟶ 750:
DO 2 I=1,N
2 A=A+X(I)*Y(I+1)-X(I+1)*Y(I)
A=ABSF(A/2.)
PRINT 303,A
STOP
Line 374 ⟶ 757:
303 FORMAT(F10.2)
</syntaxhighlight>
{{in}}
<pre>
Line 390 ⟶ 773:
=={{header|FreeBASIC}}==
<
' compile with: fbc -s console
Line 422 ⟶ 805:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre>The area of the polygon = 30</pre>
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Shoelace_formula_for_polygonal_area}}
'''Solution'''
[[File:Fōrmulæ - Shoelace formula 01.png]]
'''Test case'''
[[File:Fōrmulæ - Shoelace formula 02.png]]
[[File:Fōrmulæ - Shoelace formula 03.png]]
=={{header|Go}}==
<
import "fmt"
Line 445 ⟶ 842:
func main() {
fmt.Println(shoelace([]point{{3, 4}, {5, 11}, {12, 8}, {9, 5}, {5, 6}}))
}</
{{out}}
<pre>
Line 452 ⟶ 849:
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.Bifunctor (bimap)
----------- SHOELACE FORMULA FOR POLYGONAL AREA ----------
-- The area of a polygon formed by
-- the list of (x, y) coordinates.
shoelace :: [(Double, Double)] -> Double
shoelace
let calcSums ((x, y), (a, b)) = bimap (x * b +) (a * y +)
in (/ 2)
. abs
. foldr calcSums (0, 0)
. (<*>) zip (tail . cycle)
--------------------------- TEST -------------------------
main :: IO ()
main =
print $
shoelace [(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)]</syntaxhighlight>
{{out}}
<pre>30.0</pre>
Line 470 ⟶ 877:
Implementation:
<
0.5*|+/((* 1&|.)/ - (* _1&|.)/)|:y
)</
Task example:
<
30</
Exposition:
Line 483 ⟶ 890:
We start with our list of coordinate pairs
<
3 4
5 11
12 8
9 5
5 6</
But the first thing we do is transpose them so that x coordinates and y coordinates are the two items we are working with:
<
3 5 12 9 5
4 11 8 5 6</
We want to rotate the y list by one (in each direction) and multiply the x list items by the corresponding y list items. Something like this, for example:
<
33 40 60 54 20</
Or, rephrased:
<
33 40 60 54 20</
We'll be subtracting what we get when we rotate in the other direction, which looks like this:
<
15 20 _72 _18 _5</
Finally, we add up that list, take the absolute value (there are contexts where signed area is interesting - for example, some graphics application - but that was not a part of this task) and divide that by 2.
Line 516 ⟶ 923:
{{trans|Kotlin}}
{{works with|Java|9}}
<
public class ShoelaceFormula {
Line 554 ⟶ 961:
System.out.printf("its area is %f,%n", area);
}
}</
{{out}}
<pre>Given a polygon with vertices [(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)],
its area is 30.000000,</pre>
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">(() => {
"use strict";
// ------- SHOELACE FORMULA FOR POLYGONAL AREA -------
// shoelaceArea :: [(Float, Float)] -> Float
const shoeLaceArea = vertices => abs(
uncurry(subtract)(
ap(zip)(compose(tail, cycle))(
vertices
)
.reduce(
(a, x) => [0, 1].map(b => {
const n = Number(b);
return a[n] + (
x[0][n] * x[1][Number(!b)]
);
}),
[0, 0]
)
)
) / 2;
// ----------------------- TEST -----------------------
const main = () => {
const ps = [
[3, 4],
[5, 11],
[12, 8],
[9, 5],
[5, 6]
];
return [
"Polygonal area by shoelace formula:",
`${JSON.stringify(ps)} -> ${shoeLaceArea(ps)}`
]
.join("\n");
};
// ---------------- GENERIC FUNCTIONS -----------------
// abs :: Num -> Num
const abs = x =>
// Absolute value of a given number
// without the sign.
0 > x ? -x : x;
// ap :: (a -> b -> c) -> (a -> b) -> (a -> c)
const ap = f =>
// Applicative instance for functions.
// f(x) applied to g(x).
g => x => f(x)(
g(x)
);
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
// cycle :: [a] -> Generator [a]
const cycle = function* (xs) {
// An infinite repetition of xs,
// from which an arbitrary prefix
// may be taken.
const lng = xs.length;
let i = 0;
while (true) {
yield xs[i];
i = (1 + i) % lng;
}
};
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
"GeneratorFunction" !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
// subtract :: Num -> Num -> Num
const subtract = x =>
y => y - x;
// tail :: [a] -> [a]
const tail = xs =>
// A new list consisting of all
// items of xs except the first.
"GeneratorFunction" !== xs.constructor
.constructor.name ? (
Boolean(xs.length) ? (
xs.slice(1)
) : undefined
) : (take(1)(xs), xs);
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => "GeneratorFunction" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}).flat();
// uncurry :: (a -> b -> c) -> ((a, b) -> c)
const uncurry = f =>
// A function over a pair, derived
// from a curried function.
(...args) => {
const [x, y] = Boolean(args.length % 2) ? (
args[0]
) : args;
return f(x)(y);
};
// zip :: [a] -> [b] -> [(a, b)]
const zip = xs => ys => {
const
n = Math.min(length(xs), length(ys)),
vs = take(n)(ys);
return take(n)(xs)
.map((x, i) => [x, vs[i]]);
};
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre>Polygonal area by shoelace formula:
[[3,4],[5,11],[12,8],[9,5],[5,6]] -> 30</pre>
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
===={{trans|Wren}}====
<syntaxhighlight lang="jq"># jq's length applied to a number is its absolute value.
def shoelace:
. as $a
| reduce range(0; length-1) as $i (0;
. + $a[$i][0]*$a[$i+1][1] - $a[$i+1][0]*$a[$i][1] )
| (. + $a[-1][0]*$a[0][1] - $a[0][0]*$a[-1][1])|length / 2;
[ [3, 4], [5, 11], [12, 8], [9, 5], [5, 6] ]
| "The polygon with vertices at \(.) has an area of \(shoelace)."</syntaxhighlight>
{{out}}
<pre>
The polygon with vertices at [[3,4],[5,11],[12,8],[9,5],[5,6]] has an area of 30.
</pre>
===={{trans|Julia}}====
<syntaxhighlight lang="jq">def zip_shoelace:
def sumprod: reduce .[] as [$x,$y] (0; . + ($x * $y));
. as {$x, $y}
| [$x, ($y[1:] + [$y[0]])] | transpose | sumprod as $a
| [($x[1:] + [$x[0]]), $y] | transpose | sumprod as $b
| ($a - $b) | length / 2;
{x: [3, 5, 12, 9, 5], y: [4, 11, 8, 5, 6] }
| zip_shoelace</syntaxhighlight>
{{out}}
As above.
=={{header|Julia}}==
Line 563 ⟶ 1,165:
{{trans|Python}}
<
Assumes x,y points go around the polygon in one direction.
"""
Line 571 ⟶ 1,173:
x, y = [3, 5, 12, 9, 5], [4, 11, 8, 5, 6]
@show x y shoelacearea(x, y)</
{{out}}
Line 579 ⟶ 1,181:
=={{header|Kotlin}}==
<
class Point(val x: Int, val y: Int) {
Line 601 ⟶ 1,203:
println("Given a polygon with vertices at $v,")
println("its area is $area")
}</
{{out}}
Line 608 ⟶ 1,210:
its area is 30.0
</pre>
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
{def shoelace
{lambda {:pol}
{abs
{/
{-
{+ {S.map {{lambda {:pol :i} {* {car {A.get :i :pol}}
{cdr {A.get {+ :i 1} :pol}}}} :pol}
{S.serie 0 {- {A.length :pol} 2}}}
{* {car {A.get {- {A.length :pol} 1} :pol}}
{cdr {A.get 0 :pol}}}}
{+ {S.map {{lambda {:pol :i} {* {car {A.get {+ :i 1} :pol}}
{cdr {A.get :i :pol}}}} :pol}
{S.serie 0 {- {A.length :pol} 2}}}
{* {car {A.get 0 :pol}}
{cdr {A.get {- {A.length :pol} 1} :pol}}}}} 2}}}}
-> shoelace
{def pol
{A.new {cons 3 4}
{cons 5 11}
{cons 12 8}
{cons 9 5}
{cons 5 6}}}
-> pol = [(3 4),(5 11),(12 8),(9 5),(5 6)]
{shoelace {pol}}
-> 30
</syntaxhighlight>
=={{header|Lua}}==
<
local function det2(i,j)
return ps[i][1]*ps[j][2]-ps[j][1]*ps[i][2]
Line 617 ⟶ 1,250:
for i=1,#ps-1 do sum = sum + det2(i,i+1)end
return math.abs(0.5 * sum)
end</
Using an accumulator helper inner function
<
local function ssum(acc, p1, p2, ...)
if not p2 or not p1 then
Line 631 ⟶ 1,264:
local p = {{3,4}, {5,11}, {12,8}, {9,5}, {5,6}}
print(shoeArea(p))-- 30 </
both version handle special cases of less than 3 point as 0 area result.
=={{header|
<syntaxhighlight lang="maple">
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);
</syntaxhighlight>
{{out}}<pre>
30
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Geometry objects built-in in the Wolfram Language
<
{{out}}
<pre>30</pre>
=={{header|min}}==
{{works with|min|0.19.3}}
<syntaxhighlight lang="min">((((first) map) ((last) map)) cleave) :dezip
(((first) (rest)) cleave append) :rotate
((0 <) (-1 *) when) :abs
(
=b =a a size :n 0 :i () =list
(i n <) (
a i get b i get ' prepend list append #list
i succ @i
) while list
) :rezip
(rezip (-> *) map sum) :cross-sum
(
((dezip rotate) (dezip swap rotate)) cleave
((id) (cross-sum) (id) (cross-sum)) spread
- abs 2 /
) :shoelace
((3 4) (5 11) (12 8) (9 5) (5 6)) shoelace print</syntaxhighlight>
{{out}}
<pre>
30.0
</pre>
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">shoelace = function(vertices)
sum = 0
points = vertices.len
for i in range(0,points-2)
sum = sum + vertices[i][0]*vertices[i+1][1]
end for
sum = sum + vertices[points-1][0]*vertices[0][1]
for i in range(points-1,1)
sum = sum - vertices[i][0]*vertices[i-1][1]
end for
sum = sum - vertices[0][0]*vertices[points-1][1]
return abs(sum)/2
end function
verts = [[3,4],[5,11],[12,8],[9,5],[5,6]]
print "The polygon area is " + shoelace(verts)
</syntaxhighlight>
{{out}}
<pre>
The polygon area is 30
</pre>
=={{header|Modula-2}}==
<
FROM RealStr IMPORT RealToStr;
FROM FormatString IMPORT FormatString;
Line 696 ⟶ 1,452:
ReadChar;
END ShoelaceFormula.</
=={{header|
<syntaxhighlight lang="nim">type
x: float
y: float
func shoelace(points: openArray[Point]): float =
var leftSum, rightSum = 0.0
for i in 0..<len(points):
var j = (i + 1) mod len(points)
leftSum += points[i].x * points[j].y
rightSum += points[j].x * points[i].y
0.5 * abs(leftSum - rightSum)
var points = [(3.0, 4.0), (5.0, 11.0), (12.0, 8.0), (9.0, 5.0), (5.0, 6.0)]
echo shoelace(points)</syntaxhighlight>
{{out}}
<pre>30.0</pre>
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
sub area_by_shoelace {
my $area;
our @p;
$#_ > 0 ? @p = @_ : (local *p = shift);
$area += $p[$_][0] * $p[($_+1)%@p][1] for 0 .. @p-1;
$area -= $p[$_][1] * $p[($_+1)%@p][0] for 0 .. @p-1;
return abs $area/2;
}
say area_by_shoelace( [3,4], [5,11], [12,8], [9,5], [5,6] );
say area_by_shoelace( [ [3,4], [5,11], [12,8], [9,5], [5,6] ] );
say area_by_shoelace( @poly );
say area_by_shoelace( \@poly );</syntaxhighlight>
{{out}}
<pre>30
30
30
30</pre>
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">X</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Y</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">shoelace</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)></span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">}}</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">shoelace</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
30
</pre>
An alternative solution, which does not need the X,Y enum, and gives the same output:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">shoelace</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">j</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">*</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">}}</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">shoelace</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
=={{header|PowerBASIC}}==
{{Trans|Visual Basic}}
<syntaxhighlight lang="powerbasic">#COMPILE EXE
#DIM ALL
#COMPILER PBCC 6
FUNCTION ShoelaceArea(x() AS DOUBLE, y() AS DOUBLE) AS DOUBLE
LOCAL i, j AS LONG
LOCAL Area AS DOUBLE
j = UBOUND(x())
FOR i = LBOUND(x()) TO UBOUND(x())
Area += (y(j) + y(i)) * (x(j) - x(i))
j = i
NEXT i
FUNCTION = ABS(Area) / 2
END FUNCTION
FUNCTION PBMAIN () AS LONG
REDIM x(0 TO 4) AS DOUBLE, y(0 TO 4) AS DOUBLE
ARRAY ASSIGN x() = 3, 5, 12, 9, 5
ARRAY ASSIGN y() = 4, 11, 8, 5, 6
CON.PRINT STR$(ShoelaceArea(x(), y()))
CON.WAITKEY$
END FUNCTION</syntaxhighlight>
{{out}}
<pre>30</pre>
=={{header|Python}}==
===Python: Explicit===
<syntaxhighlight 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]))
Line 769 ⟶ 1,583:
>>> area_by_shoelace(x, y)
30.0
>>>
</syntaxhighlight>
===Python: numpy===
<syntaxhighlight lang="python">
# Even simpler:
# In python we can take an advantage of that x[-1] refers to the last element in an array, same as x[N-1].
# Introducing the index i=[0,1,2,...,N-1]; i-1=[-1,0,...,N-2]; N is the number of vertices of a polygon.
# Thus x[i] is a sequence of the x-coordinate of the polygon vertices, x[i-1] is the sequence shifted by 1 index.
# Note that the shift must be negative. The positive shift x[i+1] results in an error: x[N] index out of bound.
import numpy as np
# x,y are arrays containing coordinates of the polygon vertices
x=np.array([3,5,12,9,5])
y=np.array([4,11,8,5,6])
i=np.arange(len(x))
#Area=np.sum(x[i-1]*y[i]-x[i]*y[i-1])*0.5 # signed area, positive if the vertex sequence is counterclockwise
Area=np.abs(np.sum(x[i-1]*y[i]-x[i]*y[i-1])*0.5) # one line of code for the shoelace formula
# Remember that applying the Shoelace formula
# will result in a loss of precision if x,y have big offsets.
# Remove the offsets first, e.g.
# x=x-np.mean(x);y=y-np.mean(y)
# or
# x=x-x[0];y=y-y[0]
# before applying the Shoelace formula.
</syntaxhighlight>
===Python: Defined in terms of reduce and cycle===
{{Trans|Haskell}}
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Polygonal area by shoelace formula'''
from itertools import cycle, islice
from functools import reduce
from operator import sub
# --------- SHOELACE FORMULA FOR POLYGONAL AREA ----------
# shoelaceArea :: [(Float, Float)] -> Float
def shoelaceArea(xys):
'''Area of polygon with vertices
at (x, y) points in xys.
'''
def go(a, tpl):
l, r = a
(x, y), (dx, dy) = tpl
return l + x * dy, r + y * dx
return abs(sub(*reduce(
go,
zip(
xys,
islice(cycle(xys), 1, None)
),
(0, 0)
))) / 2
# ------------------------- TEST -------------------------
# main :: IO()
def main():
'''Sample calculation'''
ps = [(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)]
print(__doc__ + ':')
print(repr(ps) + ' -> ' + str(shoelaceArea(ps)))
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>Polygonal area by shoelace formula:
[(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)] -> 30.0</pre>
===Python: Alternate===
This adopts the ''indexing'' used in the numpy example above, but does not require the numpy library.
<syntaxhighlight lang="python">>>> def area_by_shoelace2(x, y):
return abs(sum(x[i-1]*y[i]-x[i]*y[i-1] for i in range(len(x)))) / 2.
>>> points = [(3,4), (5,11), (12,8), (9,5), (5,6)]
>>> x, y = zip(*points)
>>> area_by_shoelace2(x, y)
30.0
>>> </syntaxhighlight>
=={{header|Racket}}==
<
(struct P (x y))
Line 785 ⟶ 1,684:
(module+ main
(area (P 3 4) (P 5 11) (P 12 8) (P 9 5) (P 5 6)))</
{{out}}
<pre>30</pre>
=={{header|Raku}}==
(formerly Perl 6)
===Index and mod offset===
{{works with|Rakudo|2017.07}}
<syntaxhighlight lang="raku" line>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) ] );</syntaxhighlight>
{{out}}
<pre>30</pre>
===Slice and rotation===
{{works with|Rakudo|2017.07}}
<syntaxhighlight lang="raku" line>sub area-by-shoelace ( @p ) {
my @x := @p».[0];
my @y := @p».[1];
my $s := ( @x Z* @y.rotate( 1) ).sum
- ( @x Z* @y.rotate(-1) ).sum;
return $s.abs / 2;
}
say area-by-shoelace( [ (3,4), (5,11), (12,8), (9,5), (5,6) ] );
</syntaxhighlight>
{{out}}
<pre>30</pre>
=={{header|REXX}}==
<!--
===endpoints as exceptions===
<
parse arg pts; $polygon = 'polygon area of
if pts='' then pts= '(3,4),(5,11),(12,8),(9,5),(5,6)' /*Not specified? Use default. */
do
parse var @ '(' x.
end /*
A=
do j=1 for
jm=j-1; if jm==0 then jm=
A=A + x.j * (y.jp - y.jm) /*compute a part of the area. */
end /*j*/
say $polygon # " points: " pts ' is ───► ' abs(A/2) /*stick a fork in it, we're done*/</syntaxhighlight>
{{out|output|text= when using the default input:}}
<pre>
polygon area of 5 points: (3,4),(5,11),(12,8),(9,5),(5,6) is ───► 30
</pre>
!-->
===
<syntaxhighlight lang="rexx">/*REXX program uses a Shoelace formula to calculate the area of an N─sided polygon.*/
parse arg $; if $='' then $= "(3,4),(5,11),(12,8),(9,5),(5,6)" /*Use the default?*/
A= 0; @= space($, 0) /*init A; elide blanks from pts.*/
do #=1 until @==''; parse var @ '(' x.# "," y.# ')' "," @
z= #+1; y.0= y.#; y.z= y.1 /*define low & high Y end points*/
end /*j*/
say 'polygon area of ' #
{{out|output|text= when using the default input:}}
<pre>
polygon area of 5 points: (3,4),(5,11),(12,8),(9,5),(5,6) is ───► 30
</pre>
===somewhat simplified===
reformatted and suitable for ooRexx. (x.0 etc. not needed)
<syntaxhighlight lang="text">/*REXX program uses a Shoelace formula to calculate the area of an N-sided polygon. */
parse arg pts /*obtain optional arguments from the CL*/
if pts='' then pts= '(3,4),(5,11),(12,8),(9,5),(5,6)' /*Not specified? Use default. */
Line 850 ⟶ 1,774:
end
A=abs(A/2) /*obtain half of the ¦ A ¦ sum*/
say 'polygon area of' n 'points:' pts 'is --->' A</
{{out}}
<pre>polygon area of 5 points: (3,4),(5,11),(12,8),(9,5),(5,6) is ---> 30</pre>
Line 856 ⟶ 1,780:
===even simpler===
Using the published algorithm
<syntaxhighlight lang="text">/*REXX program uses a Shoelace formula to calculate the area of an N-sided polygon. */
parse arg pts /*obtain optional arguments from the CL*/
if pts='' then pts= '(3,4),(5,11),(12,8),(9,5),(5,6)' /*Not specified? Use default. */
Line 870 ⟶ 1,794:
a=a+x.n*y.1-x.1*y.n
a=abs(a)/2
say 'polygon area of' n 'points:' pts 'is --->' a</
{{out}}
<pre>polygon area of 5 points: (3,4),(5,11),(12,8),(9,5),(5,6) is ---> 30</pre>
=={{header|Ring}}==
<
# Project : Shoelace formula for polygonal area
Line 890 ⟶ 1,814:
sum = sum - p[1][1] * p[i][2]
return fabs(sum) / 2
</syntaxhighlight>
Output:
<pre>
The area of the polygon = 30
</pre>
=={{header|RPL}}==
{| class="wikitable"
! RPL code
! Comment
|-
|
≪
DUP 1 GET +
0 2 3 PICK SIZE '''FOR''' j
OVER j GET LAST 1 - GET
OVER RE OVER IM * SWAP RE ROT IM * - +
'''NEXT'''
ABS 2 / SWAP DROP
≫ <span style="color:blue">''''SHOEL''''</span> STO
|
<span style="color:blue">'''SHOEL'''</span> ''( { (vertices) } → area ) ''
append 1st vertice at the end
sum = 0 ; loop
get 2 vertices
sum += determinant
end loop
finalize calculation, clean stack
return area
|}
{(3,4) (5,11) (12,8) (9,5) (5,6)} <span style="color:blue">'''SHOEL'''</span>
{{out}}
<pre>
1: 30
</pre>
=={{header|Ruby}}==
<
Point = Struct.new(:x,:y) do
Line 914 ⟶ 1,868:
def area
points = @points + [@points.first]
points.each_cons(2).
end
Line 920 ⟶ 1,874:
puts Polygon.new([3,4], [5,11], [12,8], [9,5], [5,6]).area # => 30.0
</syntaxhighlight>
=={{header|Scala}}==
<
case class Polygon( pp:List[Point] ) {
Line 951 ⟶ 1,904:
println( "Area of " + p + " = " + p.area )
}
</syntaxhighlight>
{{out}}
<pre>Area of Polygon( (3,4), (5,11), (12,8), (9,5), (5,6) ) = 30.0</pre>
=={{header|Sidef}}==
{{trans|
<
var x = p.map{_[0]}
var y = p.map{_[1]}
Line 969 ⟶ 1,922:
}
say area_by_shoelace([3,4], [5,11], [12,8], [9,5], [5,6])</
{{out}}
<pre>
30
</pre>
=={{header|Swift}}==
{{trans|Scala}}
<syntaxhighlight lang="swift">import Foundation
struct Point {
var x: Double
var y: Double
}
extension Point: CustomStringConvertible {
var description: String {
return "Point(x: \(x), y: \(y))"
}
}
struct Polygon {
var points: [Point]
var area: Double {
let xx = points.map({ $0.x })
let yy = points.map({ $0.y })
let overlace = zip(xx, yy.dropFirst() + yy.prefix(1)).map({ $0.0 * $0.1 }).reduce(0, +)
let underlace = zip(yy, xx.dropFirst() + xx.prefix(1)).map({ $0.0 * $0.1 }).reduce(0, +)
return abs(overlace - underlace) / 2
}
init(points: [Point]) {
self.points = points
}
init(points: [(Double, Double)]) {
self.init(points: points.map({ Point(x: $0.0, y: $0.1) }))
}
}
let poly = Polygon(points: [
(3,4),
(5,11),
(12,8),
(9,5),
(5,6)
])
print("\(poly) area = \(poly.area)")</syntaxhighlight>
{{out}}
<pre>Polygon(points: [Point(x: 3.0, y: 4.0), Point(x: 5.0, y: 11.0), Point(x: 12.0, y: 8.0), Point(x: 9.0, y: 5.0), Point(x: 5.0, y: 6.0)]) area = 30.0</pre>
=={{header|TI-83 BASIC}}==
{{works with|TI-83 BASIC|TI-84Plus 2.55MP}}
<
Dim([A])->N:0->A
For(I,1,N)
Line 983 ⟶ 1,988:
A+[A](I,1)*[A](J,2)-[A](J,1)*[A](I,2)->A
End
Abs(A)/2->A</
{{out}}
<pre>
30
</pre>
=={{header|VBA}}==
{{trans|Phix}}<
Public Enum axes
u = 1
Line 1,015 ⟶ 2,019:
Next i
Debug.Print shoelace(tcol)
End Sub</
<pre>30</pre>
=={{header|VBScript}}==
<syntaxhighlight lang="vb">' Shoelace formula for polygonal area - VBScript
Dim points, x(),y()
points = Array(3,4, 5,11, 12,8, 9,5, 5,6)
n=(UBound(points)+1)\2
Redim x(n+1),y(n+1)
j=0
For i = 1 To n
x(i)=points(j)
y(i)=points(j+1)
j=j+2
Next 'i
x(i)=points(0)
y(i)=points(1)
For i = 1 To n
area = area + x(i)*y(i+1) - x(i+1)*y(i)
Next 'i
area = Abs(area)/2
msgbox area,,"Shoelace formula" </syntaxhighlight>
{{out}}
<pre>
30
</pre>
=={{header|Visual Basic}}==
{{works with|Visual Basic|5}}
{{works with|Visual Basic|6}}
{{works with|VBA|Access 97}}
{{works with|VBA|6.5}}
{{works with|VBA|7.1}}
<syntaxhighlight lang="vb">Option Explicit
Public Function ShoelaceArea(x() As Double, y() As Double) As Double
Dim i As Long, j As Long
Dim Area As Double
j = UBound(x())
For i = LBound(x()) To UBound(x())
Area = Area + (y(j) + y(i)) * (x(j) - x(i))
j = i
Next i
ShoelaceArea = Abs(Area) / 2
End Function
Sub Main()
Dim v As Variant
Dim n As Long, i As Long, j As Long
v = Array(3, 4, 5, 11, 12, 8, 9, 5, 5, 6)
n = (UBound(v) - LBound(v) + 1) \ 2 - 1
ReDim x(0 To n) As Double, y(0 To n) As Double
j = 0
For i = 0 To n
x(i) = v(j)
y(i) = v(j + 1)
j = j + 2
Next i
Debug.Print ShoelaceArea(x(), y())
End Sub</syntaxhighlight>
{{out}}
<pre>30</pre>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Option Strict On
Imports Point = System.Tuple(Of Double, Double)
Module Module1
Function ShoelaceArea(v As List(Of Point)) As Double
Dim n = v.Count
Dim a = 0.0
For i = 0 To n - 2
a += v(i).Item1 * v(i + 1).Item2 - v(i + 1).Item1 * v(i).Item2
Next
Return Math.Abs(a + v(n - 1).Item1 * v(0).Item2 - v(0).Item1 * v(n - 1).Item2) / 2.0
End Function
Sub Main()
Dim v As New List(Of Point) From {
New Point(3, 4),
New Point(5, 11),
New Point(12, 8),
New Point(9, 5),
New Point(5, 6)
}
Dim area = ShoelaceArea(v)
Console.WriteLine("Given a polygon with vertices [{0}],", String.Join(", ", v))
Console.WriteLine("its area is {0}.", area)
End Sub
End Module</syntaxhighlight>
{{out}}
<pre>Given a polygon with vertices [(3, 4), (5, 11), (12, 8), (9, 5), (5, 6)],
its area is 30.</pre>
=={{header|Wren}}==
<syntaxhighlight lang="wren">var shoelace = Fn.new { |pts|
var area = 0
for (i in 0...pts.count-1) {
area = area + pts[i][0]*pts[i+1][1] - pts[i+1][0]*pts[i][1]
}
return (area + pts[-1][0]*pts[0][1] - pts[0][0]*pts[-1][1]).abs / 2
}
var pts = [ [3, 4], [5, 11], [12, 8], [9, 5], [5, 6] ]
System.print("The polygon with vertices at %(pts) has an area of %(shoelace.call(pts)).")</syntaxhighlight>
{{out}}
<pre>
The polygon with vertices at [[3, 4], [5, 11], [12, 8], [9, 5], [5, 6]] has an area of 30.
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">proc real Shoelace(N, X, Y);
int N, X, Y;
int S, I;
[S:= 0;
for I:= 0 to N-2 do
S:= S + X(I)*Y(I+1) - X(I+1)*Y(I);
S:= S + X(I)*Y(0) - X(0)*Y(I);
return float(abs(S)) / 2.0;
];
RlOut(0, Shoelace(5, [3, 5, 12, 9, 5], [4, 11, 8, 5, 6]))</syntaxhighlight>
{{out}}
<pre>
30.00000
</pre>
=={{header|zkl}}==
By the "book":
<
xs,ys:=Utils.Helpers.listUnzip(points); // (x,x,...), (y,y,,,)
( xs.zipWith('*,ys[1,*]).sum(0) + xs[-1]*ys[0] -
xs[1,*].zipWith('*,ys).sum(0) - xs[0]*ys[-1] )
.abs().toFloat()/2;
}</
or an iterative solution:
<
xs,ys:=Utils.Helpers.listUnzip(points); // (x,x,...), (y,y,,,)
N:=points.len();
N.reduce('wrap(s,n){ s + xs[n]*ys[(n+1)%N] - xs[(n+1)%N]*ys[n] },0)
.abs().toFloat()/2;
}</
<
areaByShoelace(points).println();
areaByShoelace2(points).println();</
{{out}}
<pre>
|