Was ist die Fläche dieses Polygons?

19

Berechnen Sie die Fläche eines Polygons.

Inspiriert von diesem Schnürsenkel-Algorithmus-Video.

Aufgabe

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu erstellen, die die Fläche eines Polygons berechnet. Programm oder Funktion wird gemäß der Standarddefinition in Meta definiert.

Eingang

Sie erhalten die X- und Y-Koordinaten jedes Eckpunkts des Polygons. Sie können die Eingabe als Liste von Tupeln ( [[x1, y1], [x2, y2], etc]), als Matrix oder als flache Liste ( [x1, y1, x2, y2, etc]) annehmen . Es sind auch zwei Listen mit xund yKoordinaten erlaubt. Die Scheitelpunkte sind gegen den Uhrzeigersinn nummeriert und der erste Scheitelpunkt ist derselbe wie der letzte bereitgestellte Scheitelpunkt, wodurch das Polygon geschlossen wird.

Wenn Sie möchten, können Sie die Eingabe ohne den letzten Scheitelpunkt übernehmen (also jede Koordinate nur einmal empfangen).

Sie können davon ausgehen, dass sich die Kanten der Polygone nicht schneiden. Sie können auch davon ausgehen, dass alle Eckpunkte Ganzzahlkoordinaten haben.

Ausgabe

Die Fläche des Polygons. Alle Standardausgabemethoden sind zulässig. Wenn Ihre Sprache keine Gleitkommadivision zulässt und die Lösung keine Ganzzahl ist, können Sie einen Bruch zurückgeben. Die Fraktion muss nicht unbedingt vereinfacht werden, sodass eine Rückgabe 2/4zulässig wäre.

Gewinnkriterium

Kürzester Code gewinnt!

Testfälle

[[4,4],[0,1],[-2,5],[-6,0],[-1,-4],[5,-2],[4,4]]
55

Bildbeschreibung hier eingeben

[[1,1],[0,1],[1,0],[1,1]]
0.5
1/2

Bildbeschreibung hier eingeben

JAD
quelle
Ist die Eingabe wie [x1, x2, x3], [y1, y2, y3]erlaubt?
Programmer5000
@ programmer5000 und Martin Ender, ja, ich bearbeite es in :)
JAD
Ich stimme zu, stimmte für die Wiedereröffnung.
Programmer5000
1
@flawr Ich habe das zu einem Betrüger gemacht. Es handelt sich nicht wirklich um ein Duplikat seines Duplikat-Ziels. Um dieselbe Methode wie hier rekursiv anzuwenden, müssten die Eckpunkte gefunden werden, die Punkte kreuzen, und die resultierenden Teilmengen müssten gegen den Uhrzeigersinn angeordnet werden - das scheint viel komplexer zu sein.
Jonathan Allan

Antworten:

13

Gelee ,  8  6 Bytes

-1 Byte dank Emigna (redundant , ÆḊhat eine linke Tiefe von 2)
-1 Byte dank Emigna (halbieren, HFließkomma ist nicht nötig ÷2)

ṡ2ÆḊSH

Eine monadische Verbindung, die eine Liste von Koordinatenpaaren entgegen dem Uhrzeigersinn gemäß den Beispielen (mit der einen Wiederholung) aufnimmt und den Bereich zurückgibt.

Probieren Sie es online!

Wie?

Wendet den Schnürsenkel-Algorithmus an, genau wie im Video beschrieben (was ich auch gerade gesehen habe!)

ṡ2ÆḊSH - Link: list of [x,y] coordinate pairs anticlockwise & wrapped, p
ṡ2     - all overlapping slices of length 2
  ÆḊ   - determinant (vectorises)
    S  - sum
     H - halve
Jonathan Allan
quelle
Der zweite Testfall gibt für mich '-0.5' zurück: o
JAD
Oh, ich muss es überprüfen ...
Jonathan Allan
Das liegt daran, dass sie als [x,y]Koordinaten eher im Uhrzeigersinn als gegen den Uhrzeigersinn angegeben werden. Eine Eingabe von [[1,1],[0,1],[1,0],[1,1]]wird a zurückgeben 0.5.
Jonathan Allan
1
Woops, ich bearbeite das: D
JAD
1
Auch Hanstelle von÷2
Emigna
29

Mathematica, 13 Bytes

Area@*Polygon
Martin Ender
quelle
Könnte es trivialer werden?
Mr. Xcoder
5
@ Mr.Xcoder Sicher.
Martin Ender
o_O - Ich bin buchstäblich verblüfft ...
Mr. Xcoder
3
Das ist Mathematica für Sie. Alles Mögliche ist in die Sprache eingebaut.
Brian Minton
19

Oktave , 9 Bytes

@polyarea

Eingaben sind ein Vektor mit den x- Werten und ein Vektor mit den y- Werten. Dies funktioniert auch in MATLAB.

Probieren Sie es online!

Luis Mendo
quelle
16

JavaScript (ES6), 69 67 47 Byte

Vielen Dank an @Rick, dass wir den absoluten Wert nicht benötigen, wenn die Scheitelpunkte garantiert gegen den Uhrzeigersinn sortiert werden, und für den Vorschlag, eine flache Liste als Eingabe zu verwenden, um 20 Byte zu sparen!

Nimmt die Eingabe als flache Liste von Scheitelpunkten, einschließlich des letzten Scheitelpunkts.

f=([x,y,...a])=>1/a[0]?x*a[1]/2-y*a[0]/2+f(a):0

Probieren Sie es online!

Wie?

n

einreein=|(x0y1-y0x1)+(x1y2-y1x2)++(xn-1y0-yn-1x0)2|

Arnauld
quelle
Sehr beeindruckend! Könnten Sie erklären, wie es funktioniert?
Rugnir
Die Eckpunkte im zweiten Testfall wurden fälschlicherweise falsch angeordnet. Die abs sollte nicht notwendig sein.
Rick
Sie können auch 7 Bytes sparen, indem Sie in eine flache Liste wechseln:a=>(g=([x,y,...a])=>1-a?0:x*a[1]-y*a[0]+g(a))(a)/2
Rick
@ Rick hat recht - abs ist nicht notwendig. Ohne sie berechnet die Formel den vorzeichenbehafteten Bereich. Dies ist positiv, da die Eckpunkte im Gegenuhrzeigersinn angegeben werden.
Angs
@ Rick Danke! Aktualisiert ... etwa 10 Monate später: /
Arnauld
7

R, 54 52 Bytes

pryr::f({for(i in 2:nrow(x))F=F+det(x[i-1:0,]);F/2})

Was zur Funktion auswertet:

function (x) 
{
    for (i in 2:nrow(x)) F = F + det(x[i - 1:0, ])
    F/2
}

Verwendet die vordefinierten F = FALSE = 0. Implementiert den Schnürsenkel-Algorithmus im verknüpften Video :)

-2 Bytes dank Giuseppe

JAD
quelle
-1 Byte für i+-1:0als Zeilenindex
Giuseppe
@ Giuseppe Nizza. Ich werde das auch entfernen +;)
JAD
6

Python 3 , 72 71 Bytes

from numpy import*
g=lambda x,y:(dot(x[:-1],y[1:])-dot(x[1:],y[:-1]))/2

Nimmt zwei Listen auf, wie es in den Kommentaren erlaubt war

x = [x0,x1,x2, ...]
y = [y0,y1,y2, ...] 

Probieren Sie es online!

Dies ist im Grunde nur die Umsetzung der Schnürsenkel-Formel . Kann ich Pluspunkte für einen Golf bekommen, den Sie tatsächlich so umsetzen würden? : D

-1, dahinter ist kein Leerzeichen erforderlich x,y:.


P. Siehr
quelle
Das Aufnehmen von zwei Listen wird jetzt auch im Hauptteil der Frage erwähnt :)
JAD
@JarkoDubbeldam Äh, ich habe gerade gesehen, dass es den Bereich ausgeben muss. Diese Lösung gibt derzeit nur den Bereich zurück. Ist das auch erlaubt oder soll es gedruckt werden?
P. Siehr
Eine Funktion, die einen Wert
zurückgibt,
Ich denke, dass Sie bei Python nicht einmal die Funktion benennen müssen, also lambda x,y:ist es in Ordnung , einfach mit zu beginnen .
JAD
@ JarkoDubbeldam Gibt es irgendwo Regeln für jede Sprache?
P. Siehr
4

JS (ES6), 98 95 94 93 88 86 82 81 77 73 Bytes

(X,Y)=>{for(i in X){a+=(X[i]+X[i-1])*(Y[i]-Y[i-1]);if(!+i)a=0}return a/2}

Nimmt Eingaben wie [x1, x2, x3], [y1, y2, y3]und überspringt das wiederholte Koordinatenpaar.

-3 Bytes dank @JarkoDubbeldam

-4 Bytes dank @JarkoDubbeldam

-1 Byte dank @ZacharyT

-4 Bytes dank @ZacharyT

-4 Bytes dank @Rick

Taylor Scott
quelle
3

J, 12 Bytes

Angenommen, die Eingabe ist eine Liste von 2 Elementlisten (dh eine Tabelle)

-:+/-/ .*2[\
  • 2[\ - Zerlegt es in die Schnürsenkel Xs, dh überlappende Quadrate von 4 Ulmen
  • -/ .* - die Determinante von jedem
  • +/ - Fasse es zusammen
  • -: - durch 2 teilen

Wenn wir die Eingabe als einzelne Liste erhalten, müssen wir uns zuerst in eine Tabelle umwandeln und erhalten 20 Bytes:

-:+/-/ .*2[\ _2&(,\)
Jona
quelle
1
"Angenommen, die Eingabe ist eine Liste von 2 Elementlisten (dh eine Tabelle)." Dies ist erlaubt :)
JAD
3

MS-SQL, 66 Bytes

SELECT geometry::STPolyFromText('POLYGON('+p+')',0).STArea()FROM g

MS SQL 2008 und höher unterstützen Open Geospatial Consortium (OGC) -Standard-Geodaten / -Funktionen, die ich hier nutze.

Die Eingangsdaten werden in Feld gespeichert p vorbestehender Tabelle g , pro unseren Input - Standards .

Die Eingabe ist ein Textfeld mit geordneten Paaren im folgenden Format: (4 4,0 1,-2 5,-6 0,-1 -4,5 -2,4 4)

Nun, nur zum Spaß, wenn Sie zulassen, dass meine Eingabetabelle Open Geospatial Consortium-Standardgeometrieobjekte enthält (anstatt nur Textdaten), wird dies fast trivial:

--Create and populate input table, not counted in byte total
CREATE TABLE g (p geometry)
INSERT g VALUES (geometry::STPolyFromText('POLYGON((5 5, 10 5, 10 10, 5 5))', 0))

--23 bytes!
SELECT p.STArea()FROM g
BradC
quelle
0

Perl 5 -pa , 62 Bytes

map$\+=$F[$i]*($a[($i+1)%@a]-$a[$i++-1]),@a=eval<>}{$\=abs$\/2

Probieren Sie es online!

Übernimmt die Eingabe als Liste von X-Koordinaten in der ersten Zeile, gefolgt von einer Liste von Y-Koordinaten in der zweiten Zeile.

Xcali
quelle