createSlider does not work sometimes

So in the start of my code, I define time as the return value of createSlider(0, 1, 1 / animationSmoothness, where animationSmoothness is 16. But when I try to call the value() method of time, an error shows up. Why?

Code:

let i = {};
let j = {};

let matrix;
let determinant;
let animated;

let time = 0;

const accuracy = 16;
const animationSmoothness = 1024;

const defaultMatrix = [
  [ 1, 0 ],
  [ 0, 1 ]
];

const gridLineColor = {
  "red"   : 32,
  "green" : 32,
  "blue"  : 128
};

function toCartesian(x, y, width, height) {
  return [
    x + (width  / 2),
    y + (height / 2)
  ];
}

function fromCartesian(x, y, width, height) {
  return [
    x - (width  / 2),
    y - (height / 2)
  ];
}

function linearTransformation(i, j, x, y) {
  return [
    (x * i.x) + (y * j.x),
    (x * i.y) + (y * j.y)
  ];
}

function animatedLinearTransformation(basis1, basis2, time) {
  let transformations = Array(animationSmoothness);
  
  for (let i = 0; i < animationSmoothness; i += 1) {
    if (i > (1 / time)) {
      transformations[i] = basis2;
    }
    else {
      transformations[i] = basis1;
    }
  }
  
  let out = [ 0, 0 ];
  
  for (let i = 0; i < animationSmoothness; i += 1) {
    out[0] += transformations[i][0];
    out[1] += transformations[i][1];
  }
  
  out[0] /= animationSmoothness;
  out[1] /= animationSmoothness;
  
  return out;
}

function setup() {
  createCanvas(512, 512);
  
  background(0);
  
  strokeWeight(1);
  stroke(255);
  
  i.x = createSlider(-2, +2, defaultMatrix[0][0], 1 / 16);
  i.y = createSlider(-2, +2, defaultMatrix[0][1], 1 / 16);
  
  i.text = createP();
  
  katex.render("\\color{white}{i}", i.text.elt);
  
  
  j.x = createSlider(-2, +2, defaultMatrix[1][0], 1 / 16);
  j.y = createSlider(-2, +2, defaultMatrix[1][1], 1 / 16);

  j.text = createP();
  
  katex.render("\\color{white}{j}", j.text.elt);
  
  
  i.x.position(width / 2, height + 16);
  i.y.position(width / 2, height + 32);
  
  i.text.position(width / 4, height - 8);
  
  
  j.x.position(width / 2, height + 64);
  j.y.position(width / 2, height + 64 + 16);
  
  j.text.position(width / 4, height + 32 + 8);
  
  matrix = createP();
  matrix.position(width / 16, height / 16);
  
  determinant = createP();
  determinant.position(width / 32, height / 16 * 8);
  
  time = createSlider(0, 1, 0, 1 / animationSmoothness);
  time.position(width / 16, height + 128);
  
  katex.render("\\color{white}{\\begin{bmatrix}\n" + i.x.value().toString() + " & " + j.x.value().toString() + " \\\\\n " + i.y.value().toString() + " & " + j.y.value().toString() + "\n\\end{bmatrix}}", matrix.elt);
  
  katex.render("\\color{white}{\\det\\begin{pmatrix}\n" + i.x.value().toString() + " & " + j.x.value().toString() + " \\\\\n " + i.y.value().toString() + " & " + j.y.value().toString() + "\n\\end{pmatrix}} = " + (i.x.value() * j.y.value() - i.y.value() * j.x.value()).toString(), determinant.elt);
}

function draw() {
  background(0);
  
  const currentI = {
    "x" : animatedLinearTransformation([
      defaultMatrix[0][0],
      defaultMatrix[0][1]
    ], [
      i.x.value(),
      i.y.value()
    ], time.value())[0],
    "y" : animatedLinearTransformation([
      defaultMatrix[0][0],
      defaultMatrix[0][1]
    ], [
      i.x.value(),
      i.y.value()
    ], time.value())[1]
  };
  
  const currentJ = {
    "x" : animatedLinearTransformation([
      defaultMatrix[1][0],
      defaultMatrix[1][1]
    ], [
      j.x.value(),
      j.y.value()
    ], time.value())[0],
    "y" : animatedLinearTransformation([
      defaultMatrix[1][0],
      defaultMatrix[1][1]
    ], [
      j.x.value(),
      j.y.value()
    ], time.value())[1]
  };
  
  const p1 = linearTransformation(
    {
      "x" : currentI.x,
      "y" : currentI.y
    },
    {
      "x" : currentJ.x,
      "y" : currentJ.y
    },
    width / accuracy,
    0
  );

  const p2 = linearTransformation(
    {
      "x" : currentI.x,
      "y" : currentI.y
    },
    {
      "x" : currentJ.x,
      "y" : currentJ.y
    },
    width  / accuracy,
    0 - height / accuracy
  );
  
  const p3 = linearTransformation(
    {
      "x" : currentI.x,
      "y" : currentI.y
    },
    {
      "x" : currentJ.x,
      "y" : currentJ.y
    },
    0,
    0 - height / accuracy
  );
  
  const p4 = linearTransformation(
    {
      "x" : currentI.x,
      "y" : currentI.y
    },
    {
      "x" : currentJ.x,
      "y" : currentJ.y
    },
    0,
    0
  );
  
  fill(gridLineColor.red, gridLineColor.green, gridLineColor.blue);
  strokeWeight(0);
  
  quad(
    toCartesian(
      p1[0],
      p1[1],
      width,
      height
    )[0],
    toCartesian(
      p1[0],
      p1[1],
      width,
      height
    )[1],
    toCartesian(
      p2[0],
      p2[1],
      width,
      height
    )[0],
    toCartesian(
      p2[0],
      p2[1],
      width,
      height
    )[1],
    toCartesian(
      p3[0],
      p3[1],
      width,
      height
    )[0],
    toCartesian(
      p3[0],
      p3[1],
      width,
      height
    )[1],
    toCartesian(
      p4[0],
      p4[1],
      width,
      height
    )[0],
    toCartesian(
      p4[0],
      p4[1],
      width,
      height
    )[1]
  );
  
  strokeWeight(1);
  stroke(gridLineColor.red, gridLineColor.green, gridLineColor.blue);
  
  for (let l = 0 - height; l <= height; l += (height / accuracy)) {
    if (l === 0) {
      strokeWeight(3);
      stroke(255);
    }
    else {
      strokeWeight(1);
      stroke(gridLineColor.red, gridLineColor.green, gridLineColor.blue);
    }
    
    const newVector1 = linearTransformation(
      {
        "x" : currentI.x,
        "y" : currentI.y
      },
      {
        "x" : currentJ.x,
        "y" : currentJ.y
      },
      width,
      l
    );
    
    const newVector2 = linearTransformation(
      {
        "x" : currentI.x,
        "y" : currentI.y
      },
      {
        "x" : currentJ.x,
        "y" : currentJ.y
      },
      0 - width,
      l
    );
    
    line(
      toCartesian(
        newVector1[0],
        newVector1[1],
        width,
        height
      )[0],
      toCartesian(
        newVector1[0],
        newVector1[1],
        width,
        height
      )[1],
      toCartesian(
        newVector2[0],
        newVector2[1],
        width,
        height
      )[0],
      toCartesian(
        newVector2[0],
        newVector2[1],
        width,
        height
      )[1]
    );    
  }
  
  for (let k = 0 - width; k <= width; k += (width / accuracy)) {
    if (k === 0) {
      strokeWeight(3);
      stroke(255);
    }
    else {
      strokeWeight(1);
      stroke(gridLineColor.red, gridLineColor.green, gridLineColor.blue);
    }
    
    const newVector1 = linearTransformation(
      {
        "x" : currentI.x,
        "y" : currentI.y
      },
      {
        "x" : currentJ.x,
        "y" : currentJ.y
      },
      k,
      height
    );
    
    const newVector2 = linearTransformation(
      {
        "x" : currentI.x,
        "y" : currentI.y
      },
      {
        "x" : currentJ.x,
        "y" : currentJ.y
      },
      k,
      0 - height
    );
    
    line(
      toCartesian(
        newVector1[0],
        newVector1[1],
        width,
        height
      )[0],
      toCartesian(
        newVector1[0],
        newVector1[1],
        width,
        height
      )[1],
      toCartesian(
        newVector2[0],
        newVector2[1],
        width,
        height
      )[0],
      toCartesian(
        newVector2[0],
        newVector2[1],
        width,
        height
      )[1]
    );    
  }
  
  
  strokeWeight(2);
  stroke(255);
  
  
  for (let x = 0 - width; x <= width; x += (width / accuracy)) {
    for (let y = 0 - height; y <= height; y += (height / accuracy)) {
      const newVector = linearTransformation(
      {
        "x" : currentI.x,
        "y" : currentI.y
      },
      {
        "x" : currentJ.x,
        "y" : currentJ.y
      },
        x,
        y
      );
      
      point(
        toCartesian(
          newVector[0],
          newVector[1],
          width,
          height
        )[0],
        toCartesian(
          newVector[0],
          newVector[1],
          width,
          height
        )[1]
      );
    }
  }
  
  strokeWeight(8);
  stroke(255);
  
  point(
    toCartesian(0, 0, width, height)[0],
    toCartesian(0, 0, width, height)[1]
  );
  
  time += 1 / animationSmoothness;
  
  katex.render("\\color{white}{\\det\\begin{pmatrix}\n" + i.x.value().toString() + " & " + j.x.value().toString() + " \\\\\n " + i.y.value().toString() + " & " + j.y.value().toString() + "\n\\end{pmatrix}} = " + (i.x.value() * j.y.value() - i.y.value() * j.x.value()).toString(), determinant.elt);  
  
  katex.render("\\color{white}{" + "\\begin{bmatrix}\n" + i.x.value().toString() + " & " + j.x.value().toString() + " \\\\\n " + i.y.value().toString() + " & " + j.y.value().toString() + "\n\\end{bmatrix}}", matrix.elt);
}
1 Like

You are using the variable time as a Slider and as a number:

line 8:

let time = 0;

line 111:

  time = createSlider(0, 1, 0, 1 / animationSmoothness);

line 438:

time += 1 / animationSmoothness;

This converts time into the string "[object Object]" and appends a number to it, after which it will no longer have a .value() function.

3 Likes

Thanks! I already solved this with a “hack” of sorts, but your solution made me realise what went wrong.