ROMPIDO
Guía integral destinada a estructurar la comunicación gráfica de una propuesta disruptiva orientada a revalorizar la identidad del artista en el mercado del diseño uruguayo. Bajo el eslogan "Una rotura es una apertura...", la marca se fundamenta en valores de integralidad, perfeccionismo, sostenibilidad, experimentalismo y libertad.
Su elemento identificador central es un isotipo generativo concebido a partir de un algoritmo basado en el logaritmo neperiano, el cual genera una estructura fragmentada con estética de cristal roto y mantiene una proporción fija de 1:1, contando además con una versión simplificada para formatos pequeños de entre 16 px y 100 px y un área de protección equivalente a su propio tamaño.
El sistema cromático institucional se compone de negro (Pantone Black C), gris claro (Cool Gray 1 C), rojo (Pantone 185 C), azul (Pantone 2728 C) y un amarillo acento (Pantone 116 C) destinado exclusivamente a detalles, mientras que se prohíbe de manera explícita el uso de tonos neón y del gris neutro Cool Gray 5 C por connotar tibieza.
En el plano tipográfico, la marca articula la claridad de Helvetica para títulos principales, la firmeza de Rústica para bloques de texto continuo y la expresividad de Spalla para subtítulos y acentos gráficos.
Finalmente, la sección de restricciones "¡No lo rompas más!" prohíbe deformar el isotipo, invadir su área de reserva, aplicar sombras o efectos 3D, alterar el contraste de los fondos o rotar la composición, garantizando así la coherencia técnica e institucional de la marca.
- FORMATO
- Identity
- ESTADO
- Completed
- PROPÓSITO
- Experimental
- DIMENSIÓN
- Medium Project
- DISCIPLINAS
- Visual Identity
- TÉCNICAS
- Coding · Color Grading · Compositing · Motion graphics · Video Editing
- SOFTWARE
- After Effects · DaVinci Resolve · Photoshop · Figma · Processing · Reaper
El isotipo
Lo icónico de lo orgánico
El logotipo de ROMPIDO nace de un proceso generativo: un software que, al ejecutarse, crea un nuevo patrón de vidrio roto. No existe una versión definitiva; cada forma es hija del azar, como en la naturaleza. Rechazamos la obsesión por el control absoluto del diseño —esa búsqueda de la perfección que termina borrando al creador. La rotura es nuestra firma: un gesto vivo, impredecible, que deja ver lo esencial. A través de esa grieta, la luz —las ideas— atraviesan sin filtro, sin artificio.
La forma surge de una grilla generada mediante un logaritmo en base neperiana —una curva que imita los ritmos de la naturaleza. Entre el 0 y el 1, la forma se fragmenta como el cristal: irregular, impredecible, pero con una belleza que responde a una lógica interna.
El código
El software que dibuja la marca
El sketch
Arma la grilla, siembra los puntos y traza las grietas. En Processing el clic izquierdo siembra y el derecho rompe; acá se hace de un solo golpe.
ver el códigoGEN_VIDRIO_ROTO.pde · 78 líneas
import processing.pdf.*;
PGraphicsPDF pdf;
int sizeX, sizeY;
int tamaño = 500;
int tamañoX = tamaño;
int tamañoY = tamaño;
int divisiones = 5;
int vertices = 100;
int contadorCoordenadas = 0;
int numeros;
float delta;
int rango;
int base;
int indice;
float coordX, coordY;
int cortes = (divisiones+1)*(divisiones+1)+1;
float ran;
float[] interseccionesX = new float[vertices];
float[] interseccionesY = new float[vertices];
int[] puntoTipo = new int[vertices];
float[] puntosX = new float[divisiones*2];
float[] puntosY = new float[divisiones*2];
color[] col = {#DDC603, #D18017, #C3154B, #7E236C, #020002, #301B52, #37317B, #134587, #018DC8, #7BB5C7, #C1D1D8, #DCDCDC, #E0E0E0};
color[] col2 = {#CF3030/*rojo*/, #FE9B17/*amarillo*/, #3A82D6, #B6C706/*azul*/, #B6C706, #B6C706, #B6C706, #B6C706};
void settings (){
sizeX = tamañoX;
sizeY = tamañoY;
size(sizeX, sizeY, P2D);
numeros = 0;
}
void setup() {
background(255);
genGrilla(0, true, true, true, true);
///beginRecord(PDF, "resultados/gen.pdf");
ellipseMode(CENTER);
}
void draw() {
pdf = (PGraphicsPDF) createGraphics(sizeX, sizeY, PDF, "resultados/gen"+numeros+".pdf"); //POR QUE DEBO MULTIPLICARLO POR DOS, SI NO ME QUEDA UN SOLA ESQUINA
beginRecord(pdf);
numeros++;
if (mousePressed && mouseButton == LEFT) {
genPuntos(vertices);
delay(100);
}else if (mousePressed && mouseButton == RIGHT){
fragmentos();
}
if (keyPressed && key=='s'){
guardarImagen("resultados", "gen");
endRecord();
exit();
}
}Las funciones
La grilla logarítmica espejada en los cuatro lados, los tres anillos de puntos alrededor del impacto, y el orden en que se unen para que ninguno quede suelto.
ver el códigofunciones.pde · 570 líneas
String guardarImagen(String carpeta, String nombreBase) {
// Nombre con timestamp para que no se repita
String nombreArchivo = nombreBase + "-" +
year() + nf(month(), 2) + nf(day(), 2) + "-" +
nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2) +
".jpg";
// Ruta final
String rutaCompleta = carpeta + "/" + nombreArchivo;
// Guardar la imagen del canvas actual
saveFrame(rutaCompleta);
// Mensaje de confirmación
println("✅ Imagen guardada en: " + rutaCompleta);
// Devolver ruta
return rutaCompleta;
}
// genGrilla unificada: dibuja izquierda/derecha/arriba/abajo
void genGrilla(color col, boolean drawLeft, boolean drawRight, boolean drawTop, boolean drawBottom) {
stroke(col);
strokeWeight(1);
int rangoX = int(width / divisiones);
float coordXMax = rangoX;
float deltaTestX = 0;
int contadorTestX = 0;
int baseX = 10;
int contadorCoordenadasX = 0;
int contadorCoordenadasY = 0;
for (int i = divisiones; i > 0; i--) {
contadorTestX++;
float x = map(i, 0, divisiones, 0, 1);
deltaTestX += -rangoX * logX(x, baseX);
coordXMax = rangoX * contadorTestX - deltaTestX;
}
// IZQUIERDA
if (drawLeft) {
float delta = 0;
int contador = 0;
for (int i = divisiones; i > 0; i--) {
stroke(0);
contador++;
float x = map(i, 0, divisiones, 0, 1);
delta += -rangoX * logX(x, baseX);
float coordX = rangoX * contador - delta;
float coordXMap = map(coordX, 0, coordXMax, 0, width / 2);
line(coordXMap, 0, coordXMap, sizeX);
puntosX[contadorCoordenadasX] = coordXMap;
contadorCoordenadasX++;
}
println("La grilla (mitad izquierda) se generó correctamente.");
}
//DERECHA
if (drawRight) {
float delta = 0;
int contador = 0;
for (int i = divisiones; i > 0; i--) {
stroke(0);
contador++;
float x = map(i, 0, divisiones, 0, 1);
delta += -rangoX * logX(x, baseX);
float coordX = rangoX * contador - delta;
float coordXMap = map(coordX, 0, coordXMax, width, width / 2); // mapeo invertido (espejo)
//println("Der X: " + coordX + " -> " + coordXMap);
line(coordXMap, 0, coordXMap, sizeX);
puntosX[contadorCoordenadasX] = coordXMap;
contadorCoordenadasX++;
}
println("La grilla (mitad derecha / espejada) se generó correctamente.");
}
// ----- EJE Y (filas) - cálculo del máximo (coordYMax) -----
int rangoY = int(height / divisiones);
float coordYMax = rangoY;
float deltaTestY = 0;
int contadorTestY = 0;
int baseY = 10;
for (int i = divisiones; i > 0; i--) {
contadorTestY++;
float x = map(i, 0, divisiones, 0, 1);
deltaTestY += -rangoY * logX(x, baseY);
coordYMax = rangoY * contadorTestY - deltaTestY;
}
//INFERIOR
if (drawBottom) {
float delta = 0;
int contador = 0;
for (int i = divisiones; i > 0; i--) {
stroke(0);
contador++;
float x = map(i, 0, divisiones, 0, 1);
delta += -rangoY * logX(x, baseY);
float coordY = rangoY * contador - delta;
float coordYMap = map(coordY, 0, coordYMax, height, height / 2); // invertido borde -> centro
//println("Inf Y: " + coordY + " -> " + coordYMap);
line(0, coordYMap, width, coordYMap);
puntosY[contadorCoordenadasY] = coordYMap;
contadorCoordenadasY++;
}
println("La grilla (mitad inferior) se generó correctamente.");
}
//SUPERIOR
if (drawTop) {
float delta = 0;
int contador = 0;
for (int i = divisiones; i > 0; i--) {
stroke(0);
contador++;
float x = map(i, 0, divisiones, 0, 1);
delta += -rangoY * logX(x, baseY);
float coordY = rangoY * contador - delta;
float coordYMap = map(coordY, 0, coordYMax, 0, height / 2); // desde arriBA AL CENTRO
//println("Sup Y: " + coordY + " -> " + coordYMap);
line(0, coordYMap, width, coordYMap);
puntosY[contadorCoordenadasY] = coordYMap;
contadorCoordenadasY++;
}
println("La grilla (mitad superior) se generó correctamente.");
}
println("genGrilla completa ejecutada.");
for(int i=0; i<puntosY.length; i++){
println("Las coordendas del Y son: "+puntosY[i]+"en "+i);}
for(int i=0; i<puntosX.length; i++){
println("Las coordendas del X son: "+puntosX[i]+"en "+i);}
}
void primerPunto(){
float x;
float y;
boolean estado;
contadorCoordenadas = 0;
tamaño = 5;
x = puntosX[int(random(0, puntosX.length))];
estado = false;
if (x>(sizeX*2)/5 && x<(sizeX*3)/5){ //RANGO QUE QUIERO
while(estado == false){
y = puntosY[int(random(0, puntosY.length))];
if (y>(sizeY*2)/5 && y<(sizeY*3)/5){
if(x==sizeX/2 && y==sizeY/2){
println("EL CENTRO NO!");
}else{
interseccionesY[contadorCoordenadas] = y;
interseccionesX[contadorCoordenadas] = x;
fill(col2[0]); //rojo
ellipse(x, y, tamaño, tamaño);
puntoTipo[contadorCoordenadas] = 0;
contadorCoordenadas++;
estado = true;//para que termine el bucle.
}
}
}
}
}
void genPuntos(int cantidad) {
primerPunto();
contadorCoordenadas = 1;
int tamaño = 5;
float x;
float y;
boolean estado;
float probabilidad;
for(int i=0; i<cantidad; i++){
probabilidad = random(0,10);
//println(probabilidad);
if (probabilidad <=10 && probabilidad >8){ //RANGO DEL CENTRO
x = puntosX[int(random(0, puntosX.length))];
estado = false;
if (x>(sizeX*2)/5 && x<(sizeX*3)/5){ //RANGO QUE QUIERO
//println("Este X: "+x+" entro");
while(estado == false){
y = puntosY[int(random(0, puntosY.length))];
if (y>(sizeY*2)/5 && y<(sizeY*3)/5){
if(x==sizeX/2 && y==sizeY/2){
println("EL CENTRO NO!");
}else{
interseccionesY[contadorCoordenadas] = y;
interseccionesX[contadorCoordenadas] = x;
fill(col2[0]); //rojo
ellipse(x, y, tamaño, tamaño);
println("Se encontro un punto en el PRIMER anillo: ("+x+","+y+")");
puntoTipo[contadorCoordenadas] = 0;
contadorCoordenadas++;
estado = true;//para que termine el bucle.
}
}// del segundo if
}//del while
}
}else if (probabilidad <=8 && probabilidad >=6){
x = puntosX[int(random(0, puntosX.length))];
estado = false;
if (
x<=(sizeX*2)/5 &&
x>=(sizeX*1)/5 ||
x>=(sizeX*3)/5 &&
x<=(sizeX*4)/5){ //RANGO QUE QUIERO
while(estado == false){
y = puntosY[int(random(0, puntosY.length))];
if (
//y<=(sizeY*2)/5 &&
y>=(sizeY*1)/5 &&
//y>=(sizeY*3)/5 &&
y<=(sizeY*4)/5){
interseccionesY[contadorCoordenadas] = y;
interseccionesX[contadorCoordenadas] = x;
fill(col2[1]); //amarillo
ellipse(x, y, tamaño, tamaño);
println("Se encontro un punto en el SEGUNDO anillo: ("+x+","+y+")");
puntoTipo[contadorCoordenadas] = 1;
contadorCoordenadas++;
estado = true;//para que termine el bucle.
}
}
}else if(
x>(sizeX*2)/5 &&
x<(sizeX*3)/5){
while(estado == false){
y = puntosY[int(random(0, puntosY.length))];
if (
y<=(sizeY*2)/5 &&
y>=(sizeY*1)/5 ||
y>=(sizeY*3)/5 &&
y<=(sizeY*4)/5){
interseccionesY[contadorCoordenadas] = y;
interseccionesX[contadorCoordenadas] = x;
fill(col2[1]); //amarillo
ellipse(x, y, tamaño, tamaño);
println("Se encontro un punto en el SEGUNDO anillo: ("+x+","+y+")");
puntoTipo[contadorCoordenadas] = 1;
contadorCoordenadas++;
estado = true;//para que termine el bucle.
}
}
}else{
x = puntosX[int(random(0, puntosX.length))];
estado = false;
if (
x<=(sizeX)/5 &&
x>=0 ||
x>=(sizeX*4)/5 &&
x<=sizeX){ //RANGO QUE QUIERO
while(estado == false){
y = puntosY[int(random(0, puntosY.length))];
if (
//y<=(sizeY)/5 &&
y>=0 &&
//y>=(sizeY*4)/5 &&
y<=sizeY){ //RANGO QUE QUIERO
interseccionesY[contadorCoordenadas] = y;
interseccionesX[contadorCoordenadas] = x;
fill(col2[2]); //azul
ellipse(x, y, tamaño, tamaño);
println("Se encontro un punto en el TERCER anillo: ("+x+","+y+")");
puntoTipo[contadorCoordenadas] = 2;
contadorCoordenadas++;
estado = true;//para que termine el bucle.
}
}
}else if(
x>=(sizeX*1)/5 &&
x<=(sizeX*4)/5){
while(estado == false){
y = puntosY[int(random(0, puntosY.length))];
if (
y<=(sizeY)/5 &&
y>=0 ||
y>=(sizeY*4)/5 &&
y<=sizeY){ //RANGO QUE QUIERO
interseccionesY[contadorCoordenadas] = y;
interseccionesX[contadorCoordenadas] = x;
fill(col2[2]); //azul
ellipse(x, y, tamaño, tamaño);
println("Se encontro un punto en el TERCER anillo: ("+x+","+y+")");
puntoTipo[contadorCoordenadas] = 2;
contadorCoordenadas++;
estado = true;//para que termine el bucle.
}
}
}
}
}
}
for(int i=0; i<vertices; i++){
println(interseccionesX[i]);
}
}
/*void fragmentos(){
}*/
//void fragmentos(){
// float x1;
// float y1;
// float x2;
// float y2;
// float d;
// float[] distancias = new float[contadorCoordenadas];
// for (int i=0; i<contadorCoordenadas; i++){
// x1 = interseccionesX[i];
// y1 = interseccionesY[i];
// println(x1, y1);
// for (int j=0; j<contadorCoordenadas; j++){
// x2 = interseccionesX[j];
// y2 = interseccionesY[j];
// if (puntoTipo[j] == puntoTipo[i]+1){
// distancias[j] = dist(x1, y1, x2, y2);
// d = min(distancias);
// if (distancias[j]==d){
// indice = j;
// println(indice);
// }
// }
// }
// line(x1, y1, interseccionesX[indice], interseccionesY[indice]);
// }
//}
void fragmentos() {
background(255);
// --- 1. Conectar TODOS los rojos entre sí ---
for (int i = 0; i < contadorCoordenadas; i++) {
if (puntoTipo[i] == 0) {
for (int j = i + 1; j < contadorCoordenadas; j++) {
if (puntoTipo[j] == 0) {
line(interseccionesX[i], interseccionesY[i], interseccionesX[j], interseccionesY[j]);
}
}
}
}
// --- 2. Conectar cada rojo con su amarillo más cercano ---
boolean[] amarilloConectado = new boolean[contadorCoordenadas];
for (int i = 0; i < contadorCoordenadas; i++) {
if (puntoTipo[i] == 0) { // rojo
float xR = interseccionesX[i];
float yR = interseccionesY[i];
float minDist = Float.MAX_VALUE;
int idxAmarillo = -1;
for (int j = 0; j < contadorCoordenadas; j++) {
if (puntoTipo[j] == 1) {
float d = dist(xR, yR, interseccionesX[j], interseccionesY[j]);
if (d < minDist) {
minDist = d;
idxAmarillo = j;
}
}
}
if (idxAmarillo != -1) {
line(xR, yR, interseccionesX[idxAmarillo], interseccionesY[idxAmarillo]);
amarilloConectado[idxAmarillo] = true;
}
}
}
// --- 3. Asegurar que NINGÚN amarillo quede libre (si no fue conectado, unirlo al rojo más cercano) ---
for (int j = 0; j < contadorCoordenadas; j++) {
if (puntoTipo[j] == 1 && !amarilloConectado[j]) {
float minDist = Float.MAX_VALUE;
int idxRojo = -1;
for (int i = 0; i < contadorCoordenadas; i++) {
if (puntoTipo[i] == 0) {
float d = dist(interseccionesX[i], interseccionesY[i], interseccionesX[j], interseccionesY[j]);
if (d < minDist) {
minDist = d;
idxRojo = i;
}
}
}
if (idxRojo != -1) {
line(interseccionesX[j], interseccionesY[j], interseccionesX[idxRojo], interseccionesY[idxRojo]);
}
}
}
// --- 4. Conectar cada amarillo con su azul más cercano ---
boolean[] azulConectado = new boolean[contadorCoordenadas];
for (int i = 0; i < contadorCoordenadas; i++) {
if (puntoTipo[i] == 1) { // amarillo
float xA = interseccionesX[i];
float yA = interseccionesY[i];
float minDist = Float.MAX_VALUE;
int idxAzul = -1;
for (int j = 0; j < contadorCoordenadas; j++) {
if (puntoTipo[j] == 2) {
float d = dist(xA, yA, interseccionesX[j], interseccionesY[j]);
if (d < minDist) {
minDist = d;
idxAzul = j;
}
}
}
if (idxAzul != -1) {
line(xA, yA, interseccionesX[idxAzul], interseccionesY[idxAzul]);
azulConectado[idxAzul] = true;
}
}
}
// --- 5. Asegurar que NINGÚN azul quede libre (si no fue conectado, unirlo al amarillo más cercano) ---
for (int j = 0; j < contadorCoordenadas; j++) {
if (puntoTipo[j] == 2 && !azulConectado[j]) {
float minDist = Float.MAX_VALUE;
int idxAmarillo = -1;
for (int i = 0; i < contadorCoordenadas; i++) {
if (puntoTipo[i] == 1) {
float d = dist(interseccionesX[i], interseccionesY[i], interseccionesX[j], interseccionesY[j]);
if (d < minDist) {
minDist = d;
idxAmarillo = i;
}
}
}
if (idxAmarillo != -1) {
line(interseccionesX[j], interseccionesY[j], interseccionesX[idxAmarillo], interseccionesY[idxAmarillo]);
}
}
}
}
float logX (float x, int base) {
return (log(x) / log(base));
}La paleta
Negro, azul y un amarillo que solo señala
- #000000Pantone Black CCMYK 0 0 0 100 · el color base de la marca
- #0114E6Pantone 2728 CCMYK 100 91 0 10 · el azul de la rotura
- #F4F4F4Pantone Cool Gray 1 CCMYK 0 0 0 4 · el vidrio, el fondo
- #FF183BPantone 185 CCMYK 0 91 77 0 · el acento
- #FECE00Pantone 116 CCMYK 0 19 100 0 · brillo puntual: acentúa, llama y señala
La tipografía
Tres familias, tres trabajos
Helvetica
Max Miedinger
- Neutral
- Moderna
- Universal
Sans serif. Va en títulos y encabezados. Transmite claridad, profesionalismo y precisión: representa lo vanguardista y puro del proyecto, con una estructura limpia y equilibrada.
Rústica
Tipotype Team
- Geométrica
- Fuerte
- Experimental
Sans serif contemporánea. Va en cuerpos de texto grandes o destacados. Su textura y su peso aportan presencia y autenticidad, manteniendo buena legibilidad.
Spalla
Rodrigo Saiani
- Expresiva
- Elegante
- Distintiva
Serif de display. Va en detalles, subtítulos y elementos decorativos. Funciona como contrapunto estético, sumando identidad visual y un matiz más artístico.
El reel
La marca en movimiento
En el entorno digital la identidad se adapta sin perder su esencia. El formato vertical es el de las redes, y la rotura funciona igual que en el papel: entra por la grieta.
El estilo fotográfico
Composición fuerte, contraste alto, nada centrado
Las fotografías se caracterizan por un alto nivel de composición y un tratamiento de contraste que acompaña la crudeza de la marca. No se ordenan: se apilan, como el vidrio.
El mapa conceptual
Qué somos, qué hacemos y a qué nos arriesgamos
Características
Lo que define al estudio
- Integralidad
- Disrupción
- Original
Estas palabras capturan el espíritu vanguardista, el objetivo de crear cosas nuevas, respetando el pasado y el futuro, construyendo algo que merezca la pena. Se rechazan los formatos, preconceptos y reglas aceptadas sin espíritu crítico.
Objetivos
Lo que tiene que cumplir cada trabajo
- Perfeccionismo
- Innovación
- Reivindicación
Cada trabajo busca no solo ser único, sino contener un valor más allá del técnico. Se tiene la perfección técnica como base fundamental, y encima de ella se construye lo nuevo, buscando generar reflexión y crítica.
Funciones
Lo que cada trabajo deja atrás
- Trascendencia
- Interdisciplinariedad
- Experimentalismo
Cada trabajo no finaliza con su entrega, sino que es una obra viva, cuyo valor radica en el aporte académico y cultural. Se busca la trascendencia desde el constante aprendizaje y enseñanza.
Fortalezas
Los puntos fuertes que se mantienen
- Independencia
- Libertad
- Iconicidad
Se busca mantener la libertad y la independencia como puntos fuertes, porque son los valores que dan lugar a la disrupción, y esta a lo único, a lo icónico.
Debilidades
Los riesgos de pensar así
- Elitismo
- Singularidad
- Extrañeza
La falta de normas y estándares puede llevar al rechazo por la extrañeza, así como a ser encasillados dentro del marco de algo elitista. Esos son los riesgos de tener estos objetivos.