-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGenerador.java
More file actions
280 lines (216 loc) · 9.52 KB
/
Generador.java
File metadata and controls
280 lines (216 loc) · 9.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
import java.io.*;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.control.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import java.util.Arrays;
import java.nio.file.Files;
import javafx.scene.shape.*;
public abstract class Generador implements Graficable{
protected Palabra[] palabras;
protected String texto;
protected int limite;
protected final int MAX_FONT_SIZE=220;
protected final int MIN_FONT_SIZE=28;
protected Color colorPalabra;
protected Color colorFondo;
private final int WIDTH = 1280;
private final int HEIGHT = 1000;
//signos en variables -no entiendo este comment
public Generador(File texto, int limite, Color colorPalabra, Color colorFondo) {
this.texto=archivoATexto(texto);
this.limite=limite;
this.colorPalabra=colorPalabra;
this.colorFondo=colorFondo;
}
public String archivoATexto(File input) {
//aqui se recibe el archivo y se regresa una string
try {
return new String(Files.readAllBytes(input.toPath()));
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return "";
}
public Scene iniciar(){ //no tiene argumentos porque todo está en el estado, es el mismo metodo para generador 1 y generador 2, entonces se queda en la clase padre
llenarArreglo();
ordenarArreglo();
recortarArreglo();
determinarFontSizePorPalabra();
determinarTonoPorPalabra();
//ahora iniciar UI y acomodar todas las labels donde deben ir
Scene escena = crearNube();
acomodarPalabras(escena);
return escena;
}
public abstract void llenarArreglo(); //el unico metodo que se queda abstracto es llenarArreglo porque uno tiene lista negra y el otro no
public void determinarFontSizePorPalabra() {
//este metodo usa el arreglo palabras y basado en la frecuencia de cada palabra y la cantidad de palabras determina el tamaño de cada una, se manda llamar despues de iniciar el arreglo
int frecuenciaMax=palabras[0].getFrecuencia();
//el tamaño debe ser proporcional al uso de cada palabra, todo relativo a maxFontSize con regla de 3, el arreglo palabras debe estar ordenado de mayor a menor frecuencia
for (int i=0; i<palabras.length ; i++) {
int fontSize = MIN_FONT_SIZE + ((MAX_FONT_SIZE - MIN_FONT_SIZE)/(frecuenciaMax - 1))*(palabras[i].getFrecuencia() - 1);
//if (fontSize<15) fontSize=15;
palabras[i].setFontSize(fontSize);
//si la palabra está en el 20% mas usada sera maysuculas
float floati = ((float) i);
float largo = (float) palabras.length;
if (floati/largo<=0.2) {
palabras[i].labelAMayus();
}
}
}
public void determinarTonoPorPalabra() {
int cantidadPalabras=palabras.length;
//experimental
for (int i=0; i<cantidadPalabras; i++) {
//int tonoGris = ((250)/(cantidadPalabras))*(i);
//y = y1 + ((y2 - y1)/(x2 - x1))*(x - x1) para i=0(x1) transparencia= 1 (y1) , para i=cantidadPalabras-1 (x2) transparencia= transMin(y2)
float cant= (float) cantidadPalabras;
float index = (float) i;
float transpMin = 0.05f;
float transparencia = 1 + ((transpMin - 1)/(cant-1))*(index);
int R = (int) Math.round(colorPalabra.getRed()*255);
int G = (int)Math.round(colorPalabra.getGreen()*255);
int B = (int)Math.round(colorPalabra.getBlue()*255);
palabras[i].getLabel().setTextFill( Color.rgb(R, G, B, transparencia));
}
}
public Scene crearNube() {
//crear UI y mostrarala como siempre y regresar la escena con un grupo raiz vacio y ya
Group root = new Group();
Scene scene = new Scene(root, WIDTH, HEIGHT, colorFondo); //cambiar después
return scene;
}
public void acomodarPalabras(Scene escena) {
for (Palabra palabra : palabras) {
//debugging System.out.println("La palabra que se acomodara es "+palabra.getContenido()+", ancho: "+palabra.getWidth()+", alto: "+palabra.getHeight());
acomodarPalabra(palabra, escena);
}
}
public void acomodarPalabra(Palabra palabra, Scene escena) {
//checar colosiones primero para y positivos despues para negativos (cuadrantes II (-+), I (++), III(--), IV(+-)), iterar para cada radio del circulo
boolean acomodado=false;
//iterador de radio
for (int r=0; !acomodado; r++) {
//empezar con cuadrantes II y I, probando todas las x entre 0 y |r|
for (int x=-r ; x<=r && !acomodado; x++) {
int y = funcionCirculo(x,r);
int coordX=x-palabra.getWidth()/2; //para centrar en el centro de la etiqueta y no en la esquina superior izqquerda
int coordY=y-palabra.getHeight()/2;//para centrar en el centro de la etiqueta y no en la esquina superior izqquerda
boolean colision = checarColision(palabra, coordX, coordY);
// System.out.println("Tratando de acomodar "+ palabra.getContenido() + "en coordenadas "+coordX +","+coordY );
if (!colision) {
Label etiqueta = palabra.getLabel();
//agregar etiqueta a escena
//guardar coordenadas relativo a un centro de coordenadas 0|0
palabra.setCoordenadas(coordX, coordY);
etiqueta.setTranslateX(coordX+WIDTH/2);
etiqueta.setTranslateY(coordY+HEIGHT/2);
/* // usado para debuggear
Rectangle rect1 = RectangleBuilder.create()
.x(coordX+WIDTH/2)
.y(coordY+HEIGHT/2)
.width(palabra.getWidth())
.height(palabra.getHeight())
.build();
((Group)escena.getRoot()).getChildren().add(rect1);
*/
((Group)escena.getRoot()).getChildren().add(etiqueta);
acomodado=true; //ya se acomodo
//debugging System.out.println("SE ACOMODO "+ palabra.getContenido() + "en coordenadas "+coordX +","+coordY );
}
}
//¿cuadrantes III y IV, probando todas las x entre 0 y |r|
//solo tiene sentido intentar acomodarlo en cuadrantes III y IV si no se ha podido acomodar arriba
for (int x = -r; x <= r && !acomodado; x++) {
int y = -funcionCirculo(x,r);
int coordX=x-palabra.getWidth()/2; //para centrar en el centro de la etiqueta y no en la esquina superior izqquerda
int coordY=y-palabra.getHeight()/2;//para centrar en el centro de la etiqueta y no en la esquina superior izqquerda
boolean colision = checarColision(palabra, coordX, coordY);
// System.out.println("Tratando de acomodar "+ palabra.getContenido() + "en coordenadas "+coordX +","+coordY );
if (!colision) {
Label etiqueta = palabra.getLabel();
//agregar etiqueta a escena
//guardar coordenadas relativo a un centro de coordenadas 0|0 y en el centro de la palabra
palabra.setCoordenadas(coordX, coordY);
etiqueta.setTranslateX(coordX+WIDTH/2);
etiqueta.setTranslateY(coordY+HEIGHT/2);
/* // usado para debuggear
Rectangle rect1 = RectangleBuilder.create()
.x(coordX+WIDTH/2)
.y(coordY+HEIGHT/2)
.width(palabra.getWidth())
.height(palabra.getHeight())
.build();
((Group)escena.getRoot()).getChildren().add(rect1);
*/
((Group)escena.getRoot()).getChildren().add(etiqueta);
acomodado=true; //ya se acomodo
//debugging System.out.println("SE ACOMODO "+ palabra.getContenido() + "en coordenadas "+coordX +","+coordY );
}
}
}
}
public boolean checarColision(Palabra palabra, int x, int y) {
//checar si no hay una superposicion de la palabra actual y alguna otra palabra en la posicion deseada
// int w = palabra.getWidth();
// int h = palabra.getHeight();
//importante, el centro de coordenadas de las labels es la esquina de arriba izquierda, tomar en cuenta
//la colision ocurre cuando el rectangulo de la palabra actual coincide con el de alguna palabra, es decir, cuando el rango de x && de y de ambos rectangulos coincide para una o mas combinaciones de x && y
int aIzq= x;
int aDer=x+(palabra.getWidth()); //CREO que aaqui esta el problema somehow
int aAbajo= y;
int aArriba= y+(palabra.getHeight());
for (Palabra actual : palabras){
int bIzq= actual.getX();
int bDer= actual.getX()+actual.getWidth();
int bAbajo= actual.getY();
int bArriba= actual.getY()+actual.getHeight();
if (actual.getX()!=-2147483648 && actual.getY()!=-2147483648) { //si no se ha acomodado la palabra actual (x o y == valor minimo de int), no tiene sentido checar colisiones
if (!(aDer < bIzq || aIzq > bDer || aArriba < bAbajo || aAbajo > bArriba)) { //rectangulo b tiene que estar arriba o abajo o a la derecha o a la izquiera de rectangulo b. si no esta ahi es sobreposicion
return true; //hubo colision
}
}
}
//debugging System.out.println("En colosion, ancho:"+palabra.getWidth()+" alto: "+palabra.getHeight());
return false;
}
public int funcionCirculo(int x, int r) { //recibe un valor x regresa el valor positivo correspondiente de la funcion x^2 + y^2 = r^2
return (int) Math.round(Math.sqrt(r*r-x*x));
}
public void agregarPalabra(String nuevaPalabra) {
Label etiqueta = new Label(nuevaPalabra);
palabras = Arrays.copyOf(palabras, palabras.length + 1);
palabras[palabras.length - 1] = new Palabra(nuevaPalabra, etiqueta);
}
public void ordenarArreglo() {
// bubble sort! (ineficiente pero facil de programar)
int n = palabras.length;
Palabra temp;
for(int i=0; i < n; i++){
for(int j=1; j < (n-i); j++){
if(palabras[j-1].getFrecuencia() < palabras[j].getFrecuencia()){
//hacer el cambio
temp = palabras[j-1];
palabras[j-1] = palabras[j];
palabras[j] = temp;
}
}
}
}
public void recortarArreglo() { //reducir el arreglo según el limite, dejando las palabras más usadas
if (palabras.length>limite) {
//recortar arreglo
palabras = Arrays.copyOf(palabras, limite);
}
}
public Palabra[] getPalabras(){ return palabras;}
}