Un punto che ha bisogno di aria.

Ale1521
Ho creato un servizio in php che permette di inserire delle scritte su delle immagini.
Le scritte vengono posizionate casualmente, hanno un colore casuale, una dimensione casuale e in'inclinazione casuale.
Purtroppo capita spesso che in un'immagine vuota, si vadano a collocare 4-5 scritte nello stesso punto, rendendole illeggibili. Non è colpa di nessuno, è solo un caso, ma...
C'è un modo per calcolare il punto migliore in cui inserire una scritta (dove c'è più spazio)?
Io conosco le coordinate (x,y) del vertice superiore sinistro di ogni scritta, e l'origine del sistema cartesiano è posta nel vertice superiore sinistro dell'immagine di sfondo.
Come posso fare?

Risposte
Umby2
E' chiaro il tuo concetto, ma effettivamente puo' darti risultati errati. Proprio in virtu' che esamini un asse separato dall'altro.
Io proverei anche con il metodo casuale, cosi come prima ti dicevo, anche perchè resto convinto, che il tempo di elaborazione (sola cpu) è irrilevante.

Ale1521
Ho fatto uno script che prende tutte le scritte lungo l'asse X, le mette in un array e le ordina.
Poi prende l'intervallo consecutivo che ha differenza maggiore (tipo 1,2,3,15,17 restituisce 3-15) e inserisce la scritta casualmente tra il valore minimo e quello massimo (rand[3,15]).
Poi fa lo stesso con la Y.

Così facendo, lo spazio disponibile si dimezzerà sempre più e le scritte si posizioneranno sempre in zone dove c'è spazio, ed è la stessa cosa che si fa quando si cerca di trovare il risultato di un'equazione con la calcolatrice (metodo della bisezione). Ad esempio sinx+4logx-2=0, inserisci un valore di x -> vedi il risultato, se è maggiore di zero, metti una x più piccola, altrimenti il contrario, finché non ti avvicini allo zero.

Questo metodo purtroppo non è il migliore, perché gestisce la x e la y separatamente. Ciò comporta che se mi trovo in una situazione del genere: (0=spazio)
___________
|-----0------00|
|-----0000000|
|---00000000|
|----000------|
|__________|
il posto migliore dove piazzare la scritta sarebbe al centro a destra, perché c'è più spazio. Ma con questo metodo mi troverei la Y in basso a tutto, e la x al centro dell'immagine.

Facendo diversi tentativi, ho visto che è comunque un ottimo sistema per evitare la sovrapposizione delle scritte. Funziona molto bene entro le prime 20-30 scritte.

Alla fine tutto ciò è per evitare che quando qualcuno si crea un muretto nuovo, e ci sono soltato DUE (massimo tre) scritte, queste due siano proprio una sopra l'altra!
Fa incazzare che con tutto quello spazio, le due scritte siano proprio accavallate :P

dissonance
beh però a questo punto dovresti dare qualche dettaglio in più... io almeno mi sono incuriosito.

Ale1521
Ho risolto con la bisezione :D

Ale1521
"Megan00b":
Un'idea furba in casi come questo è quella di utilizzare la randomizzazione solo alla fine di un processo di generazione di separatori dell'area da riempire. In parole povere dividi l'immagine in settori (generati in modo da rispettare le risposte alle domande all'inizio del post e il numero di elementi da inserire) e all'interno di questi posizioni casualmente i contenuti.

Infatti è così che faccio :D
&xpos = rand( 5 , abs((&larghezza_del_muro - (strlen(&testo_inserito) * 19))));
&ypos = rand ( 40 , abs(&altezza_del_muro - 40));
//Controllo se ci sono altre scritte dove si trova questa
&spazio = 30;
&queryd = "seleziona scritte che hanno come posizione: xpos > '".(&xpos - &spazio)."' AND xpos < '".(&xpos + (strlen(&testo_inserito) * 19))."' AND ypos > '".(&ypos - &spazio)."' AND ypos < '".(&ypos + &spazio*2)."'";
&tentativi = 10;
while (@mysql_num_rows(mysql_query(&queryd, &db)) and &tentativi) {
	&xpos = rand( 5 , abs((&larghezza_del_muro - (strlen(&testo_inserito) * 19))));
	&ypos = rand ( 40 , abs(&altezza_del_muro  - 40));
	&queryd = "seleziona scritte che hanno come posizione: xpos > '".(&xpos - &spazio)."' AND xpos < '".(&xpos + (strlen(&testo_inserito) * 19))."' AND ypos > '".(&ypos - &spazio)."' AND ypos < '".(&ypos + &spazio*2)."'";
	&tentativi--;
}
//è php, le variabili sono dichiarate col dollaro, ma le ho sostituite con & altrimenti il forum pensa siano formule!

Le scritte hanno una lunghezza massima di 40 caratteri, ma con font diversi e casuali, quindi posso solo "ipotizzare" una lunghezza massima in pixel.
Comunque per maggiori informazioni, il sito è questo: http://www.wirgilio.it/wirgilio/

Megan00b
Le scritte possono avere lunghezza qualsiasi o devono stare in un range di lunghezza predefinito?
Le scritte hanno una dimensione di carattere fissa? Vengono stampate in una riga o possono occupare più righe?
Le scritte sono sempre in orrizzontale o possono essere oblique?

Purtroppo capita spesso che in un'immagine vuota, si vadano a collocare 4-5 scritte nello stesso punto, rendendole illeggibili. Non è colpa di nessuno, è solo un caso, ma...

Non conosco l'algoritmo che hai usato ma non è detto che sia un caso. Magari se scrivi qualche riga almeno in metacodice si capisce di più. Può darsi che utilizzi <> la funzione randomize di libreria.

Un'idea furba in casi come questo è quella di utilizzare la randomizzazione solo alla fine di un processo di generazione di separatori dell'area da riempire. In parole povere dividi l'immagine in settori (generati in modo da rispettare le risposte alle domande all'inizio del post e il numero di elementi da inserire) e all'interno di questi posizioni casualmente i contenuti.

dissonance
Oppure bisogna alterare l'algoritmo che genera le posizioni casuali.
La probabilità per ogni singolo punto di essere il centro (o il vertice superiore sinistro, come nel tuo programma) di una scritta deve essere direttamente proporzionale alla distanza dai centri (o dai vertici) delle scritte precedenti. Così è più probabile che una scritta cada in una zona più libera.

Ora bisogna "solo" ( :-D ) implementarlo... al momento non mi viene in mente niente però...

Raptorista1
è indispensabile che la posizione sia casuale? se deve solamente "sembrare" casuale allora potresti determinare tu delle posizioni predefinite per scritte di diverse dimensioni.

Ale1521
L'immagine è 800x600, e il ciclo di elaborazione pixel non mi spaventa affatto.
Quello che mi spaventa è il numero inquantificabile di query che devo fare al db. Mysql morirebbe :(

Umby2
Ovviamente dipende dalla grandezza della immagine in pixel.
Una 1024 x 768 ha meno di 1M di pixel. Si tratta di fare cicli di memoria (lavora solo la Cpu) e pertanto ritengo che l'elaborazione sia poco influente.

prova...

Ale1521
Avevo pensato anch'io al ciclo, ma è troppo lenta come soluzione.
Cercavo qualcosa che sfruttasse qualche regola matematica, perciò ho scritto qui :P

Umby2
Immagino che tu abbia l'intera matrice (in pixel) a disposizione, e che quindi puoi conoscere in ogni momento se un pixel è vuoto o meno.
Io calcolerei la grandezza in pixel della scritta che devi posizionare, e in modo casuale farei un ciclo ad esempio di 1000 volte ( o anche di piu), dove per ogni punto vedrei quanti pixel sono gia' occupati o meno.
Avrei cosi' un grado di occupazione per ognuno dei 1000 punti (scelti a caso).
A fine ciclo, prenderei la scelta piu' vantaggiosa.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.