Derivada e tangente

A reta tangente a uma função, num ponto, pode ser calculada, de forma aproximada, a partir da reta que passa em (x,f(x)) e (x2,f(x2)), onde x2=x+dx, sendo dx um valor muito pequeno.

No exemplo abaixo, o utilizador pode inserir a expressão da função (com sintaxe de Javascript), assim como os valores de x e dx.

O declive da reta tangente é calculado como m=(f(x2)-f(x))/(x2-x), e a ordenada da origem é obtida pela expressão b=f(x)-m*x.

O gráfico é configurável: é possível alterar a escala de x (xEscala), a escala de y (yEscala), a frequência de traços em cada eixo (xMarcas e yMarcas), assim como a posição da origem do referencial (xr e yr).

Visualização:

Código html

<!DOCTYPE html>
<html>
<head>
<title>Gráfico - reta tangente</title>
<meta charset="iso-8859-1">
<script 
  src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>


<script type="text/javascript" src="codigo.js"></script>
<script type="text/javascript" src="Grafico.js"></script>
<link type="text/css" href="estilos.css" rel="stylesheet" />
</head>
<body onload="init();">
<h3>Gráfico - reta tangente</h3>
<canvas width="400" height="300" id="cvs"></canvas>
<form>
  <div>
    xEscala
    <meter id="xEsc" min="1" max="100" value=""></meter>
    <input type="text" id="vxEsc" size="3" value="" onblur="cInput('xEsc');" />
  </div>
  <div>
    yEscala
    <meter id="yEsc" min="1" max="100" value=""></meter>
    <input type="text" id="vyEsc" size="3" value="" onblur="cInput('yEsc');" />
  </div>
  <div>
    xMarcas
    <meter id="xMrc" min="1" max="50" value=""></meter>
    <input type="text" id="vxMrc" size="3" value="" onblur="cInput('xMrc');" />
  </div>
  <div>
    yMarcas
    <meter id="yMrc" min="1" max="50" value=""></meter>
    <input type="text" id="vyMrc" size="3" value="" onblur="cInput('yMrc');" />
  </div>
  <div>
    xr
    <meter id="xRef" min="0" max="400" value=""></meter>
    <input type="text" id="vxRef" size="3" value="" onblur="cInput('xRef');" />
  </div>
  <div>
    yr
    <meter id="yRef" min="0" max="300" value=""></meter>
    <input type="text" id="vyRef" size="3" value="" onblur="cInput('yRef');" />
  </div>
  <div>
    Função:
    <input type="text" id="func" size="30" value="4*Math.log(x)" />
  </div>
  <div>
    x:
    <input type="text" id="xtan" size="10" value="5" />
  </div>
  <div>
    dx:
    <input type="text" id="xdelta" size="10" value="0.2" />
  </div>
  <input type="button" value="Redesenha" onclick="redesenha();" />
</form>
</body>
</html>

Ficheiro codigo.js

var g;

function init() {
	g = new Grafico();
	g.inicia();

	document.getElementById("xEsc").value = g.xEscala;
	document.getElementById("vxEsc").value = g.xEscala;
	document.getElementById("yEsc").value = g.yEscala;
	document.getElementById("vyEsc").value = g.yEscala;

	document.getElementById("xMrc").value = g.xMarcas;
	document.getElementById("vxMrc").value = g.xMarcas;
	document.getElementById("yMrc").value = g.yMarcas;
	document.getElementById("vyMrc").value = g.yMarcas;

	document.getElementById("xRef").value = g.xr;
	document.getElementById("vxRef").value = g.xr;
	document.getElementById("yRef").value = g.yr;
	document.getElementById("vyRef").value = g.yr;

	$("#xEsc").click(cMeter);
	$("#yEsc").click(cMeter);
	$("#xMrc").click(cMeter);
	$("#yMrc").click(cMeter);
	$("#xRef").click(cMeter);
	$("#yRef").click(cMeter);
}

function redesenha() {
	g.xEscala = eval(document.getElementById("vxEsc").value);
	g.yEscala = eval(document.getElementById("vyEsc").value);
	g.xMarcas = eval(document.getElementById("vxMrc").value);
	g.yMarcas = eval(document.getElementById("vyMrc").value);
	g.xr = eval(document.getElementById("vxRef").value);
	g.yr = eval(document.getElementById("vyRef").value);
	g.inicia();
}

function cMeter(e) {
	var id = $(this).attr("id");
	var met = document.getElementById(id);
	var max = met.getAttribute("max");
	var min = met.getAttribute("min");

	var offx = e.clientX - met.getBoundingClientRect().left;
	opac = offx / $('#'+id).width();
	var pct = Math.round((max-min) * opac);
	$('#'+id).val(pct);
	$('#v'+id).val(pct);
}

function cInput(id) {
	var valor = $('#v'+id).val();
	$('#'+id).val(valor);
}

Ficheiro Grafico.js


/* 
Classe Grafico

*/

function Grafico() {

	// Coordenadas da origem do referencial visível
	this.xr = 50;
	this.yr = 260;
	// Escalas dos eixos
	this.xEscala = 15;
	this.yEscala = 15;
	// Espaçamento entre marcas
	this.xMarcas = 5;
	this.yMarcas = 2;

	var canvas = document.getElementById("cvs");
	var larg = canvas.getAttribute("width");
	var alt = canvas.getAttribute("height");
	var ctx = canvas.getContext("2d");

	// Criar imagens de 1x1 pixels
	var ptPreto = ctx.createImageData(1,1);
	ptPreto.data[0] = 0;	// Componente vermelha
	ptPreto.data[1] = 0;	// Componente verde
	ptPreto.data[2] = 0;	// Componente azul
	ptPreto.data[3] = 255;	// Componente alfa
	var ptVermelho = ctx.createImageData(1,1);
	ptVermelho.data[0] = 255;// Componente vermelha
	ptVermelho.data[1] = 0;	// Componente verde
	ptVermelho.data[2] = 0;	// Componente azul
	ptVermelho.data[3] = 255;	// Componente alfa
	var ptVerde = ctx.createImageData(1,1);
	ptVerde.data[0] = 0;	// Componente vermelha
	ptVerde.data[1] = 128;	// Componente verde
	ptVerde.data[2] = 0;	// Componente azul
	ptVerde.data[3] = 255;	// Componente alfa
	var ptAzul = ctx.createImageData(1,1);
	ptAzul.data[0] = 0;	// Componente vermelha
	ptAzul.data[1] = 0;	// Componente verde
	ptAzul.data[2] = 255;	// Componente azul
	ptAzul.data[3] = 255;	// Componente alfa

	this.inicia = inicia;
	function inicia() {
		ctx.fillStyle = "white";
		ctx.beginPath();
		ctx.rect(0,0,larg,alt);
		ctx.fill();

		ctx.fillStyle = "white";
		ctx.beginPath();
		ctx.rect(0,0,larg,alt);
		ctx.fill();

		ctx.strokeStyle = "black";
		ctx.beginPath();
		ctx.rect(0,0,larg,alt);
		ctx.stroke();

		// Colocar os dois eixos xx, yy
		poeLinha(0,this.yr,larg,this.yr,"black");
		poeLinha(this.xr,0,this.xr,alt,"black");

		// Preparação para escrever o texto na horizontal
		ctx.fillStyle = "black";
		ctx.font = "12px 'Courier'";
		ctx.textAlign = "center";
		ctx.textBaseline = "top";
		// Colocar a escala nos eixos
		// Eixo x positivo
		for(var n=0; n*this.xEscala+this.xr<larg; n+=this.xMarcas) {
			poeLinha(n*this.xEscala+this.xr,this.yr-5,n*this.xEscala+this.xr,this.yr+5,"black");
			ctx.fillText(n, n*this.xEscala+this.xr, this.yr+10);
		}
		// Eixo x negativo
		for(var n=0; n*this.xEscala+this.xr>0; n-=this.xMarcas) {
			poeLinha(n*this.xEscala+this.xr,this.yr-5,n*this.xEscala+this.xr,this.yr+5,"black");
			ctx.fillText(n, n*this.xEscala+this.xr, this.yr+10);
		}
		// Preparação para escrever o texto na horizontal
		ctx.textAlign = "right";
		ctx.textBaseline = "middle";
		// Eixo y negativo
		for(var n=0; n*this.yEscala+this.yr<alt; n+=this.yMarcas) {
			poeLinha(this.xr-5,n*this.yEscala+this.yr,this.xr+5,n*this.yEscala+this.yr,"black");
			ctx.fillText(-n, this.xr-10, n*this.yEscala+this.yr);
		}
		// Eixo y positivo
		for(var n=0; n*this.yEscala+this.yr>0; n-=this.yMarcas) {
			poeLinha(this.xr-5,n*this.yEscala+this.yr,this.xr+5,n*this.yEscala+this.yr,"black");
			ctx.fillText(-n, this.xr-10, n*this.yEscala+this.yr);
		}

		// Desenhar a função
		var y;
		for(var i=0; i<larg; i++) {
			x = i/this.xEscala;
			y = f(x);
			if(!isFinite(y)) continue;
			this.poePonto(ptPreto, x, y);
		}

		// Calcular o declive
		var xt = eval( document.getElementById("xtan").value );
		var dx = eval( document.getElementById("xdelta").value );
		if(xt==undefined || dx==undefined) return;
		yt = f(xt);
		yt2 = f(xt+dx);
		var m = (yt2-yt)/dx;
		// Calcular ordenada na origem
		var b = yt - m * xt;

		// Desenhar tangente
		for(var i=0; i<larg; i++) {
			x = i/this.xEscala;
			y = m * x + b;
			if(!isFinite(y)) continue;
			this.poePonto(ptPreto, x, y);
		}

		
	}

	function f(x) {
		var ff = document.getElementById("func").value;
		if(ff=="") return 0;

		var y = eval(ff);
		return y;
	}


	this.poePonto = poePonto;
	function poePonto(pt, x, y) {
		var xe = x * this.xEscala + this.xr;
		var ye = -y * this.yEscala + this.yr;
		ctx.putImageData(pt, xe, ye);
	}

	this.poeLinha = poeLinha;
	function poeLinha(x1,y1,x2,y2,cor) {
		ctx.strokeStyle = cor;
		ctx.beginPath();
		ctx.moveTo(x1,y1);
		ctx.lineTo(x2,y2);
		ctx.stroke();
	}
}

Ficheiro estilos.css

meter {
	width: 200px;
}

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *