Saltearse al contenido

Unidad 2

Introducción

En esta unidad, te sumergirás en el fascinante mundo de los vectores, las fuerzas invisibles que dan vida a tus creaciones digitales. Experimentarás con conceptos matemáticos y físicos, como velocidad y aceleración, para controlar el movimiento en tus proyectos interactivos. Aprenderás a manipular vectores en p5.js, pero recuerda que este conocimiento es aplicable a cualquier lenguaje de programación.

¿Qué aprenderás en esta unidad?

En esta fase, vas a revisar algunos conceptos básicos de vectores que ya conoces tu paso por ciencia básica.

Actividad 01

Analiza una aplicación interactiva

Enunciado: analiza el ejemple: Example 1.2: Bouncing Ball with Vectors!

  • ¿Cómo funciona la suma dos vectores?
  • ¿Por qué esta línea position = position + velocity; no funciona?

Entrega: escribe en tu bitácora la solución a las preguntas anteriores.

🚀 Tu solución:

Trabajando con vectores

En este caso tenemos algo que para poder entender, debemos entender como funciona add(), y es que en este caso ‘position’ y ‘velocity’ son vectores creados de dos dimensiones (x, y), donde ‘position’ representa la ubicación del objeto y ‘velocity’ su movimiento.

Aquí lo que pasa es que en cada fotograma, la posición se actualiza sumándole la velocidad con position.add(velocity), lo que significa que ‘position.x’ aumenta en ‘velocity.x’ y ‘position.y’ en ‘velocity.y’, lo que es en esencia la fórmula de la suma de unos vectores pero en código, y de esta manera es como se desplaza el vector en pantalla.

Ya la otra línea de código que consiste en los bordes (width o height), lo que haces es que al tocarlos la velocidad se invierte y por ende la pelota se devuelve, y poco más.

Ahora, por qué no funciona la línea ‘position = position + velocity’, el tema aquí es cómo funciona la lógica de los vectores en js, y debemos empezar porque los vectores son objetos, y es que si ‘position’ y ‘velocity’ son objetos que representan vectores, necesitas un método que entienda cómo sumar sus componentes, que en este caso, sería la función add(), ya que no puedes usar + para sumar objetos en JavaScript.

Actividad 02

Repasa

Enunciado: realiza este ejercicio del libro Exercise 1.1

  • ¿Que tuviste que hacer para hacer la conversión propuesta?

Entrega: el código del ejercicio.

🚀 Tu solución:

Convirtiendo el walker a vectores

En este caso, para poder convertir uno de los walkers que había en mi unidad 1, lo que tocaría hacer sería lo siguiente:

Primero tendríamos que reemplazar las variables ‘x’ y ‘y’ por ‘this.position’, el cual es un vector creado con createVector(width / 2, height / 2), que almacena la posición del Walker en la pantalla.

Luego, en ‘step()’, en lugar de modificar ‘x’ y ‘y’ directamente, creamos un vector ‘stepVector’ con (1,0), (-1,0), (0,1) o (0,-1), según el valor aleatorio, esto es equivalente a this.x++, this.x—, this.y++ y this.y—, y lo sumamos a ‘this.position’ usando ‘this.position.add(stepVector)’, quedando así el mismo walker pero modificado a un uso de vectores.

Ahora pondré el código actualizado con vectores:

let walker;
function setup() {
createCanvas(640, 640);
walker = new Walker();
background(95, 128, 128);
}
function draw() {
walker.step();
walker.show();
}
class Walker {
constructor() {
this.position = createVector(width / 2, height / 2);
}
show() {
stroke(0);
point(this.position.x, this.position.y);
}
step() {
let stepVector = createVector(0, 0);
const choice = floor(random(4));
if (choice == 0) {
stepVector.x = 1;
} else if (choice == 1) {
stepVector.x = -1;
} else if (choice == 2) {
stepVector.y = 1;
} else {
stepVector.y = -1;
}
this.position.add(stepVector);
}
}

Y aquí pondré la referencia del walker para que se note el cambio directo

let walker;
function setup() {
createCanvas(640, 640);
walker = new Walker();
background(95,128,128);
}
function draw() {
walker.step();
walker.show();
}
class Walker {
constructor() {
this.x = width / 2;
this.y = height / 2;
}
show() {
stroke(0);
point(this.x, this.y);
}
step() {
const choice = floor(random(4));
if (choice == 0) {
this.x++;
} else if (choice == 1) {
this.x--;
} else if (choice == 2) {
this.y++;
} else {
this.y--;
}
}
}

Investigación

¡Es hora de explorar! En esta fase, profundizarás en la teoría y práctica de los vectores a través de la lectura del capítulo 1 del libro “The Nature of Code”. Realizarás experimentos, analizarás ejemplos y te familiarizarás con las diferentes funciones de p5.js para manipular vectores.

Actividad 03

Experimenta

Enunciado: dale una mirada a este código

let position;
function setup() {
createCanvas(400, 400);
posicion = createVector(6,9);
playingVector(posicion);
noLoop();
}
function playingVector(v){
v.x = 20;
v.y = 30;
}
function draw() {
background(220);
console.log("Only once");
}

Para este experimento puedes usar las funciones console.log() y print() para imprimir mensajes en la consola del navegador. También puedes usar el método toString() de la clase p5.Vector para imprimir el vector en la consola.

  • ¿Qué resultado esperas obtener?
  • ¿Qué resultado obtuviste?
  • Recuerda los conceptos de paso por valor y paso por referencia en programación. Muestra ejemplos de este concepto en javascript.
  • ¿Qué tipo de paso se está realizando en el código?
  • ¿Qué aprendiste?

Entrega: la solución a las preguntas.

🚀 Tu solución:

Experimentando con el código

En este caso se me piden varias cosas, por lo cual primero daré las explicaciones pertinentes y luego pondré el código con comentarios que hagan referencia a los cambios hechos o a las líneas relevantes del código:

  • Primeramente usaré el console.log() y el print() para mostrar mi nombre, el vector que se crea y posteriormente el vector modificado, todo esto se debería mostrar en la consola del p5.js en la versión web.

  • Efectivamente al momento de realizar el cambio en el código implementando estas funciones, sí se realizó esto que esperaba, fue un cambio simple, pero saber que funciona nunca sobra.

  • Ahora, ¿qué tipo de paso se está realizando en este código?, en este caos tenemos un paso por referencia, en este código ‘posicion’ es un objeto ‘p5.Vector’, y los objetos en JavaScript se pasan por referencia. Cuando se llama a ‘playingVector(posicion)’, la función recibe una referencia al mismo objeto, no una copia, y es por eso que cuando modificamos ‘v.x’ y ‘v.y’ dentro de ‘playingVector(v)’, esos cambios afectan directamente a posicion en ‘setup()’.

  • Realmente no ‘recordé’ los conceptos de paso por valor y paso por referencia, los aprendí ya que no eran algo de lo que tuviera conocimiento, así que empezando por ahí ya es un aprendizaje, también entendí que la prinicpal diferencia entre las funciones console.log() y print() es que la console es para un debugging un poco más serio, mientras que print la usé para algo muy simple como simplemente escribir mi nombre, también aprendí un poco más sobre como funciona los objetos en javascript y es que estos son más complejos que un número primitivo cualquier, lo cual es realmente interesante.

  • Ahora sí, el código final modificado con lo que me esperaba encontrar en él y la explicación en comentario del paso por referencia

let position;
function setup() {
createCanvas(400, 400);
position = createVector(6, 9);
console.log("Vector original:", position.toString()); // Muestra el vector antes de modificarlo
playingVector(position);
console.log("Vector después de modificar:", position.toString()); // Muestra el vector después de modificarlo
print("Daniel Muñoz"); // Escribo mi nombre en la pestaña de mensajes de p5.js
noLoop();
}
function playingVector(v) {
// PASO POR REFERENCIA: Se modifica el mismo objeto, no una copia.
v.x = 20;
v.y = 30;
}
function draw() {
background(220);
console.log("Only once");
}

Actividad 04

Explora posibilidades

Enunciado: dale una mirada a la clase p5.Vector aquí.

  • ¿Para qué sirve el método mag()? Nota que hay otro método llamado magSq(). ¿Cuál es la diferencia entre ambos? ¿Cuál es más eficiente?
  • ¿Para qué sirve el método normalize()?
  • Te encuentras con un periodista en la calle y te pregunta ¿Para qué sirve el método dot()? ¿Qué le responderías en un frase?
  • El método dot() tiene una versión estática y una de instancia. ¿Cuál es la diferencia entre ambas?
  • Ahora el mismo periodista curioso de antes te pregunta si le puedes dar una intuición geométrica acerca del producto cruz. Entonces te pregunta ¿Cuál es la interpretación geométrica del producto cruz de dos vectores? Tu respuesta debe incluir qué pasa con la orientación y la magnitud del vector resultante.
  • ¿Para que te puede servir el método dist()?
  • ¿Para qué sirven los métodos normalize() y limit()?

Entrega: la solución a las preguntas

🚀 Tu solución:

Respondiendo a las preguntas

  • ¿Método mag(), método magSq()? | El método mag() devuelve la magnitud o longitud del vector, es decir, calcula la distancia desde el origen (0,0) hasta el punto definido por el vector, mientras que magSq() devuelve el cuadrado de la magnitud sin calcular la raíz cuadrada lo cual es más eficiente porque evita calcular la raíz cuadrada, se usa cuando solo necesitas comparar magnitudes y no la longitud exacta.

  • ¿Método normalize()? | El método normalize() convierte un vector en un vector unitario, es decir, mantiene la dirección pero lo reduce a longitud 1.

  • ¿Método dot()? | dot() mide la alineación entre dos vectores, si el resultado es positivo apuntan en la misma dirección, si es negativo apuntan en direcciones opuestas.

  • ¿Versión estática de dot(), versión de instancia de dot()? | La versión de instancia se usa cuando ya tienes un vector y quieres calcular el producto punto con otro, como por ejemplo:

let v1 = createVector(1, 2);
let v2 = createVector(3, 4);
console.log(v1.dot(v2)); // Devuelve 11 (1*3 + 2*4)

Mientras que en la versión estática no necesitas crear un objeto p5.Vector, simplemente pasas dos vectores y obtienes su producto punto, como por ejemplo:

let v1 = createVector(1, 2);
let v2 = createVector(3, 4);
console.log(p5.Vector.dot(v1, v2)); // Devuelve 11

Es una diferencia bastante simple, sigamos:

  • ¿Producto cruz de dos vectores? | El producto cruz crea un vector perpendicular a los dos originales, su magnitud indica qué tan “cruzados” están los vectores, lo que vendría siendo lo mismo a qué tan grande es el área que hay entre ellos, mientras que la orientación es hacia donde apunta este vector perpendicular a ellos. Esto sigue la “regla de la mano derecha”: el nuevo vector apunta en la dirección en que tu pulgar apunta si alineas los dedos con el primer vector y giras hacia el segundo.

  • ¿Método dist()? | El método dist() calcula la distancia entre dos vectores en el espacio, y pues podría servir para saber si un objeto está lo suficientemente cerca de otro (colisión) o en su defecto para medir distancias entre enemigos y jugadores en juegos.

  • ¿Métodos normalize() y limit()? | Ya sabemos para qué sirve normalize, y podría servir para controlar fuerzas en simulaciones físicas, o para mantener direcciones sin afectar la velocidad. Mientras que limit() restringe la magnitud de un vector a un máximo dado, esto podría servir para evitar que algunos objetos se muevan demasiado rápido en juegos o simulaciones.

Actividad 05

Interpolamos?

Enunciado: vas a tomar como inspiración este ejemplo de la referencia de p5.js:

function setup() {
createCanvas(100, 100);
}
function draw() {
background(200);
let v0 = createVector(50, 50);
let v1 = createVector(30, 0);
let v2 = createVector(0, 30);
let v3 = p5.Vector.lerp(v1, v2, 0.5);
drawArrow(v0, v1, 'red');
drawArrow(v0, v2, 'blue');
drawArrow(v0, v3, 'purple');
}
function drawArrow(base, vec, myColor) {
push();
stroke(myColor);
strokeWeight(3);
fill(myColor);
translate(base.x, base.y);
line(0, 0, vec.x, vec.y);
rotate(vec.heading());
let arrowSize = 7;
translate(vec.mag() - arrowSize, 0);
triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
pop();
}

Vas a modificarlo para generar este resultado:

Resultado

  • Analiza cómo funciona el método lerp().
  • Nota que además de la interpolación lineal de vectores, también puedes hacer interpolación lineal de colores con el método lerpColor().

Dedica un tiempo a estudiar cómo se dibuja una flecha en el método drawArrow().

Entrega:

  • El código que genera el resultado propuesto.
  • ¿Cómo funciona lerp() y lerpColor().
  • ¿Cómo se dibuja una flecha usando drawArrow()?

🚀 Tu solución:

Interpolación de vectores

En este caso para que el código propuesto termine dando como resultado la animación que se nos muestra, debemos primero que todo añadir un tercer vector, entre el rojo y el azul, esto no es complicado, pues básicamente es un vector que sea la resta entre estos vectores, posteriormente tendríamos que hacer que se interpole el vector de la mitad, el morado, este vector lo que tendría que hacer, utilizando el método lerp():

Tenemos que interpolar los dos primeros vectores, el rojo y el azul, básicamente lerp() calcula un número que esté entre dos números en un momento específico, en este caso, lerp hace que el vector morado sea la interpolación entre el vector rojo y el vector azul a lo largo del tiempo, dando como resultado un vector que va de uno al otro a lo largo del tiempo.

Ahora, hablemos del método lerpColor(), y es que si se logró entender el método lerp, lerpColor es exactamente lo mismo, pero con colores, en este caso, le dimos un color inicial (El rojo, que es el vector inicial, para que coincida al llegar a él), y un color final (El azul, que es el vector final, para que coincida al llegar a él), y también se interpola a lo largo del tiempo, esto da como resultado que al ir de un vector al otro el vector “morado” cambie de color entre un vector y otro, a lo largo del tiempo.

Esto se vería así, tal y como pide el enunciado que se vea:

image image

Y el código quedaría de la siguiente manera, con unos pequeños ajustes para mejor visualización:

let t = 0;
let increasing = true;
function setup() {
createCanvas(500, 500);
}
function draw() {
background(200);
let v0 = createVector(10, 10); // Cambio de tamaño por visualización
let v1 = createVector(400, 0); // Vector rojo, cambio de tamaño por visualización
let v2 = createVector(0, 400); // Vector azul, cambio de tamaño por visualización
let vGreen = p5.Vector.sub(v2, v1); // Vector verde: punta de rojo a punta de azul, se resta
let v3 = p5.Vector.lerp(v1, v2, t); // Vector morado en movimiento, función lerp()
// Color del vector morado
let startColor = color(255, 0, 0); // Rojo, el color del vector de arriba
let endColor = color(0, 0, 255); // Azul, el color del vector de abajo
let lerpedColor = lerpColor(startColor, endColor, t); //Transición entre los colores a lo largo del tiempo
// Dibujar vectores
drawArrow(v0, v1, 'red'); // Rojo
drawArrow(v0, v2, 'blue'); // Azul
drawArrow(p5.Vector.add(v0, v1), vGreen, 'green'); // Verde, resta entre rojo y azul
drawArrow(v0, v3, lerpedColor); // Morado en movimiento y cambiando de color
// Animación del vector morado
if (increasing) {
t += 0.02;
if (t >= 1) increasing = false;
} else {
t -= 0.02;
if (t <= 0) increasing = true;
}
}
function drawArrow(base, vec, myColor) {
push();
stroke(myColor);
strokeWeight(3);
fill(myColor);
translate(base.x, base.y);
line(0, 0, vec.x, vec.y);
rotate(vec.heading());
let arrowSize = 7;
translate(vec.mag() - arrowSize, 0);
triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
pop();
}

Actividad 06

Hagamos que todo se mueva

Enunciado: modifica de nuevo el programa de la actividad anterior, pero esta vez cambia la base de las flechas y la escala de los vectores usando el mouse.

Entrega:

  • Código con la modificación.
  • Explica cómo solucionaste el problema.

🚀 Tu solución:

Moviendo los vectores

En este caso lo único que tocaría hacer sería que la base de los vectores no empiece en un lugar específico sino que sea igual a la posición del mouse, por lo cual, en la creación de los vectores, en la posición X puse el mouse en X, y en la posición Y puse el mouse en Y, de esa forma puedo mover todos los vectores sólo moviendo el mouse, con ‘mouseX’ y ‘mouseY’.

Respecto al tamaño lo más fácil es agregar un factor multiplicador para este, de esta manera se puede aumentar o disminuir el tamaño dependiendo de este factor, este factor se modificaría con la rueda del mouse, subiéndola y bajándola, esto no es complicado pues es en esencia una función que ya está en js, la cual sería ‘mouseWheel’, esta modificaría el factor, y a su vez el factor se multiplicaría por la escala, todo esto se regula para que el tamaño no exceda los límtes del canvas.

Siendo así las cosas, el código sería este:

let t = 0;
let increasing = true;
let scaleFactor = 1; // Factor de escala inicial
function setup() {
createCanvas(700, 700);
}
function draw() {
background(200);
let v0 = createVector(mouseX, mouseY); // Base de las flechas sigue el mouse
let v1 = createVector(250, 0).mult(scaleFactor); // Vector rojo escalado
let v2 = createVector(0, 250).mult(scaleFactor); // Vector azul escalado
let vGreen = p5.Vector.sub(v2, v1); // Vector verde: punta de rojo a punta de azul
let v3 = p5.Vector.lerp(v1, v2, t); // Vector morado interpolado
// Color del vector morado
let startColor = color(255, 0, 0); // Rojo (color del vector rojo)
let endColor = color(0, 0, 255); // Azul (color del vector azul)
let lerpedColor = lerpColor(startColor, endColor, t); //Transición de color
// Dibujar vectores
drawArrow(v0, v1, 'red'); // Rojo
drawArrow(v0, v2, 'blue'); // Azul
drawArrow(p5.Vector.add(v0, v1), vGreen, 'green'); // Verde
drawArrow(v0, v3, lerpedColor); // Morado interpolado
// Animación del vector morado
if (increasing) {
t += 0.02;
if (t >= 1) increasing = false;
} else {
t -= 0.02;
if (t <= 0) increasing = true;
}
}
// Función para dibujar una flecha
function drawArrow(base, vec, myColor) {
push();
stroke(myColor);
strokeWeight(3);
fill(myColor);
translate(base.x, base.y);
line(0, 0, vec.x, vec.y);
rotate(vec.heading());
let arrowSize = 7;
translate(vec.mag() - arrowSize, 0);
triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
pop();
}
// Cambiar la escala de los vectores con la rueda del mouse
function mouseWheel(event) {
scaleFactor += event.delta * -0.001; // Ajustar sensibilidad de la escala
scaleFactor = constrain(scaleFactor, 0.5, 2.5); // Limitar el tamaño
}

Actividad 07

Motion 101

Entrega: ahora vas a leer y analizar con mucho detenimiento la sección Motion with vectors. El autor propone un marco de movimiento llamado motion 101.

¿En qué consiste motion 101?

Entrega: la respuesta a la pregunta e ilustra con un ejemplo.

🚀 Tu solución:

Motion 101

En esencia, este código representa un concepto básico de movimiento en p5.js, conocido como “Movimiento 101” o en este caso, en inglés “Motion 101”, donde un objeto se desplaza sumando su velocidad a su posición en cada fotograma, creando un movimiento constante y sin aceleración, es algo bastante básico pero es una buena forma de empezar a entender movimiento por vectores. También tenemos que si el objeto alcanza un borde de la pantalla, reaparece del lado opuesto mediante la función checkEdges(). La clase Mover define la posición, velocidad y métodos para actualizar y dibujar el objeto, mientras que el programa principal (setup() y draw()) gestiona su ciclo de vida, asegurando que el objeto se mueva, reaparezca en los bordes y se renderice correctamente en cada iteración que hace el programa, en general es algo simple en animación por codificación.

Y qué mejor ejemplo que el que nos brinda la sección (Ligeramente modificado por colores):

image image

Actividad 08

Experimenta

Enunciado: realiza un experimento para basado en el ejemplo 1.7.

  • Entiende el ejemplo.
  • Vas a proponer una modificación mediante esta pregunta que te harás: ¿Qué pasa si…?
  • ¿Qué te imaginas que pasará?
  • ¿Qué pasó?
  • ¿Por qué?
  • Concluye

Entrega: la respuesta a las cuestiones anteriores.

🚀 Tu solución:

Experimentando con el movimiento

El ejemplo se entiende debido a la actividad anterior, en donde precisamente se explica como funciona el movimiento y posteriormente se muestra el código y la vista previa de este, ahora, siguiendo propiedades físicas básicas, qué pasaría si teniendo en cuenta que la velocidad es la derivada del movimiento, derivamos nuevamente la velocidad para conseguir una aceleración, es decir:

  • ¿Qué pasaría si añadimos un vector de aceleración y este se lo sumamos a la velocidad?

  • Supongo que lo que pasará es que efectivamente habrá una aceleración constante ilimitada, pues será cada que se haga una iteración, en un principio no tengo pensado limitarla o controlarla

  • Al principio reemplacé la velocidad por la aceleración, pero esto fue una falla al escribir el código jajaja, puse que se le añadiera la aceleración a la posición en lugar de a la velocidad, sin embargo, al corregir es un hecho que funcionó como se esperaba, era algo bastante intuitivo, pero de esta forma podemos hacer más cosas, incluso, después de cierto tiempo desacelerar nuevamente, y si ponemos límites podemos tener un control absoluto de todo

  • Pues en este caso el porqué es que se está sumando la aceleración con la velocidad, y la velocidad con el tiempo, creando así lo que en física conocemos como doble derivada, o segunda derivada, que en este caso al estar hablando del movimiento, la primera derivada es la velocidad, y al derivar esta, tenemos la aceleración, entonces, en esencia, al movimiento se le está sumando el vector de velocidad, mientras que al vector de velocidad se le está sumando constantemente el vector de aceleración, como anteriormente dije, aquí lo importante no es controlar, sino experimentar, y funcionó

  • Llega un punto en que sin un límite de velocidad, la aceleración constante hace que el objeto se mueva cada vez más rápido, lo que puede llevar a parecer que el objeto se teletransporta de un lado a otro, lo que lo hace poco realista, esto se puede controlar uun poco, más o menos, y también depende un poco de la velocidad inicial la cual es aleatoria en cierto rango, pero sigue sin tener un límite así que eventualmente siempre tendrá este comportamiento

Código modificado de la clase mover:

class Mover {
constructor() {
this.position = createVector(random(width), random(height));
this.velocity = createVector(random(-2, 2), random(-2, 2));
this.aceleracion = createVector(0.01, 0.01);
}
update() {
this.velocity.add(this.aceleracion)
this.position.add(this.velocity);
}
show() {
stroke(0);
strokeWeight(2);
fill(95,200,200);
circle(this.position.x, this.position.y, 48);
}
checkEdges() {
if (this.position.x > width) {
this.position.x = 0;
} else if (this.position.x < 0) {
this.position.x = width;
}
if (this.position.y > height) {
this.position.y = 0;
} else if (this.position.y < 0) {
this.position.y = height;
}
}
}

Actividad 09

Experimentando con la aceleración

Enunciado: en el libro proponen una regla (que eventualmente se rompe cuando conviene :)):

The goal for programming motion is to come up with an algorithm for calculating acceleration and then let the trickle-down effect work its magic.

Para investigador el significado de esta frase te propone que construyas un experimento donde analices cómo se comporta un objeto en movimiento con:

  • Aceleración constante.
  • Aceleración aleatoria.
  • Aceleración hacia el mouse.

Entrega:

  • Reporta que encontraste para cada una de las posibles aceleraciones
  • ¿Por qué?

🚀 Tu solución:

Aceleraciones

  • Aceleración constante: Realmente en la actividad anterior prácticamente realicé el experimento con la aceleración constante, cosa que honestamente no fue a propósito, pero claramente la conclusión es la misma, debo decir que es un hecho que en un principio todo parece normal, el objeto inicia con una velocidad determinada y empieza a acelerar muy lentamente debido a los valores, se ve bien, se ve cómodo y pues se nota la aceleración, sin embargo llega un punto en que esto se vuelve incontrolable y el objeto debido a limitaciones visuales y por otro lado falta de límites de velocidad, llega un punto en que su visualización se vuelve errática, parece estarse teletrasportando por todos lados en la pantalla.

Todo esto se debe a que la aceleración suma y suma, y en ningún momento se limita su velocidad. No hay ningún control prácticamente.

  • Aceleración aleatoria: En este caso fue algo bastante más cómodo de ver, es cierto que puede que el objeto llege a ser bastante rápido, sin embargo al ser una aceleración aleatoria, es muy probable que sea entre un rango, lo cual hace que el objeto acelere y frene constantemente, incluso puede que cambie de de trayectoria y se devuelva, sin necesidad de llamar a la función checkEdges(), esto siempre y cuando las aceleraciones se pongan en un rango negativo, positivo; también se puede decir que con el simple hecho de tener una aceleración aleatoria, este control pasa a ser mínimo, ya que aunque acelere más o menos, sigue acelerando, lo ideal para lograr el efecto antes mencionado, es la técnica antes mencionada, es decir, una aceleración aleatoria entre un rango negativo, positivo, para así tener ciclos de aceleración y frenados constantes, de manera aleatoria.

Esto depende completamente de los rangos puestos en la aleatoreidad, es decir, puede ser una aceleración tirando a constante, pero más o menos rápida, o puede ser un movimiento aleatorio de un lado a otro. Hay un control mediano.

  • Aceleración hacia el mouse: En este caso tenemos un control mucho más avanzado, e incluso podemos llegar a tener prácticamente limitaciones de velocidad, al tener una aceleración hacia el mouse podemos hacer que el objeto se acelere constamente hacia una posición, o no tiene que ser hacia una, pero si podemos hacer que acelere constantemente, también, podemos hacer que el objeto acelere y frene, hacia donde queremos todo el tiempo, podemos ponerlo a dar vueltas en un lugar, a trazar una cierta línea con una especie de suavizado dependiendo de la aceleración que tenga en el momento, etc, es algo que podría servir bastante como aplicación interactiva, y probablemente este sea uno de los principios que siguen aplicaciones como Photoshop para realizar el suavizado de trazos al momento de estar dibujando.

Esto depende plenamente de hacia donde movamos el mouse y qué tanta ventaja le dejemos coger a la aceleración. Tenemos un control casi total.

Aplicación

En esta fase, aplicarás tus conocimientos sobre vectores para crear arte generativo algorítmico. Pondrás en práctica los conceptos aprendidos en las fases anteriores.

Actividad 10

Diseño: exploración de la idea

Enunciado: diseña una aplicación interactiva en tiempo que utilice los conceptos que investigaste. La aplicación debe:

  • Generar una pieza de arte generativo algorítmico.
  • Debes aplicar el marco MOTION 101.
  • El contenido generado debe ser interactivo. Puedes utilizar mouse, teclado, cámara, micrófono, etc, para variar los parámetros del algoritmo en tiempo real.

Entrega:

  • Un texto donde expliques tu intención de diseño.
  • ¿Cómo piensas aplicar el marco MOTION 101 y por qué estos?
  • Reporta los referentes que usaste para inspirarte.

🚀 Tu solución:

Diseñando ideas

  • Se me ocurre algo en donde puedo aplicar el concepto de vectores, motion 101, y la aceleración: Me parece que podría hacer una aplicación en donde la bolita, esté en un plano gris, o blanco, es irrelevante el color del fondo, y que esta bolita, tenga una aceleración aleatoria, de esta manera tendría un movimiento un poco natural, fluido y con un límite de velocidad le podríamos dar un control interesante para que nunca llegue a ser un movimiento errático, ahora, esto sería lo que deje un trazo para plasmar algo, se me ocurre que al momento de dar click, la bolita se transporte a ese lugar, y siga con su movimiento, sin embargo, donde entran los vectores es que entre un click y otro habrá una línea que muestre estos saltos, de esta manera, podemos ver donde empiezan y terminan los mismos, y qué tanto se aleja esta bolita de cada “punto de rebote” por así decirlo, viendo el trazado que esta deja.

Es decir, una pelota blanca que deje un trazado aleatorio en cierta zona debido a una aceleración aleatoria controladda, esta zona sería la A, al dar click en otro lugar, esta salta a este lugar, dejando un vector desde el punto A, hasta el B, al llegar al punto B seguirá con su movimiento aleatorio y dejará un trazado, dejando así evidencia de qué tanto se movió esta pelota alrededor del punto B, y dejando también evidencia los saltos hechos y los lugares.

  • Esta idea sigue el marco Motion 101 porque separa la posición, velocidad y aceleración, lo que permite un movimiento más dinámico y natural en lugar de simplemente trasladar el objeto de un punto a otro. La aceleración aleatoria afecta la velocidad, y esta, a su vez, cambia la posición, creando un efecto acumulativo que imita fuerzas externas como el viento o la inercia.

En esencia algo así:

image

Actividad 11

Materialización

Enunciado: vas a implementar tu aplicación diseñada.

Entrega:

  • Código de la aplicación.
  • Captura del contenido generado.
  • En caso de realizar alguna variación al concepto original, escribe un texto donde expliques la razón del cambio.

🚀 Tu solución:

Codificando la idea:

  • El único cambio que hice realmente fue de estética, ahora los vectores de salto de posición no quedaron rojos, sino que van cambiando aleatoriamente de salto en salto, esto para que se vea algo un poco diferente, y no tan monótono y simple

Aquí se puede probar la aplicación

Se vería algo así:

image

Y así quedaría el código:

class Mover {
constructor() {
this.position = createVector(random(width), random(height));
this.velocity = createVector(0, 0);
this.acceleration = createVector(0, 0);
this.trail = []; // Almacena todas las posiciones anteriores
}
update() {
this.acceleration = createVector(random(-0.1, 0.1), random(-0.1, 0.1));
this.velocity.add(this.acceleration);
// Limitar la velocidad máxima
this.velocity.limit(2);
this.position.add(this.velocity);
// Agregar la posición actual al rastro (ahora sin límite)
this.trail.push(createVector(this.position.x, this.position.y));
}
show() {
// Dibujar el rastro normal
stroke(255, 165, 0, 150);
strokeWeight(2);
noFill();
beginShape();
for (let p of this.trail) {
vertex(p.x, p.y);
}
endShape();
fill(95, 200, 200);
stroke(0);
strokeWeight(3);
circle(this.position.x, this.position.y, 25);
}
checkEdges() {
if (this.position.x > width) this.position.x = 0;
if (this.position.x < 0) this.position.x = width;
if (this.position.y > height) this.position.y = 0;
if (this.position.y < 0) this.position.y = height;
}
teleport(x, y) {
let randomColor = color(random(255), random(255), random(255));
teleportLines.push({start: this.position.copy(), end: createVector(x, y), color: randomColor}); // Guarda la línea de teletransporte con color aleatorio
this.position.set(x, y);
}
}
let mover;
let clickPositions = []; // Lista para almacenar los clics
let teleportLines = []; // Lista para almacenar las líneas de teletransporte
function setup() {
createCanvas(640, 640);
mover = new Mover();
}
function draw() {
background(155, 155, 155);
// Dibujar las líneas de teletransporte con flecha y color aleatorio
strokeWeight(3);
for (let lineData of teleportLines) {
stroke(lineData.color);
line(lineData.start.x, lineData.start.y, lineData.end.x, lineData.end.y);
drawArrow(lineData.start, lineData.end, lineData.color);
}
// Dibujar los puntos rojos de los clics anteriores
fill(255, 0, 0);
noStroke();
for (let pos of clickPositions) {
circle(pos.x, pos.y, 8);
}
mover.update();
mover.checkEdges();
mover.show();
}
function mousePressed() {
mover.teleport(mouseX, mouseY);
clickPositions.push(createVector(mouseX, mouseY)); // Guarda la posición del clic
}
function drawArrow(start, end, color) {
push();
let angle = atan2(end.y - start.y, end.x - start.x);
let arrowSize = 10;
translate(end.x, end.y);
rotate(angle);
fill(color);
noStroke();
triangle(-arrowSize, -arrowSize / 2, -arrowSize, arrowSize / 2, 0, 0);
pop();
}

Consolidación y matacognión

En esta fase final, reflexionarás sobre tu proceso de aprendizaje. Analizarás tus logros, identificarás áreas de mejora y consolidarás tu comprensión de los vectores y su aplicación.

Actividad 12

Análisis de resultados

Enunciado: revisa los resultados de las actividades de la fase APPLY. ¿Qué desafíos encontraste al aplicar los conceptos aprendidos? ¿Qué aprendiste de estos desafíos?

Entrega: descripción de los desafíos encontrados y las lecciones aprendidas durante la fase APPLY.

🚀 Tu solución:

Reflexionemos del proceso

  • En este caso, en la fase de APPLY los principales desafíos fueron al momento de implementar el código, a decir verdad en esta ocasión si que prácticamente todo lo hice con ayuda de la IA respecto al código, el diseño de la idea y el concepto si fueron algo mío, pero en este caso aplicarlos se me dificultó bastante ya que tocaba hacer listas para guardar el recorrido de los saltos, luego el tema de los vectores diferentes, el recorrido, etc, son cosas que honestamente no tuve muy claro como hacer en un principio y tuve que preguntar bastante a ChatGPT.

  • El tema es que a pesar de estos desafíos pude mejorar un poco la lógica que tenía respecto a eso, ya que yo creía que para poder implementar lo que tenía en mente se debía hacer de una forma específica, cuando realmente había otras maneras de hacerlo, también, aunque no está relacionado directamente con el curso, estoy mejorando bastante a la hora de pedirle a ChatGpt que me ayude codificando, y no sé si eso sea negativo o positivo, pero a mí es algo que me ayuda bastante debido a mis falencias respecto a la programación. En cuanto al tema de vectores, considero que lo tengo bastante claro, realmente viendo los conceptos de los que se hablaba en esta unidad, me parece que voy bastante bien en el tema.

Actividad 13

Conexión con Diseño de Entretenimiento Digital

Enunciado: describe cómo los conceptos de esta unidad pueden ser utilizados en el diseño de videojuegos, experiencias interactivas o animaciones. Da ejemplos concretos.

Entrega: descripción de al menos tres aplicaciones de los conceptos aprendidos en el diseño de entretenimiento digital, con ejemplos concretos.

🚀 Tu solución:

Aplicaciones en el entretenimiento digital

Me parece que estos conceptos son fundamentales en el diseño de entretenimiento digital, y es que es un hecho que realmente los vectores son una base fundamental en el movimiento, teniendo en cuenta que como tal el vector de posición, de velocidad y aceleración pueden formar entre si una gama de movimientos complejos y naturales, tanto en animaciones como videojuegos y por ende llegando al campo de las experiencias interactivas de forma aún más compleja.

  • Por ejemplo, se me ocurre que para empezar, en los videojuegos, en un juego de plataformas, un personaje se mueve con aceleración y velocidad, aquí ya se implementan los vectores, y de esta forma al caer el personaje, saltar, etc, este tiene una aceleración mucho más realista, simulando diferentes gravedades modificando algo tan simple como el valor del vector de la aceleración.

  • Otro ejemplo en los videojuegos, sean en 3D o en 2D, es en los momentos de sigilo, en donde la función dist() podría ser esencial para verificar si el jugador está en el campo de visión de un enemigo, empezando así la alerta, en este caso, en juegos 3D más complejos, se agregaría la función de dot(), para saber si el enemigo está viendo o no al jugador, alertándolo así de manera inmediata o ‘ignorando’ su presencia, como resultado el enemigo detecta al jugador solo si está dentro de su ángulo de visión, tal y como se puede ver por ejemplo en la serie de videojuegos de Far Cry:

  • Ahora, en la animación esto sería muy útil para movimientos naturales, por ejemplo, en una cinemática de un juego, una soga se balancea de forma realista cuando un personaje la sujeta, esto no tiene por qué hacerse a mano, con el uso de dot() y mag() se podrían calcular ángulos y fuerzas para lograr un movimiento oscilante realista.

Ejemplo en far cry (Enemigos alertados): image

Actividad 14

Reflexión sobre el proceso de aprendizaje

Enunciado: reflexiona sobre tu propio proceso de aprendizaje durante esta unidad. ¿Qué estrategias te resultaron más efectivas para comprender los conceptos? ¿Qué podrías mejorar en futuras unidades?

Entrega:

  • Descripción de las estrategias de aprendizaje utilizadas y su efectividad.
  • Planteamiento de mejoras para futuras unidades.

🚀 Tu solución:

Estrategias de aprendizaje

  • Realmente en general he seguido con un proceso similar, he visto las explicaciones técnicas que hay en las páginas propuestas, he buscado aparte tanto en internet como preguntado a la IA, para poder quitarle el miedo al nuevo concepto, de esta manera lo que logro es meterme de lleno con temas técnicos para así poder tener un proceso de avance y conocer nuevas palabras, nuevos conceptos y ampliar mis conocimienots esforzándome un poco en entender todo lo nuevo que haya, mientras que por otro lado lo que hago es tratar de comparar con cosas que ya he visto, que ya conozco, que ya me resultan familiares, de esta forma puedo fortalecer la memorización y facilitar la compresión de todo lo que no conozco aún, y es un hecho que al compararlo fortalezco estos conceptos, ya que inconscientemente siento que ya sabía de qué se trataban.

Hasta ahora este método me ha parecido muy efectivo, me parece que es lo mejor para comprender nuevas cosas, lo único que estoy tratando es de entrenarlo y perfeccionarlo, de aprender a buscar en los lugares adecuados, y de entender cómo puedo ser más preciso y que me queden más claras todas las cosas que veo y leo.

  • Ahora, en cuanto a tema de mejoras, es un hecho que ya me pasó que ví todos los conceptos y creí y realmente sentí que ya los tenía claros en su totalidad, posteriormente caía en cuenta que se me habian olvidado algunas cosas, de hecho habían conceptos que sabía que había visto pero por algún motivo aunque no fueran de difícil comprensión, se me escapaba todo recuerdo que tenía de ellos, esto se debe a que quizá no hago el trabajo de reforzarlos correctamente, y he pensado en varias falencias que tengo al momento de hacerlo, y es que no aplico estos conceptos tan conscientemente en mi código y quizá por eso es que los doy por sentados y al momento de regresar a ellos me quedo en blanco, por lo cual debería prestar más atención a estos y en cómo los aplico, también me pasa que no los repaso lo suficiente, sino cuando ya vuelvo a tener clase, que aunque en ocasiones es un día después, hay otras veces que toca esperar una semana, eso hace que en ese transcurso entre tantas cosas que pasan por mi cabeza y en mi vida, estos se vayan dejando de lado y luego incluso se me pasa repasarlos nuevamente, lo cual genera una bola de nieve y hace que se debilite la memorización.

En resumen me parece que debería tener en cuenta estas dos cosas, aplicar los conceptos más conscientemente y repasarlos más seguido para no tener problema con la memorización.

Actividad 15

Autoevaluación

Enunciado: evalúa tu nivel de comprensión de los conceptos de la unidad en una escala del 1 al 5 (1: Nada de comprensión, 5: Dominio completo). Justifica tu autoevaluación con ejemplos concretos de tu trabajo en la unidad. Identifica áreas donde necesitas reforzar tu aprendizaje.

Entrega:

  • Autoevaluación con justificación y ejemplos concretos de tu trabajo que sustenten.
  • Identificación de áreas de mejora.

🚀 Tu solución:

Autoevaluación de Unidad 2

  • Autoevaluación: 4/5

Me parece que en esta unidad he tenido un desempeño mejor al de la anterior, pero aún así me daré una menor calificación ya que ahora entiendo cuales fueron mis falencias en la anterior unidad y soy más consciente de las mismas, es cierto que siento que lo comprendo todo, recuerdo casi todos los conceptos vistos y me parece que aunque algunos no se me vienen a la mente, si me preguntan por ellos sabré responder de qué tratan y también si utilizo la lógica podría decir cómo podrían aplicarse al momento de codificar, sea en videojuegos o en animaciones, etc. Aunque debo decir que esto tiene bastante que ver con que en esta unidad hablamos de vectores, un tema al cual se le llegó a dar mucha importancia en materias diferentes, años anteriores y todo porque es un concepto fundamental en la física y por ende la comprensión de muchas fuerzas y bases de movimiento en general, quizá por esto ya venía con mayores conocimientos previos y hace que esto que vi en esta unidad sea más un refuerzo, aún así sé que hay conceptos que quizá mezcle, pero en general me parece que lo tengo todo bastante claro.

En la unidad en general apliqué todos los conceptos cuando se me pedía, pero me pasó lo que llegué a mencionar en la actividad anterior, posteriormente no los volví a tener en cuenta y esto se nota en el diseño de la aplicación, se me ocurrió más adelante que pude hacer que en la consola se hicieran los cálculos de los saltos de posición, mostrando la magnitud de los vectores, la posición, o cosas por el estilo con las funciones que llegué a ver en las actividades del principio y en las cuales se me pidió utilizarlas, esto me parece muy importante y es que ahora me parece muy claro, pero en su momento evidentemente se me pasó, aún así no quería dejar pasar la oportunidad de hacer saber que caí en cuenta, un poco tarde, pero lo hice, me parece buena idea haber mostrado esos cálculos en la consola, no creo que hubiera sido difícil y le hubiera dado un plus muy interesante a la aplicación.

Aún así está lo que dije, los conceptos los apliqué en su momento, cuando se me pidió hacerlo, no estoy seguro si esto cuenta pero es lo que se me pregunta jaja, por ende me parece que en general me fue bastante bien y siendo objetivos me fue mejor que en la unidad anterior, pero ahora comprendo que la exigencia debe ser mayor y por eso aunque me fue mejor, me parece más justa una nota menor.