Skip to content

Instantly share code, notes, and snippets.

@flying19880517
Last active September 19, 2016 10:25
Show Gist options
  • Save flying19880517/6186ceae32e93874bb2b8d445cd9bb98 to your computer and use it in GitHub Desktop.
Save flying19880517/6186ceae32e93874bb2b8d445cd9bb98 to your computer and use it in GitHub Desktop.
来源: http://yujianrong.bitbucket.org/JsTool/Plot/plot.html 说明:虽然使用了动态细分的办法,但效果还是不够理想,不知道应该用什么办法才能做得比较好。 尝试第一个的话要写成 sin(pow(E,x+y)) = pow(E,sin(x)+cos(y)) 可以用以下Javascript数学库的函数/常数: E LN2 LN10 LOG2E LOG10E PI SQRT1_2 SQRT2 abs acos asin atan atan2 ceil cos exp floor log max min pow round sin sqrt tan 注意 a^b 要写成 pow(a,b) 这种形式,要不然会被当作异或操作
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
var Config={
Width :400,
Height:400,
Range:{X:{Min:-10, Max:10}, Y:{Min:-10, Max:10}},
MaxSplit:10
};
function $(id)
{
return document.getElementById(id);
}
function ApplySetting()
{
Config.Width= parseInt(CanvasWidth.value );
Config.Height= parseInt(CanvasHeight.value );
Config.Range.X.Min= parseFloat(XMin.value ,10);
Config.Range.Y.Min= parseFloat(YMin.value ,10);
Config.Range.X.Max= parseFloat(XMax.value ,10);
Config.Range.Y.Max= parseFloat(YMax.value ,10);
MainCanvas.width = Config.Width;
MainCanvas.height= Config.Height;
MainData=[];
for (var y=0;y<Config.Height+1;++y)
{
MainData.push([]);
}
MainData[-1]=[];
}
function Plot()
{
Config.MaxSplit = parseInt( MaxSplit.value, 10);
// reset the DataArray
for (var y=0;y<Config.Height;++y)
{
for(var x=0;x<Config.Width;++x)
{
MainData[y][x] = false;
}
}
var FunctonStr = InputFunction.value;
// FunctonStr = FunctonStr.toLowerCase();
FunctonStr = FunctonStr.replace( (/E|LN2|LN10|LOG2E|LOG10E|PI|SQRT1_2|SQRT2|abs|acos|asin|atan|atan2|ceil|cos|exp|floor|log|max|min|pow|round|sin|sqrt|tan/g),function(x){return "Math."+x;})
var Delta={X:(Config.Range.X.Max - Config.Range.X.Min)/Config.Width,
Y:(Config.Range.Y.Max - Config.Range.Y.Min)/Config.Height};
if (FunctonStr.indexOf("=") !== -1)
{
var matchs = FunctonStr.match(/(.*?)={1,}(.*)/);
FunctonStr ="("+ matchs[1] + ")-(" + matchs[2]+")";
eval("var func_equ=function(x,y, dx, dy){ var oldx=x;var t1 = "+FunctonStr+
"; x+=dx; t2 = " + FunctonStr+
"; y+=dy; t3 = " + FunctonStr+
"; x=oldx; t4 = " + FunctonStr+
"; return t1*t2<=0 || t1*t3<=0 || t1*t4<=0 ;};");
} else
{
eval("var func_equ=function(x,y){ return "+ FunctonStr + "; };");
}
var Y = Config.Range.Y.Max;
var y=0;
var lasty =0;
var max_y =0;
var split = 1;
var DX = Delta.X/split, DY = Delta.Y/split;
var pass = 1;
intervalID = setInterval(function(){
if (y<Config.Height)
{
var X = Config.Range.X.Min;
var lineModified = false;
for (var x=0; x<Config.Width; ++x, X+=Delta.X)
{
if (MainData[y][x])
continue;
if (y <= max_y
&& !MainData[y][x+1]
&& !MainData[y][x-1]
&& !MainData[y+1][x+1]
&& !MainData[y+1][x]
&& !MainData[y+1][x-1]
&& !MainData[y-1][x+1]
&& !MainData[y-1][x]
&& !MainData[y-1][x-1]
) continue;
Y2 = Y;
CellLoop:
for (var idx=0;idx<split;idx++, Y2+=DY)
{
X2 = X;
for (var idy=0;idy<split;idy++, X2+=DX)
{
if (func_equ(X2, Y2, DX, DY))
{
MainCtx.fillRect(x,y,1,1);
MainData[y][x] = true;
lineModified = true;
break CellLoop;
}
}
}
}
if (y>max_y) max_y = y;
if (!lineModified)
{
lasty = y;
Y -= Delta.Y;
y++;
if (y>max_y)
{
split=Math.floor(split/2);
// split--;
if (split<1) split=1;
}
} else
{
if (lasty < y)
{
split*=2;
// split++;
if (split>Config.MaxSplit) split = Config.MaxSplit;
}
lasty = y;
if (y!== 0)
{
y--;
Y+=Delta.Y
}
}
DX = Delta.X/split, DY = Delta.Y/split;
} else
{
Stop();
}
}, 0);
BtnSet.disabled = true;
BtnPlot.disabled = true;
BtnStop.style.display="inline";
}
function Stop()
{
clearInterval(intervalID);
BtnSet.disabled = false;
BtnPlot.disabled = false;
BtnStop.style.display="none";
}
function init()
{
MainCanvas = $("Main")
MainCtx = MainCanvas.getContext("2d");
CanvasWidth = $("CanvasWidth");
CanvasHeight = $("CanvasHeight");
XMin = $("XMin");
XMax = $("XMax");
YMin = $("YMin");
YMax = $("YMax");
MaxSplit = $("MaxSplit");
InputFunction = $("InputFunction");
BtnSet = $("BtnSet");
BtnPlot = $("BtnPlot");
BtnStop = $("BtnStop");
CanvasWidth.value = Config.Width;
CanvasHeight.value = Config.Height;
XMin.value = Config.Range.X.Min;
YMin.value = Config.Range.Y.Min;
XMax.value = Config.Range.X.Max;
YMax.value = Config.Range.Y.Max;
MaxSplit.value = Config.MaxSplit;
BtnSet.addEventListener("click", ApplySetting ,false);
BtnPlot.addEventListener("click", Plot ,false);
BtnStop.addEventListener("click", Stop ,false);
ApplySetting();
}
window.onload=init;
</script>
<title> Math Plot </title>
</head>
<body>
<canvas id="Main" style="border-width: 1px; border-color: black; border-style: solid;"></canvas><br/>
<!-- <span id="Info" style="color:#00a"></span><br/> -->
Canvas Width:<input type="TEXT" style="width:100px" id="CanvasWidth"></input>
Canvas Height:<input type="TEXT" style="width:100px" id="CanvasHeight"></input> <br/>
X: <input type="TEXT" style="width:60px" id="XMin"></input> to <input type="TEXT" style="width:60px" id="XMax"></input>
Y: <input type="TEXT" style="width:60px" id="YMin"></input> to <input type="TEXT" style="width:60px" id="YMax"></input>
<input type="BUTTON" value="Set & Clear" id="BtnSet"></input></br/>
Input:<input type="TEXT" style="width:500px" id="InputFunction"></input></br>
Max Split: <input type="TEXT" style="width:40px" id="MaxSplit"></input> <input type="BUTTON" value="Plot" id="BtnPlot"></input>
<input type="BUTTON" value="Stop" id="BtnStop" style="display:none"></input></br/>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment