使用 JavaScript 和 HTML5 画布绘制线性函数



我的代码中可能出了什么问题?我尝试绘制一个线性函数 (y=a*x+b(,键入ab作为输入,每次线穿过点 (0,0( 时,即使我设置b!= 0。
为此,我使用了canvas和JavaScript。还有CSS,但元素的样式在这里并不重要。

谁能指出我的错误?

<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<title>Ploter</title>
<style>
body {
background-color: #303030;
margin-right: auto;
margin-left: auto;
text-align: center;
}
h1,
h2 {
color: #ADADAD;
}
</style>
<script>
var canvas;
var context;
window.onload = function() {
canvas = document.getElementById("plotCanvas");
context = canvas.getContext("2d");
}
function plot() {
var a = document.getElementById("inputA").value;
var b = document.getElementById("inputB").value;
document.getElementById("funEquation").innerHTML = "y=" + a + "x+" + b;
context.clearRect(0, 0, canvas.width, canvas.height);
var x0 = 0.5 * canvas.width;
var y0 = 0.5 * canvas.height;
var scale = 40; //40px per 1 unit
var x;
var y;
var dx = 4;
var xMax = Math.round((canvas.width - x0) / dx);
var xMin = Math.round(-x0 / dx);
var axes = {};
axes.x0 = x0;
axes.y0 = y0;
axes.scale = scale;
drawAxes(context, axes);
context.beginPath();
context.strokeStyle = "white";
context.lineWidth = 2;
for (var i = xMin; i < xMax; i++) {
x = dx * i;
y = (a * x + b) / scale;
if (i == xMin) context.moveTo(x0 + x, y0 - y);
else context.lineTo(x0 + x, y0 - y);
}
context.stroke();
}
function drawAxes(context, axes) {
var x0 = axes.x0;
var y0 = axes.y0;
var width = context.canvas.width;
var height = context.canvas.height;
var xmin = 0;
context.beginPath();
context.strokeStyle = "red";
context.lineWidth = 5;
//----Y axis----
context.moveTo(xmin, y0);
context.lineTo(width, y0);
//----X axis-----
context.moveTo(x0, 0);
context.lineTo(x0, height);
//---X arrow---
context.moveTo(width, height / 2);
context.lineTo(width - 15, (height / 2) + 10);
context.moveTo(width, height / 2);
context.lineTo(width - 15, (height / 2) - 10);
//---Y arrow---
context.moveTo(width / 2, 0);
context.lineTo((width / 2) - 10, 15);
context.moveTo(width / 2, 0);
context.lineTo((width / 2) + 10, 15);
//X - signs
for (var i = x0; i < width; i += 50) {
context.moveTo(i, (height / 2) - 7);
context.lineTo(i, (height / 2) + 7);
}
for (var i = x0; i > 0; i -= 50) {
context.moveTo(i, (height / 2) - 7);
context.lineTo(i, (height / 2) + 7);
}
//Y - signs
for (var i = y0; i < height; i += 50) {
context.moveTo((width / 2) - 7, i);
context.lineTo((width / 2) + 7, i);
}
for (var i = y0; i > 0; i -= 50) {
context.moveTo((width / 2) - 7, i);
context.lineTo((width / 2) + 7, i);
}
context.stroke();
}
</script>
</head>
<body>
<header>
<h1>Ploter XY</h1>
</header>
<main>
<section>
<div id="inputContainer">
<label for="inputA">a:</label>
<input id="inputA" type="text" />
<br />
<label for="inputB">b:</label>
<input id="inputB" type="text" />
<br />
<p>Equation: <span id="funEquation"></span></p>
<input id="confirmButton" type="button" value="Draw" onclick="plot()"></input>
</div>
<div id="plotContainer">
<canvas id="plotCanvas" height="500" width="700" />
</div>
<section>
</main>
</body>
</html>

当您从输入框中获取ab时,它们都以字符串形式出现,您需要将它们转换为Number才能使下面的方程式起作用。

以下行发生错误

y=(a*x+b)/scale;

在这里,如果x = 11, b = 22, x = 1那么由于ab是字符串而不是数学加法,因此执行了字符串连接。 值 y 变为1122/scale

您必须更改以下内容

var a = Number(document.getElementById("inputA").value);
var b = Number(document.getElementById("inputB").value);

或快捷方式

var a = +document.getElementById("inputA").value;
var b = +document.getElementById("inputB").value;

以下代码中还有一个错误

x=dx*i;
y=(a*x+b)/scale;

您必须将比例应用于xy而不仅仅是y。它应该是如下所示

x=dx*i;
y=(a*x+b);
x /= scale;
y /= scale;

此外,比例太大,这会减小小值的图形大小

请在下面找到工作示例

var canvas;
var context;
window.onload = function()
{
	canvas = document.getElementById("plotCanvas");
	context = canvas.getContext("2d");
}
function plot()
{
	var a = Number(document.getElementById("inputA").value);
	var b = Number(document.getElementById("inputB").value);
	document.getElementById("funEquation").innerHTML = "y=" + a +"x+" + b;
	context.clearRect(0,0, canvas.width, canvas.height);
	var x0 = 0.5 * canvas.width;
	var y0 = 0.5 * canvas.height;
	var scale = 1;  //40px per 1 unit
	var x;
	var y;
	var dx = 4;
	var xMax = Math.round((canvas.width-x0)/dx);
	var xMin = Math.round(-x0/dx);
	var axes={};
	axes.x0 = x0;
	axes.y0 = y0;
	axes.scale = scale;
	drawAxes(context,axes);
	context.beginPath();
	context.strokeStyle = "white";
	context.lineWidth = 2;
	for (var i=xMin; i<xMax; i++)
	{
		x=dx*i;
		y=(a*x+b);
		
		x /= scale;
		y /= scale;
		if(i==xMin) {
			context.moveTo(x0+x,y0-y);
		} else {
			context.lineTo(x0+x,y0-y);
		}
	}
	context.stroke();
}
function drawAxes(context, axes)
{
	var x0=axes.x0;
	var y0=axes.y0;
	var width=context.canvas.width;
	var height = context.canvas.height;
	var xmin = 0;
	context.beginPath();
	context.strokeStyle = "red";
	context.lineWidth = 5;
	//----Y axis----
	context.moveTo(xmin,y0);
	context.lineTo(width,y0);
	//----X axis-----
	context.moveTo(x0,0);
	context.lineTo(x0,height);
	//---X arrow---
	context.moveTo(width,height/2);
	context.lineTo(width-15,(height/2)+10);
	context.moveTo(width,height/2);
	context.lineTo(width-15,(height/2)-10);
	//---Y arrow---
	context.moveTo(width/2,0);
	context.lineTo((width/2)-10,15);
	context.moveTo(width/2,0);
	context.lineTo((width/2)+10,15);
	//X - signs
	for(var i=x0; i<width; i+=50)
	{
		context.moveTo(i,(height/2)-7);
		context.lineTo(i,(height/2)+7);
	}
	for(var i=x0; i>0; i-=50)
	{
		context.moveTo(i,(height/2)-7);
		context.lineTo(i,(height/2)+7);
	}
	//Y - signs
	for(var i=y0; i<height; i+=50)
	{
		context.moveTo((width/2)-7,i);
		context.lineTo((width/2)+7,i);
	}
	for(var i=y0; i>0; i-=50)
	{
		context.moveTo((width/2)-7,i);
		context.lineTo((width/2)+7,i);
	}
	context.stroke();
}
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<title>Ploter</title>
<style>
body
{
background-color: #303030;
margin-right: auto;
margin-left: auto;
text-align: center;
}
h1, h2
{
color: #ADADAD;
}   
</style>
<script src="app.js"></script>
</head>
<body>
<header>
<h1>Ploter XY</h1>
</header>
<main>
<section>
<div id="inputContainer">
<label for="inputA">a:</label>
<input id="inputA" type="text" />
<br />
<label for="inputB">b:</label>
<input id="inputB" type="text" />
<br />
<p>Equation: <span id="funEquation"></span></p>
<input id="confirmButton" type="button" value="Draw" onclick="plot()" >
</div>
<div id="plotContainer">
<canvas id="plotCanvas" height="500" width="700" />
</div>
<section>
</main>
</body>
</html>