##### Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

# 在Windows Phone和Windows 8上绘制数学函数图形

WS_YiLunLuo 在 12 Jul 2012 创建

## 实现

<canvas id="mainCanvas"/>

canvas不会自动根据环境改变大小。当然，你可以使用绝对坐标，但是如果你想让不同大小的屏幕都能正常显示你的图形，就还是需要使用相对坐标。下面的代码定义了一些和大小相关的变量，并且处理window.onresize事件，从而能够针对不同大小的屏幕绘制不同大小的图画。

var mainCanvas = null;
var width = 0;
var height = 0;

app.onactivated = function (args) {
// Automatically generated code omitted.
mainCanvas = document.getElementById("mainCanvas");
onresize();
};

function onresize() {
width = document.body.clientWidth;
mainCanvas.width = width;
height = document.body.clientHeight;
mainCanvas.height = height;
ondraw();
}

function ondraw() {
var context = mainCanvas.getContext("2d");
context.strokeStyle = "white";
context.fillStyle = "white";
context.beginPath();
var halfWidth = width / 2;
var halfHeight = height / 2;

// x axis
context.moveTo(10, halfHeight);
context.lineTo(width - 10, halfHeight);
context.lineTo(width - 20, halfHeight - 10);
context.moveTo(width - 10, halfHeight);
context.lineTo(width - 20, halfHeight + 10);
context.font = "30px Arial";
context.textAlign = "left";
context.textBaseline = "top";
context.fillText("x", width - 20, halfHeight + 10);

// y axis
context.moveTo(halfWidth, 10);
context.lineTo(halfWidth, height - 10);
context.moveTo(halfWidth - 10, 20);
context.lineTo(halfWidth, 10);
context.lineTo(halfWidth + 10, 20);
context.fillText("y", halfWidth - 20, 10);
context.stroke();

// more code to be added...
}

function drawFunc(func, context, min, max) {

// Type check omitted...
if (min >= max) {
throw "min must be less than max.";
}
var interval = max - min;
var halfWidth = width / 2;
var halfHeight = height / 2;
var oldY = null;
for (var i = -halfWidth; i < halfWidth; i++) {

// i is the screen coordinate.
// Translate x to math coordinate.
var x = i * interval / width;

// Translate y to screen coordinate.
// y is negative because the math coordinate is reflected from screen coordinate.
// + halfHeight so that 0 starts at the center.
var y = -func(x) / interval * width + halfHeight;
if (oldY === null) {
oldY = y;
context.moveTo(i + halfWidth, y);
}
else {
context.lineTo(i + halfWidth, y);
oldY = y;
}
}
}

func可以是任何能用代码表示的函数，例如下面的代码代表一次函数，二次函数，三次函数。当然，这个函数并不一定要能用数学公式表示。你也完全可以写一个函数，传入一个国家的边界线的纬度，返回经度，或者传入某一时刻，返回某地的天气或者某个股票的价格，等等。

function line(x) {
return x;
}

function square(x) {
return Math.pow(x, 2);
}

function cube(x) {
return Math.pow(x, 3);
}

context.beginPath();
context.strokeStyle = "blue";

// y = x
drawFunc(line, context, -10, 10);
context.stroke();
context.beginPath();
context.strokeStyle = "red";

// y = x ^ 2
drawFunc(square, context, -10, 10);
context.stroke();

derivative = lim(dx->0) dy/dx

function drawDerivative(func, context, min, max) {

// Type check omitted...
if (min >= max) {
throw "min must be less than max.";
}
var interval = max - min;
var halfWidth = width / 2;
var halfHeight = height / 2;
var oldX = null;
var oldY = null;
var oldTangent = null;
for (var i = -halfWidth; i < halfWidth; i++) {

// i is the screen coordinate.
// Translate x to math coordinate.
var x = i * interval / width;
var y = func(x);
if (oldX === null) {
oldX = x;
oldY = y;
}
else {
var dy = y - oldY;
var dx = x - oldX;
oldX = x;
oldY = y;

// tangent is negative because the math coordinate is different from screen coordinate.
var tangent = -dy / dx / interval * width + halfHeight;
if (oldTangent === null) {
oldTangent = tangent;
context.moveTo(i + halfWidth, tangent);
}
else {
context.lineTo(i + halfWidth, tangent);
oldTangent = tangent;
}
}
}
}

context.beginPath();
context.strokeStyle = "green";

// The derivative of y = x ^ 2 is y = 2x
drawDerivative(square, context, -10, 10);
context.stroke();

// Legend
context.fillStyle = "red";
context.fillText("y = x ^ 2", 10, 10);
context.fillStyle = "blue";
context.fillText("y = x", 10, 40);
context.fillStyle = "green";
context.fillText("The derivative of y = x ^ 2 is y = 2x", 10, 70);