Cosine Curve

Math
Code
chart = {
  const margin = { top: 20, right: 10, bottom: 20, left: 10 };
  const width = fullWidth - margin.left - margin.right,
        height = fullHeight - margin.top - margin.bottom;

  const window = d3.create("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("viewBox", `0 0 ${fullWidth} ${fullHeight}`)
    .attr("preserveAspectRatio", "xMidYMid meet");

  const svg = window.append("g")
    .attr("class", "cosine")
    .attr("transform", `translate(${margin.left},${margin.top})`);

  const xmin = -1.2,
        xmax = 6.4,
        ymin = -(height / width) * (xmax - xmin) / 2,
        ymax = -ymin;

  const x = d3.scaleLinear().domain([xmin, xmax]).range([0, width]),
        y = d3.scaleLinear().domain([ymin, ymax]).range([height, 0]);

  svg.append("path")
    .attr("class", "axis")
    .attr("d", `M${x(xmin)},${y(0)}H${width},${y(0)}`);

  svg.append("path")
    .attr("class", "axis")
    .attr("d", `M${x(0)},${y(ymin)}V${x(0)},${y(ymax)}`);

  svg.append("circle")
    .attr("class", "axis")
    .attr("cx", x(0))
    .attr("cy", y(0))
    .attr("r", x(1) - x(0));

  let p = 0;
  const dp = 0.01;

  const line = d3.line()
    .x(d => x(d))
    .y(d => y(Math.cos(d - p)))
    .curve(d3.curveBasis);

  const arc = d3.arc()
    .innerRadius(0)
    .outerRadius(x(1) - x(0))
    .startAngle(0);

  svg.append("path")
    .datum({ endAngle: p })
    .attr("class", "wedge")
    .attr("transform", `translate(${x(0)},${y(0)})`)
    .attr("d", arc);

  svg.append("line")
    .attr("class", "line line-0");

  svg.append("path")
    .datum(d3.range(0, xmax, dp * xmax))
    .attr("class", "line line-1")
    .attr("d", line);

  svg.append("line")
    .attr("class", "line line-2")
    .attr("x1", x(0))
    .attr("x2", x(0))
    .attr("y1", y(1))
    .attr("y2", y(1));

  svg.selectAll(".circle")
    .data(d3.range(2))
    .join("circle")
      .attr("class", "circle")
      .attr("cx", x(0))
      .attr("cy", y(1))
      .attr("r", 5);

  function tick() {
    p += dp;
    if (p > 2 * Math.PI - 0.5 * dp){
        p = 0;
    }

    svg.select(".wedge")
      .datum({ endAngle: p })
      .attr("d", arc);

    svg.selectAll(".line-0")
      .attr("x1", x(Math.sin(p)))
      .attr("y1", y(Math.cos(p)))
      .attr("x2", x(0))
      .attr("y2", y(Math.cos(p)));

    svg.select(".line-1")
      .attr("d", line);

    svg.select(".line-2")
      .attr("x2", x(p));

    svg.selectAll(".circle")
      .each(function(d) {
        switch (d) {
          case 0:
            d3.select(this)
              .attr("cx", x(Math.sin(p)))
              .attr("cy", y(Math.cos(p)));
            break;
          case 1:
            d3.select(this)
              .attr("cx", x(p));
            break;
        }
      });
  }

  const timer = d3.interval(tick, 20);

  invalidation.then(() => {
    timer.stop();
  });

  return window.node();
}

This animation demonstrates the relationship of \(\cos(x)\) to the circle.

Resources