Quali sono i buoni algoritmi per generare bordi / aree di stato su mappe stellari 2D?


9

Sto cercando di generare una mappa stellare bidimensionale abbastanza grande che mostri diverse fazioni / stati, ognuno dei quali possiede uno o più sistemi stellari. Vorrei creare automaticamente bordi / aree per le fazioni.

L'idea è essenzialmente di passare da qualcosa del genere (i punti rappresentano i sistemi stellari su un piano 2d, i colori sono affiliazioni di fazioni)

I sistemi stellari e la loro appartenenza alla fazione

a questo

Sistemi stellari con aree di fazione

Generare mappe come questa sembra un requisito abbastanza comune, quindi la mia vera domanda è questa: ci sono algoritmi standard per generare aree di stato come mostrato? Se è così, potresti indicarmeli? In caso contrario, riesci a pensare a un buon algoritmo (l'idea di base o lo pseudo codice vanno bene)?

Le prestazioni dell'algoritmo non sono una preoccupazione primaria per me, quindi preferirei avere una mappa "più bella" piuttosto che una più veloce da generare. Questa domanda simile offre un approccio che è probabilmente applicabile al mio problema, anche se con qualche "prettificazione" necessaria: come creare una mappa dal grafico

Lascia che ti spieghi cosa intendo quando dico più bello: in fondo alla domanda collegata, la richiedente presenta il suo risultato finale dopo aver implementato la risposta accettata. Il mio primo problema qui: le aree per i nodi # 6, # 9 e # 12 sono molto piccole e stranamente modellate. Inoltre, al posto degli spigoli vivi, preferirei un aspetto più liscio e curvo.

Le mie idee finora, compresi i rispettivi svantaggi / domande che vedo con loro:

  • Genera un poligono "scafo convesso" per ogni fazione, quindi espandi leggermente verso l'esterno. Problemi: nessuna funzione concava. Inoltre, come gestisci le sovrapposizioni?
  • Genera un grafico voronoi per i punti, quindi usa i bordi del poligono voronoi tra i sistemi vicini di diverse fazioni come bordi. Problema: grandi poligoni ai bordi della mappa: come identificarli e correggerli?
  • Genera un poligono di dimensioni fisse per ciascun punto, unendo tutti i poligoni per una singola fazione (risultante in un "poligono di fazione" grande, potenzialmente complesso). Quindi fai qualcosa per riconciliare le aree sovrapposte tra due fazioni. Problemi: come lo farei esattamente? Non è esattamente un processo banale. E se ci fosse una sovrapposizione tra più di due fazioni?

Il tuo aiuto è apprezzato.


Addendum: dopo aver pensato alle prime due risposte e ai rispettivi approcci per risolvere il problema, mi sono reso conto che i miei requisiti di cui sopra sono incompleti.

Devo aggiungere che la mappa può avere aree scarsamente popolate, il che significa che potrebbe esserci una stella isolata o un gruppo di stelle. Vorrei visualizzare ognuno di questi cluster con la loro area colorata contigua. Qualcosa come questo:

Sistemi stellari con aree di fazione, diversi cluster

Mi rendo conto che ciò potrebbe richiedere un primo passo che identifica i cluster e quindi l'esecuzione dell'algoritmo effettivo per ciascuno dei cluster.


(brainstorming) Potresti essere in grado di riempire il resto dello spazio con rumore blu (ad es. disco di poisson) e quindi eseguire voronoi per ottenere un'assegnazione di colore. Ai punti aggiunti verrebbe assegnata la regione di sfondo bianco.
dal

@amitp Ehi, Amit, è un onore farti commentare qui! Ho preso un'enorme quantità di ispirazione e conoscenza pratica dalla lettura dei tuoi articoli su Red Blob Games. Altro sull'argomento: l'idea di generare punti aggiuntivi ha senso, qualche motivo particolare per cui stai menzionando specificamente il rumore blu ?
Grüse,

... Immagino perché sembra una distribuzione più naturale rispetto ad altri rumori.
Grüse,

Risposte:


16

Penso che l'idea di Voronoi sia valida. Ogni stella diventa un punto di partenza per Voronoi, e quindi le regioni Voronoi mostrano le aree di proprietà di ciascuna fazione. Tuttavia, ci sono alcune modifiche che lo faranno funzionare meglio:

  1. Come hai detto, ci sono aree vuote che non dovrebbero essere assegnate a una fazione. Voronoi creerà grandi poligoni che si estendono alle aree in cui la fazione non dovrebbe raggiungere. Per risolvere questo problema, usa un algoritmo di rumore blu come il disco di Poisson per riempire lo spazio non occupato di stelle "di proprietà di nessuno". Il rumore blu è casuale ma uniformemente distribuito (potrebbe anche essere utile per generare le posizioni delle stelle).
  2. Voronoi produce regioni a blocchi. Per produrre celle più rotonde, sostituire il calcolo del circoncenter di Voronoi con un calcolo del centroide. Ho scritto un po 'su questo qui con alcune immagini di confronto.
  3. Voronoi produce poligoni, ma vuoi aree rotonde. Ad ogni angolo, ci sono tre poligoni. Quando tutte e tre sono la stessa fazione, puoi lasciarla sola. Quando due sono la stessa fazione, introdurre una curva quadratica più bezier che sposta il confine verso l'altra fazione. Quando tutte e tre le fazioni sono diverse, puoi lasciare l'angolo da solo oppure puoi introdurre tre curve più bezier per allontanare tutti i confini l'uno dall'altro. Non sono sicuro di quale sia l'aspetto migliore.

Ecco l'output:

Mappa blobby

Ho anche scritto una pagina che ti permette di dipingere le regioni per vedere come sarebbero.


Questo si adatta perfettamente al mio caso d'uso, grazie mille! Devo dire che è altrettanto impressionante e deprimente che tu sia stato in grado di mettere insieme un esempio interattivo così rapidamente, mentre probabilmente mi ci vorranno almeno alcuni giorni per riprodurre anche ciò che hai presentato qui :) In attesa di quell'articolo tutorial.
Grüse,

4

Uno dei molti metodi è una mappa di influenza . Puoi cercare implementazioni di codice specifiche, ma l'algoritmo di base è abbastanza semplice.

Per ogni oggetto di fazione (ad es. Sistema stellare), assegna un valore positivo (caldo). Per tutti gli oggetti di altre fazioni assegnare un valore negativo (freddo). L'entità del caldo o del freddo dovrebbe essere basata su quanta influenza pensi che l'oggetto eserciti sul suo ambiente e sui suoi vicini. Questi valori non devono essere proporzionali se alla fine si desidera mantenere un "dmz" tra le fazioni.

Usa questi dettagli per creare una griglia temporanea (ad es. Array) che approssima i pixel della tua mappa. Puoi creare una griglia del genere alla risoluzione che desideri, incluso 1: 1.

Quindi, usa l'equazione del trasferimento di calore / campo per iterare e propagare i punti di forza degli oggetti della fazione (calore) contro i punti di forza degli oggetti degli avversari (freddo) per ogni cella vicina nella griglia.

Risciacqua e ripeti per ciascuna Fazione sulla tua mappa creando griglie di fazioni separate per ciascuna.

Infine, interpolare le griglie della fazione insieme per produrre un contorno di influenza per ciascuna fazione. Quindi trasferisci quella griglia sulla tua mappa di pixel data la risoluzione che hai usato per la griglia (aggiungendo colori specifici per ogni fazione, ecc.).

L'arte in questo processo è determinare quanta influenza dovrebbe avere ciascun oggetto e quali elementi di gioco usi per quantificare quel valore.

A parte questo, i prodotti di questo metodo possono essere usati per ogni altra cosa, come il tuo processo decisionale.


Ulteriori riferimenti: thread di discussione sulle origini della mappatura dell'influenza .


Questo approccio dovrebbe essere ovvio, ma non mi è mai venuto in mente. Grazie per averlo portato alla mia attenzione! Un pensiero: le mie mappe possono essere sparse in alcune aree, mentre altre aree sono densamente piene di stelle di affiliazioni diverse l'una accanto all'altra. Esiste un modo per utilizzare celle di dimensioni diverse per le diverse aree? Pensando sulla falsariga di un quadrifoglio o simile.
Grüse,

2

Dovresti guardare nei diagrammi di Voronoi. Ecco la definizione su Wikipedia:

In matematica, un diagramma di Voronoi è un partizionamento di un piano in regioni in base alla distanza da punti in un sottoinsieme specifico del piano.

I punti di base sono generalmente generati casualmente e sono spesso chiamati nodi. Nel tuo caso, ogni nodo potrebbe essere la tua stella. In questo modo, la fazione associata alle stelle può essere associata alla cellula voronoi che circonda la stella e quando ogni cella è stata calcolata, si uniscono quelli con la stessa fazione insieme e si dovrebbe avere un bordo abbastanza pulito attorno alle stelle.

La libreria FastNoise supporta i diagrammi Voronoi, quindi forse dovresti guardarla.

Levigatura delle regioni

Mantieni le tue stelle in un «array sicuro» e utilizzane una copia in cui aggiungi effettivamente più punti tramite l'interpolazione dei vicini più vicini e genera il diagramma da quei punti. Dovrebbe darti regioni più fluide.

Altre idee L'algoritmo di fortuna si basa su una linea retta che spazza il piano cartesiano. Un'idea interessante sarebbe quella di usare un cerchio per spazzare invece l'aereo dal centro della tua galassia / spazio, forse questo potrebbe portare anche ad alcune forme interessanti.

Manipolazione della geometria

La tua ultima idea di combinare poligoni più piccoli in quelli più grandi e quindi fissare i bordi richiederà algoritmi spline avanzati per modificare le forme. Non sono sicuro se ciò lo renderebbe efficiente o bello. Sono abbastanza sicuro che il diagramma voronoi con tassellatura aggiuntiva sia la strada da percorrere in quanto risolve il problema del bordo da solo e può anche offrire alcuni dati extra da solo come la distanza dai bordi (che potrebbero essere utilizzati per determinare le zone di conflitto tra le diverse fazioni, la probabilità di incontrare diversi tipi di navi, ecc.)


Si noti che OP ha già fatto riferimento a una risposta utilizzando i diagrammi Voronoi, quindi sono a conoscenza della tecnica, ma hanno chiesto modifiche specifiche per cambiare l'aspetto dei bordi. Puoi espandere la tua risposta per rispondere a tali richieste specifiche?
DMGregory

Siamo spiacenti,
ho

Grazie per aver modificato la tua risposta! L'idea di smoothing è interessante. Ho due problemi con l'approccio Voronoi: Uno: come posso rilevare e limitare i punti "esterni" in modo che i bordi non si estendano fino ai bordi dello schermo (vedi la seconda immagine della mia domanda). Due: nelle aree scarsamente popolate, Voronoi non dà grandi risultati perché i poligoni diventano enormi. Forse c'è una soluzione ovvia a quelli che non riesco a vedere?
Grüse,

Sarebbe un'opzione per aggiungere punti da soli per inquadrare l'area? Quindi, quando si esegue il rendering del grafico, se una linea raggiunge il bordo effettivo dell'immagine, semplicemente non viene disegnata in quanto non farà parte dell'area di gioco. Il secondo problema dovrebbe essere risolvibile con il livellamento. È possibile aggiungere più punti quando sono ulteriormente appartati in modo da mantenere una sorta di «dimensione della griglia» coerente.
BadgerBadger,

@BadgerBadger sì, sto sperimentando l'aggiunta di punti in questo momento
Grüse,
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.