The Serious Business Of AI - Family

How we integrate AI into our kid’s daily lives is an ongoing concern. The less we know the more worrying it can be.

I introduced my son to a lot of Math, Typing, Programming early. He has worked on 2D with Scratch and then 3D with various technologies from Blender to Unreal Engine and now JS (P5.JS).

By some bizarre twist of fate I have been home-schooling him on his first term of Secondary School. This has led to us working quite closely together with AI for the last 12 weeks.

Below is one of the AI projects he worked on today.

The Love Bug
Love Bug

Soft Body AI adjusting it’s form and effort to balance entropy HTML Code
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/p5.js"></script>
    <meta charset="utf-8" />
<style>
html, body {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
}
</style>
  </head>
  <body>
    <main>
    </main>
    <script>

// Declare variables for the physics calculations
let centerX = 0.0;
let centerY = 0.0;
let radius = 45;
let rotAngle = -90;
let accelX = 0.0;
let accelY = 0.0;
let deltaX = 0.0;
let deltaY = 0.0;
let springing = 0.001; // Reduced springing for less stiffness
let damping = 0.975; // Slightly increased damping for smoother motion

// Declare variables for specifying vertex locations
let nodes = 5;
let nodeStartX = [];
let nodeStartY = [];
let nodeX = [];
let nodeY = [];
let angle = [];
let frequency = [];

// Declare the variable for the curve tightness
let organicConstant = 1.0;

// Declare variables for obstacles
let obstacles = [];

// Player variables
let playerX = 0;
let playerY = 0;
let playerSpeed = 5;

// Sparks
let sparks = [];

function setup() {
  createCanvas(windowWidth, windowHeight);

  // Start in the center of the canvas
  centerX = width / 2;
  centerY = height / 2;
  playerX = width / 2;
  playerY = height / 2;

  // Initialize arrays to 0
  for (let i = 0; i < nodes; i++) {
    nodeStartX[i] = 0;
    nodeStartY[i] = 0;
    nodeX[i] = 0;
    nodeY[i] = 0;
    angle[i] = 0;
  }

  // Initialize frequencies for corner nodes
  for (let i = 0; i < nodes; i++) {
    frequency[i] = random(5, 12);
  }

  // Add obstacles to the canvas
  for (let i = 0; i < 50; i++) {
    obstacles.push({
      x: random(-500, 500),
      y: random(-500, 500),
      r: random(20, 40),
    });
  }

  noStroke();
  angleMode(DEGREES);
}

function draw() {
  background(0);

  // Update player position
  updatePlayer();

  // Draw obstacles
  drawObstacles();

  // Draw player
  fill(0, 255, 0);
  ellipse(width / 2, height / 2, 20);

  // Draw and move the shape
  drawShape();
  moveShape();
  
  // Update and draw sparks
  updateSparks();
  drawSparks();
}

function updatePlayer() {
  if (keyIsDown(87)) playerY -= playerSpeed; // W
  if (keyIsDown(83)) playerY += playerSpeed; // S
  if (keyIsDown(65)) playerX -= playerSpeed; // A
  if (keyIsDown(68)) playerX += playerSpeed; // D
}

function drawObstacles() {
  
  fill(139,146,98);
  for (let obs of obstacles) {
    ellipse(obs.x - playerX + width / 2, obs.y - playerY + height / 2, obs.r * 2);
  }
}

function drawShape() {
  // Calculate node starting locations
  for (let i = 0; i < nodes; i++) {
    nodeStartX[i] = centerX + cos(rotAngle) * radius;
    nodeStartY[i] = centerY + sin(rotAngle) * radius;
    rotAngle += 360.0 / nodes;
  }

  // Draw the polygon
  curveTightness(organicConstant);
  let shapeColor = lerpColor(color('blue'), color('red'), organicConstant);
  fill(shapeColor);

  beginShape();
  for (let i = 0; i < nodes; i++) {
    curveVertex(nodeX[i] - playerX + width / 2, nodeY[i] - playerY + height / 2);
  }
  endShape(CLOSE);
}

function moveShape() {
  // Move center point towards player
  deltaX = playerX - centerX;
  deltaY = playerY - centerY;

  // Create springing effect
  deltaX *= springing;
  deltaY *= springing;
  accelX += deltaX;
  accelY += deltaY;

  // Adjust center for obstacle collision
  for (let obs of obstacles) {
    let distToObstacle = dist(centerX, centerY, obs.x, obs.y);
    if (distToObstacle < radius + obs.r) {
      let overlap = radius + obs.r - distToObstacle;
      let repelX = (centerX - obs.x) / distToObstacle;
      let repelY = (centerY - obs.y) / distToObstacle;

      // Adjust position to resolve collision
      centerX += repelX * overlap * 0.5;
      centerY += repelY * overlap * 0.5;

      // Redirect velocity away from obstacle
      accelX += repelX * 0.1;
      accelY += repelY * 0.1;
    }
  }

  // Move center
  centerX += accelX;
  centerY += accelY;

  // Slow down springing
  accelX *= damping;
  accelY *= damping;

  // Change curve tightness based on the overall acceleration;
  // use abs() to avoid dependence on direction of acceleration
  organicConstant = 1 - (abs(accelX) + abs(accelY)) * 0.2;

  // Move nodes
  for (let i = 0; i < nodes; i++) {
    nodeX[i] = nodeStartX[i] + sin(angle[i]) * (accelX * 2);
    nodeY[i] = nodeStartY[i] + sin(angle[i]) * (accelY * 2);

    // Check collision with obstacles
    for (let obs of obstacles) {
      let distToObstacle = dist(nodeX[i], nodeY[i], obs.x, obs.y);
      if (distToObstacle < obs.r) {
        let overlap = obs.r - distToObstacle;
        let repelForceX = (nodeX[i] - obs.x) / distToObstacle;
        let repelForceY = (nodeY[i] - obs.y) / distToObstacle;

        // Adjust node position
        nodeX[i] += repelForceX * overlap * 0.5;
        nodeY[i] += repelForceY * overlap * 0.5;
        
        // Create sparks
        createSpark(nodeX[i], nodeY[i], repelForceX, repelForceY);
      }
    }

    angle[i] += frequency[i];
  }
}

function updateSparks() {
  for (let i = sparks.length - 1; i >= 0; i--) {
    let spark = sparks[i];
    spark.x += spark.dx;
    spark.y += spark.dy;
    spark.life--;

    // Remove dead sparks
    if (spark.life <= 0) sparks.splice(i, 1);
  }
}

function createSpark(x, y, dx, dy) {
  // Use the same color as the softbody shape for sparks
  let sparkColor = lerpColor(color('blue'), color('red'), organicConstant);

  for (let i = 0; i < 5; i++) {
    sparks.push({
      x: x,
      y: y,
      dx: dx * random(1, 3) + random(-1, 1),
      dy: dy * random(1, 3) + random(-1, 1),
      life: 30,
      color: sparkColor // Store the color for each spark
    });
  }
}

function drawSparks() {
  noStroke();
  for (let spark of sparks) {
    fill(spark.color); // Use the stored color for each spark
    ellipse(spark.x - playerX + width / 2, spark.y - playerY + height / 2, 4, 4);
  }
}
    </script>
  </body>
</html>

Fostering intelligence is a duty we take on when we become parents whether or not we work on AI

This thread is intended for parents to show off some of the positive sparks that inspire us.

2 Likes

So cool :rabbit::honeybee::heart::four_leaf_clover::infinity::arrows_counterclockwise::white_circle:
I hope others share family projects, I’m still teaching my cat and Anna uses GPT like super google but not much else lol. :stuck_out_tongue_closed_eyes: