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


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

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



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|


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


-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:.



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


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&(,\)

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


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.