Visualizar una función en una computadora significa convertir valores matemáticos en puntos de una pantalla. Para lograrlo hay que calcular muestras, transformar escalas y decidir cómo representar ejes, curvas y rangos.
La visualización ayuda a interpretar crecimiento, máximos, mínimos, discontinuidades, oscilaciones y comportamientos que no siempre son evidentes solo mirando la fórmula.
Una computadora no dibuja una curva infinita. Calcula muchos puntos y luego los une o los muestra uno por uno.
function f(x) {
return x * x;
}
const puntos = [];
for (let x = -3; x <= 3; x++) {
puntos.push({ x, y: f(x) });
}
console.log(puntos);
Cada objeto representa un punto de la gráfica.
Muestrear consiste en elegir valores de x dentro de un intervalo y calcular sus valores de y.
function muestrear(funcion, desde, hasta, cantidad) {
const puntos = [];
const paso = (hasta - desde) / (cantidad - 1);
for (let i = 0; i < cantidad; i++) {
const x = desde + i * paso;
puntos.push({ x, y: funcion(x) });
}
return puntos;
}
const puntos = muestrear(x => Math.sin(x), 0, Math.PI, 6);
console.log(puntos);
La cantidad de muestras afecta la calidad visual. Pocas muestras pueden producir una curva angular o perder detalles importantes.
function contarPuntos(desde, hasta, paso) {
return Math.floor((hasta - desde) / paso) + 1;
}
console.log("Paso 1:", contarPuntos(0, 10, 1), "puntos");
console.log("Paso 0.25:", contarPuntos(0, 10, 0.25), "puntos");
Más puntos dan más detalle, pero también requieren más cálculo.
Los valores matemáticos deben convertirse a píxeles. Una función de mapeo permite pasar de un rango matemático a un rango visual.
function mapear(valor, minOrigen, maxOrigen, minDestino, maxDestino) {
const proporcion = (valor - minOrigen) / (maxOrigen - minOrigen);
return minDestino + proporcion * (maxDestino - minDestino);
}
const xMatematico = 0;
const xPixel = mapear(xMatematico, -10, 10, 0, 500);
console.log("x en pantalla:", xPixel);
En muchas pantallas, el eje y crece hacia abajo. En matemática, normalmente crece hacia arriba. Por eso suele invertirse al dibujar.
function yAPixel(y, yMin, yMax, alto) {
const proporcion = (y - yMin) / (yMax - yMin);
return alto - proporcion * alto;
}
console.log(yAPixel(1, -1, 1, 300));
console.log(yAPixel(-1, -1, 1, 300));
Después de muestrear una función, se transforman todos los puntos al sistema de coordenadas de la pantalla.
function mapear(valor, minOrigen, maxOrigen, minDestino, maxDestino) {
const proporcion = (valor - minOrigen) / (maxOrigen - minOrigen);
return minDestino + proporcion * (maxDestino - minDestino);
}
function puntoAPixel(punto, rangoX, rangoY, ancho, alto) {
return {
x: mapear(punto.x, rangoX.min, rangoX.max, 0, ancho),
y: mapear(punto.y, rangoY.min, rangoY.max, alto, 0)
};
}
const punto = { x: 2, y: 4 };
console.log(puntoAPixel(punto, { min: -5, max: 5 }, { min: -10, max: 10 }, 400, 300));
Para ajustar una gráfica a los datos, se pueden calcular mínimos y máximos de los puntos generados.
function rangoY(puntos) {
const valoresY = puntos.map(punto => punto.y);
return {
min: Math.min(...valoresY),
max: Math.max(...valoresY)
};
}
const puntos = [
{ x: 0, y: 4 },
{ x: 1, y: -2 },
{ x: 2, y: 7 }
];
console.log(rangoY(puntos));
Si una gráfica usa exactamente el mínimo y el máximo, puede quedar pegada al borde. Agregar margen mejora la lectura.
function agregarMargen(rango, porcentaje) {
const amplitud = rango.max - rango.min;
const margen = amplitud * porcentaje;
return {
min: rango.min - margen,
max: rango.max + margen
};
}
console.log(agregarMargen({ min: -2, max: 8 }, 0.1));
Los ejes se ubican convirtiendo el valor matemático cero a coordenadas de pantalla. Si el cero está fuera del rango, el eje puede no aparecer.
function mapear(valor, minOrigen, maxOrigen, minDestino, maxDestino) {
const proporcion = (valor - minOrigen) / (maxOrigen - minOrigen);
return minDestino + proporcion * (maxDestino - minDestino);
}
const xEjeY = mapear(0, -10, 10, 0, 500);
const yEjeX = mapear(0, -5, 5, 300, 0);
console.log("Eje Y en x =", xEjeY);
console.log("Eje X en y =", yEjeX);
Las marcas ayudan a leer valores sobre los ejes. Se generan a intervalos constantes.
function generarMarcas(desde, hasta, paso) {
const marcas = [];
for (let valor = desde; valor <= hasta; valor += paso) {
marcas.push(Number(valor.toFixed(10)));
}
return marcas;
}
console.log(generarMarcas(-2, 2, 0.5));
Algunas funciones no están definidas en ciertos puntos o tienen saltos. La visualización debe evitar unir puntos que no pertenecen a la misma rama.
function inversa(x) {
if (x === 0) {
return null;
}
return 1 / x;
}
const valores = [-2, -1, 0, 1, 2].map(x => ({ x, y: inversa(x) }));
console.log(valores);
El valor null indica que en ese punto no se debe dibujar una conexión normal.
Algunas funciones pueden producir Infinity o NaN. Estos valores deben filtrarse antes de dibujar.
function esPuntoValido(punto) {
return Number.isFinite(punto.x) && Number.isFinite(punto.y);
}
const puntos = [
{ x: 1, y: 2 },
{ x: 0, y: Infinity },
{ x: 2, y: NaN }
];
console.log(puntos.filter(esPuntoValido));
Comparar funciones requiere generar series separadas. Cada serie puede tener su propio nombre, color y lista de puntos.
function muestrear(nombre, funcion, desde, hasta, cantidad) {
const puntos = [];
const paso = (hasta - desde) / (cantidad - 1);
for (let i = 0; i < cantidad; i++) {
const x = desde + i * paso;
puntos.push({ x, y: funcion(x) });
}
return { nombre, puntos };
}
const series = [
muestrear("lineal", x => x, -2, 2, 5),
muestrear("cuadrática", x => x * x, -2, 2, 5)
];
console.log(series);
Una visualización puede usar colores para destacar zonas positivas, negativas, altas o bajas.
function colorSegunValor(y) {
if (y > 0) {
return "verde";
}
if (y < 0) {
return "rojo";
}
return "gris";
}
console.log(colorSegunValor(4));
console.log(colorSegunValor(-2));
console.log(colorSegunValor(0));
Hacer zoom en una función significa reducir el rango visible. La función no cambia; cambia la ventana de visualización.
function aplicarZoom(rango, factor) {
const centro = (rango.min + rango.max) / 2;
const mitad = (rango.max - rango.min) / (2 * factor);
return {
min: centro - mitad,
max: centro + mitad
};
}
console.log(aplicarZoom({ min: -10, max: 10 }, 2));
Desplazar la vista consiste en mover el rango visible sin modificar la función original.
function desplazarRango(rango, delta) {
return {
min: rango.min + delta,
max: rango.max + delta
};
}
console.log(desplazarRango({ min: -5, max: 5 }, 3));
Una visualización puede cambiar con el tiempo si la función depende de un parámetro adicional.
function onda(x, tiempo) {
return Math.sin(x + tiempo);
}
for (let frame = 0; frame < 4; frame++) {
const tiempo = frame * 0.5;
console.log("Frame", frame, "f(1):", onda(1, tiempo).toFixed(3));
}
Las etiquetas numéricas deben ser legibles. Mostrar demasiados decimales puede dificultar la interpretación.
function formatearEtiqueta(valor) {
return Number(valor.toFixed(2)).toString();
}
console.log(formatearEtiqueta(3.141592));
console.log(formatearEtiqueta(2.00001));
Aunque el dibujo final dependa de una tecnología específica, la preparación matemática puede mantenerse separada.
function construirPolyline(puntos) {
return puntos
.map(punto => `${punto.x.toFixed(1)},${punto.y.toFixed(1)}`)
.join(" ");
}
const puntosPixel = [
{ x: 0, y: 100 },
{ x: 50, y: 80 },
{ x: 100, y: 120 }
];
console.log(construirPolyline(puntosPixel));
La cadena resultante podría usarse como atributo points en un elemento SVG.
La visualización computacional de funciones se usa en:
Al visualizar funciones conviene evitar estos problemas:
Visualizar una función en una computadora implica transformar una relación matemática en una representación discreta y legible. Para eso se necesitan funciones de muestreo, mapeo, escalado y filtrado.
Una buena visualización no solo dibuja puntos: ayuda a comprender el comportamiento de la función, sus límites, sus cambios y sus zonas importantes.