0

I started today learning HTML5/Javascript/Canvas so please be easy on me.

I wanted to plot a sin(x) over the range x=-Pi..Pi. Therefore, the logical coordinates will extend from x=-Pi..Pi and from y=-1..1. I do not want to use a plotting library or any external functions. I want to learn how to do this all in javascript and HTML5 myself.

The canvas size is width=200 and height=100 in pixels.

After lots of reading and googling, I learned I need to use translate and scale to be able to work in the logical coordinates, not the physical (pixels) based coordinates.

Finally I get the correct plot, but the line is too thick. It looks like line thickness is not affect by scaling? How can I make the line thickness much less than shown below?

The plot I want to generate in javascript is this (from Matematica)

Mathematica graphics

The one I get now in HTML is this

Mathematica graphics

Could someone look at the code and suggest what is needed to fix the line thickness issue? Am I doing the scaling correctly?

The shape seems correct, it is that the line is too thick. Here is the complete code I just wrote

function draw() {
  var canvas = document.getElementById('canvas');
  var W = canvas.width;
  var H = canvas.height;
  var ctx = canvas.getContext('2d');
  ctx.lineWidth = 1; // attempt to make line less thick, but no effect

  ctx.rect(0, 0, W, H); // draw frame around the physical canvas
  ctx.stroke();
  ctx.save();

  ctx.translate(W / 2, H / 2); //put coordinates system origin in middle
  ctx.scale(W / (2 * Math.PI), -H / 2); //Is this correct?
  // want logical width to be 2 PI and logical height 2.
  // the minus sign due to flipping of y axis.

  var lowEnd = -Math.PI; // x range is -Pi..Pi
  var highEnd = Math.PI;
  var xValues = [];
  var yValues = [];

  while (lowEnd <= highEnd) //generate x,y points
  {
    xValues.push(lowEnd);
    yValues.push(Math.sin(lowEnd));
    lowEnd += (Math.PI) / 10; // arbitray sampling interval
  }
  // start drawing the points generated above
  ctx.beginPath();
  ctx.moveTo(xValues[0], yValues[0]); //move to starting point of curve.

  for (var i = 1; i < xValues.length; i++) {
    //console.log(xValues[i],yValues[i]);
    ctx.lineTo(xValues[i], yValues[i]);
    ctx.stroke();
  }
  ctx.restore();
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
</head>
<body onload="draw();">
  <canvas id="canvas" width="200" height="100"></canvas>
</body>
</html>
SAMUEL
  • 8,098
  • 3
  • 42
  • 42
Nasser
  • 12,849
  • 6
  • 52
  • 104
  • lineWidth increasing because you are scaling the canvas `ctx.scale(W / (2 * Math.PI), -H / 2);` If you still want to decrease the width set lineWidth again `ctx.lineWidth = W / (2 * Math.PI)` – Durga Feb 21 '18 at 07:21
  • @Durga Thanks. But it should be `ctx.lineWidth = (2 * Math.PI)/W;` I did not think I needed to do this, as I read that 1 pixel is the smallest possible size of line width. But you are right., I needed to scale the width again. Now it works ok. – Nasser Feb 21 '18 at 07:27

0 Answers0