Intersezione di due triangoli


19

Dati 4 punti sui piani 2D A, B, C, D, calcola l'area della regione di intersezione dei triangoli OABe OCD, dove si Otrova il centro del piano, avendo coordinate (0, 0).

Gli algoritmi che funzionano in costante complessità temporale (in termini di operazioni aritmetiche) sono incoraggiati, ma non forzati.

Regole

  • Ogni punto è rappresentato come due numeri reali, indica le loro coordinate X e Y.
    • Facoltativamente, se il tuo linguaggio di programmazione (o qualche libreria del tuo linguaggio di programmazione) ha un tipo incorporato Pointo equivalente, è consentito prendere l' Pointoggetto come input.
  • L'input è dato come 4 punti, nei formati, incluso ma non limitato a:
    • Un elenco di 8 coordinate.
    • Un elenco di 4 punti, ogni punto può essere rappresentato in qualsiasi formato conveniente.
    • Due liste di 2 punti.
    • eccetera.
  • Non puoi assumere un ordine particolare dei punti (ordine antiorario o orario)
  • Non si può presumere che il punto Osia passato come input. In altre parole, il programma non deve accettare e utilizzare input estranei.
  • Non puoi presumere che tutti i punti siano diversi. In altre parole, i triangoli possono essere degenerati. È inoltre necessario gestire tale caso (vedere i casi di prova di seguito)
  • La differenza assoluta o relativa deve essere inferiore rispetto ai casi di test di esempio riportati di seguito.10-3

Criteri vincenti

Questo è , la risposta più breve in byte vince!

Esempi di casi di test

Ax Ay Bx By Cx Cy Dx Dy area

5 1 1 3 -1 0 0 -1 0
5 1 1 3 -1 0 0 0 0
5 1 1 3 0 0 0 0 0
5 1 1 3 3 4 4 -3 4.50418
5 1 1 3 1 2 2 1 1.5
5 1 1 3 -2 5 4 -2 1.74829
5 1 1 3 -2 5 5 4 2.96154
5 1 1 3 3 5 5 4 1.88462
5 1 1 3 3 5 3 1 3.92308
5 1 1 3 3 5 4 -1 5.26619
5 1 1 3 5 1 4 -1 0
5 1 1 3 5 1 1 3 7
1 3 1 3 5 1 1 3 0
1 3 1 3 1 3 1 3 0
4 8 4 -1 -2 6 -2 -3 0

1.2 3.4 -0.3 4.2 5 7.6 -1.1 2.4 2.6210759326188535
3.1 0.6 0.1 7.2 5.2 0.7 0.9 8 9.018496993987977

Se qualcuno lo desidera, ecco gli output per il primo gruppo di casi di test in forma esatta:

0
0
0
46375/10296
3/2
1792/1025
77/26
49/26
51/13
23345/4433
0
7
0
0
0

Immagine dell'illustrazione per il test case 5 1 1 3 3 4 4 -3(l'area del quadrilatero verde è l'output previsto):

[ Immagine]


Uno dei tuoi casi di test ha 9 input anziché 8. 1.2 3.4 -0.3 4.2 5 3 7.6 -1.1 2.4 0
Kelly Lowder

1
@KellyLowder Risolto.
user202729

Risposte:


16

Wolfram Language (Mathematica) , 55 byte

0&@@Area@BooleanRegion[And,Simplex[{0{,}}~Join~#]&/@#]&

Provalo online!

Rasato qualche byte dalla banale risposta.

%@{{{5, 1}, {1, 3}}, {{3, 4}, {4, -3}}} yields 46375/10296 or 4.504176379

La sostituzione Areacon DiscretizeRegionmostrerà l'intersezione.

inserisci qui la descrizione dell'immagine

A proposito, questo funzionerà con qualsiasi simplex, non solo triangoli.

-1 Byte grazie a JungHwan Min

Il suggerimento di @utente202729 ha aggiunto 4 byte ma lo rende 0 per triangoli degeneri


1
Il poligono può essere sostituito anche con Simplex
Kelly Lowder il

1
Un altro byte: {{0,0}}to {0{,}}(funziona perché l'espressione {Times[0, {Null, Null}]}
restituisce

Esito negativo per questo caso di test , elencato in casi di test di esempio.
user202729,

Ho già notato che questo NON funziona su TIO. Non sono sicuro di quello che hanno sotto il cofano.
Kelly Lowder,

1
Vedo che non funziona per l'intersezione di due linee. Il mio male per saltare quel caso di prova. Tecnicamente questi non sono triangoli. Suppongo che se avremo questo aspetto tecnico, forse dovresti cambiare il titolo del post e la prima frase. Potremmo anche avere una discussione davvero esoterica sul fatto che l'area sia persino definita per un oggetto monodimensionale, ma preferirei di no.
Kelly Lowder,

5

Python 2 + PIL, 341 318 313 284 270 byte

Un ringraziamento speciale a Dennis che ha prontamente aggiunto PIL su TIO
-23 byte grazie a Mr. Xcoder

import PIL.Image as I,PIL.ImageDraw as D
l=[i*1000for i in[0,0]+input()+[0,0]]
z=zip(*[[i-min(t)for i in t]for t in l[::2],l[1::2]])
print sum(map(int.__mul__,*map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),map(I.new,'11',[[max(l)-min(l)]*2]*2),[z[:3],z[3:]])))/1e6

Provalo online! oppure Prova tutti i casi di test

Per calcolare la differenza, ciò disegna letteralmente i triangoli e controlla la quantità di pixel che sono dipinti in entrambe le immagini.
Questo metodo ha inserito un errore di arrotondamento, che viene attenuato aumentando la dimensione dell'immagine.

Spiegazione

#the image/triangles are enlarged to increase the precision
#a pair of zeros are inserted in the start and at the end, this way "l" will have all 6 points to draw the triangles 
l=[i*1000for i in[0,0]+input()+[0,0]]
#split the input in x and y, where x=l[::2] and y=l[1::2]
#get the smallest number on each list, that will be "0" if there is no negative number, to be used as offset.
#this will be used to overcome the fact that PIL won't draw on negative coords
#zip "x" and "y" lists, to create a list containing the points
z=zip(*[[i-min(t)for i in t]for t in x,y])
#create 2 (B&W) blank images
#where the size is the difference between the smallest and the largest coord.
map(I.new,'11',[[max(l)-min(l)]*2]*2)
#draw both triangles and return the pixel list of each image
map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),<result of previous line>,[z[:3],z[3:]])
#count the amount of overlapping pixels by summing the color of each pixel, if the pixel is "1" in both images, then the triangles are overlapping, then the amount of pixels is divided by the initial enlarging factor squared (1e6)
print sum(map(int.__mul__,*<result of previous line>))/1e6
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.