Determina se una serie di tessere su una griglia forma una forma chiusa


10

Dato un insieme di tessere su una griglia, voglio determinare:

  • Se le tessere formano una figura chiusa
  • Se le tessere formano una figura chiusa quando contate i lati del tabellone come un bordo della figura
  • Se una delle due precedenti affermazioni è vera, quali tessere aggiuntive rientrano nella figura racchiusa si formano le tessere iniziali.

Il giocatore inizierà premendo su una tessera, quindi trascinando il dito su altre tessere per creare una catena di tessere dello stesso colore. Controllerò mentre vado per vedere se la tessera successiva è valida. Ex. Se il giocatore comincia una tessera rossa, la loro unica mossa successiva valida è quella di una tessera rossa adiacente (diagonali fanno conteggio). Quando l'utente alza il dito, devo essere in grado di verificare i 3 elementi sopra.

Quindi il mio pensiero iniziale era che, dato che stavo controllando la validità della catena ogni volta che andavo, quando il giocatore ha alzato il dito ho potuto verificare se la prima e l'ultima tessera erano adiacenti. (So ​​già che sono dello stesso colore.) Se fossero adiacenti avrei avuto la sensazione che avessi fatto una figura chiusa, e sarei venuto qui per provare a vedere se mi mancava qualcosa di grosso, e per ottenere una sorta di prova logica / matematica che il mio sospetto era corretto (o un esempio che lo dimostrava errato).

Ma fu allora che pensai all'articolo numero 2: devo anche tenere conto delle catene che usano un bordo della tavola come un lato della figura allegata. In tal caso, il primo e l'ultimo oggetto della catena non sarebbero adiacenti, ma avrei comunque una figura chiusa. Quindi ora sono tornato al punto di partenza, un po '.

Cosa posso fare con questa catena di coordinate della griglia per capire se formano una figura chiusa o no? E una volta che non so di avere una figura allegata, qual è il modo migliore per ottenere un ulteriore elenco di tutte le tessere che cadono dentro i suoi limiti?

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Sopra ho disegnato le foto di ciò che mi aspetto possano essere i 4 possibili risultati di questo test.

  1. La catena non fa una figura chiusa.

  2. La catena fa una figura chiusa.

  3. Se contate i lati della tavola come un bordo (o più di un bordo) della figura, la catena crea una figura chiusa.

  4. La catena crea una figura chiusa, ma ci sono punti dati aggiuntivi (selezionati validamente dall'utente come parte della catena) che non fanno parte della figura creata.

Il caso 4 è il più complicato, perché dovresti estrarre le maglie "extra" per trovare la figura racchiusa e i pezzi che cadono al suo interno (ma non attorno all'area "non chiusa").

Quindi ... Qualcuno ha un'idea di un buon modo per risolvere questo, o solo un punto di partenza per me? Sto andando in tondo a questo punto e potrei usare un'altra serie di occhi.


1
Che dire di intersecare percorsi come una figura 8 o un pentagramma ? Assumeresti la regola di riempimento diverso da zero o pari-dispari ?
Anko,

Il caso 4 potrebbe anche fondersi con il caso 3: Racchiuso usando i lati del tabellone, con ulteriori informazioni
RicaricaPun

Se hai una linea verticale che corre lungo il centro della tavola dal bordo superiore a quello inferiore, quale lato della tavola è 'racchiuso'?
Steven Stadnicki,

Penso che dovremmo supporre che lo spazio più piccolo sia chiuso per ora. A meno che OP non specifichi diversamente.
Tom 'Blue' Piddock,

Risposte:


3

1. Rilevamento di un ciclo di tessere

Il problema sembra simile al rilevamento di un ciclo (loop) in un grafico, vedere qui o qui .

  • L'insieme di nodi Vdi quel grafico G=(V, E)sono le tessere,
  • e = (v1, v2)esiste un bordo tra due nodi diversi, se i riquadri sono vicini diretti o diagonali

2. Gestione della custodia del bordo dello schermo

Il bordo dello schermo è costituito da quelle tessere immaginarie che formerebbero un bordo largo di una tessera attorno allo schermo di tessere visibili.

Secondo le vostre specifiche parte del bordo dello schermo costituirebbe una parte implicita di un circuito chiuso. Solo per rilevare un circuito chiuso, sarebbe sufficiente estendere il grafico Ga un grafico G'onorando la connessione tramite questa regola:

  • esiste un altro bordo tra due nodi diversi, se i due riquadri sono posizionati direttamente vicino al bordo dello schermo

Quindi le tessere in (0,0) e (1,0) farebbero parte di un circuito chiuso, insieme alle "tessere del bordo" (-1,0), (-1, -1), (0, -1) , (1, -1).

3. La parte interna di un'area ad anello

Andrei in una direzione simile a quella suggerita dall'utente Arthur Wulf White :

Limitando il set di tessere che dobbiamo esaminare dal riquadro di selezione delle tessere ad anello.

Quindi, usando un riempimento di inondazione per selezionare tutte le tessere all'interno del riquadro di delimitazione che sono esterne o interne al circuito chiuso. Può essere solo uno di quei due casi. Quale dobbiamo scoprire in seguito.

Anche l'estensione del riquadro di delimitazione di una piastrella in ogni direzione sarebbe una buona idea, dando il risultato extbb, quindi finiamo con un insieme collegato di punti esterni, nel caso in cui abbiamo iniziato il riempimento di inondazione con una piastrella esterna.

Una volta che abbiamo l'area di riempimento dell'inondazione, calcoleremo anche il suo rettangolo di selezione, il ffbb. Nel caso in cui abbiamo iniziato con una piastrella esterna, dovrebbe essere identica al riquadro di delimitazione ad anello esteso.

ffbb == extbb

Nel caso in cui abbiamo iniziato con una tessera interna, dovrebbe produrre un riquadro di delimitazione nettamente più piccolo, poiché le tessere ad anello devono essere inserite tra le due caselle di delimitazione.

ffbb < extbb

La tessera iniziale iniziale per il riempimento di alluvione potrebbe essere qualsiasi tessera all'interno della extbbquale è una tessera libera. Forse sceglierne uno a caso è l'approccio migliore.

Se prima sapessi che l'interno è più piccolo dell'esterno, inizierei intorno al centro della massa dei punti del ciclo che è all'interno per molte aree (esempio contrario: area a forma di C), altrimenti sul bordo del extbb. Ma non ho idea di come stimarlo.

Osservazioni finali

Normalmente direi che una semplice passeggiata a partire da alcune tessere e mantenere un elenco delle tessere visitate sarebbe sufficiente per rilevare un ciclo, ma quella condizione al contorno dello schermo potrebbe produrre un grafico più complicato, quindi dovresti essere al sicuro con un algoritmo grafico .

Di seguito è riportato un esempio in cui l'interno non è collegato, d'altra parte il rilevamento del ciclo dovrebbe trovare due anelli in quel caso, uno dovrebbe essere scartato.

alcuni casi


1

È possibile risolvere questo problema:

  1. Trovare il rettangolo di selezione di quella forma.
  2. Aumentando le dimensioni di 1 in ogni direzione.
  3. Scorrere sul telaio della nuova scatola di delimitazione leggermente ingrandita e applicare riempimento.
  4. Se ci sono tessere che non hai contrassegnato con il riempimento alluvione che non si trovano su quella catena, allora sono racchiuse. Suppongo che per tua definizione se ci sono tessere chiuse rispetto alla forma è una figura chiusa.

Per fare uno, iterare su tutte le tessere sulla catena e trovare la loro minX, minY, maxXed maxYe questo è il vostro casella di delimitazione o AABB.

Due è banale.

L'iterazione sul telaio è semplice, assicurati di non riempire completamente la griglia. Puoi imparare come riempire inondazioni in Wikipedia .

Per il numero quattro puoi iniziare controllando solo le tessere adiacenti alla catena. È possibile riempire inondazioni da qualsiasi riquadro non contrassegnato per individuare più riquadri.


0

La tua intuizione è corretta, supponendo che la catena finisca non appena l'utente tenta di selezionare una tessera che ha già selezionato. In tal caso, la forma in generale sembra un lazo, nella tua foto (4). Se riescono a continuare a scorrere, possono disegnare molti loop e le cose si complicano. Quello che vuoi fare è rispondere alla domanda dei punti poligonali .

Innanzitutto, dobbiamo definire il problema. Presumo che la situazione assomigli a (2), ovvero che ogni coda sia stata spogliata e che la fine si ricolleghi all'inizio, in modo che ogni tessera abbia esattamente un "predecessore" e esattamente un "successore" nella catena (dove il predecessore del successore della tessera X è sempre la tessera X). Inoltre, se segui i "successori" abbastanza a lungo, alla fine torni da dove hai iniziato. Puoi usare il suggerimento di Gurgadurgen per rilevare se il loop si ripercuote su se stesso in qualsiasi momento. Supponendo di terminare l'input dell'utente quando lo fa, sembrerà una serie di nodi in una linea, seguita da un ciclo. È possibile eliminare la linea per ottenere il ciclo.

Ora, per ogni riga facciamo quanto segue:

  1. Inizia dal bordo sinistro e tieni traccia di un valore booleano per ogni riquadro che indica se siamo IN o OUT. Iniziare.
  2. Se la tessera corrente fa parte della catena, guarda sia il successore che il predecessore (che deve essere adiacente). Se uno dei due è strettamente sopra (ovvero nord, nord est o nord ovest della tessera corrente), imposta lo stato della tessera corrente sull'opposto della tessera alla sua sinistra. Altrimenti, impostalo allo stesso modo del riquadro a sinistra. Vai a 4.
  3. Se il riquadro corrente non fa parte della catena, imposta il riquadro sullo stato del titolo alla sua sinistra. Vai a 4.
  4. Il riquadro a destra è ora il riquadro corrente. Vai a 2.

Ora prendi tutte le tessere che sono IN, aggiungi le tessere sul bordo (inclusa una coda se l'hai spogliata prima o no, a tua scelta) e chiama quella regione.

Se vuoi consentire all'utente di usare i bordi, ricorda che questo non definisce e IN / OUT sulla scheda, ma lo divide semplicemente in due parti. È possibile selezionare la regione più piccola, ad esempio, o richiedere all'utente di utilizzare due lati adiacenti (ovvero, sinistro e inferiore, ma non superiore / inferiore o sinistro / destro).

Un'ottimizzazione è che devi solo fare le righe che hanno un bordo (se non puoi usare i lati). Suppongo che la tua scheda sia abbastanza piccola da iterare su ogni riquadro e fare un calcolo molto semplice non è un problema, anche sul sistema mobile più debole. (Devi renderli, dopo tutto, che è molto più complesso di un'attività).

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.