我的目标是检测我的函数在哪里首先穿过负边的X轴。为此,我首先检查所有范围,然后根据结果除以其中一条边的两个。我想把我所有的圆圈一一画出来。我第一次得到这样的东西:
然后我搜索并尝试了这个:
window.requestAnimationFrame(drawDicho(a,b));
我想它会单独画出每个圆圈。但是,它只在坐标(0,0)上绘制圆。如果我再次单击,它会再次在上面绘制。
¨
我试过window.setInterval(...)但也什么也没发生。
我可以恢复正确的值,但我想逐个显示圆圈,而不是同时显示所有圆圈。有谁有主意吗?也许我把代码放错了地方,我不知道..
@更新完整代码:
<script type="text/javascript">
window.onload = function(){
var canvas = $('myCanvas');
if(!canvas){
alert("Impossible to recover canvas");
return;
}
var context = canvas.getContext('2d');
if(!context){
alert("Impossible dto recover canvas context");
return;
}
context.fillStyle = 'rgba(255, 255, 255, 1)';
context.fillRect(0, 0, 500, 500);
context.strokeStyle = 'rgba(0, 0, 0, 1)';
var width = canvas.width;
var height = canvas.height;
//draw axis Y
context.beginPath();
context.moveTo(width/2, 0);
context.lineTo(width/2, height);
context.closePath();
context.stroke();
//draw axis X
context.beginPath();
context.moveTo(0, height/2);
context.lineTo(width, height/2);
context.closePath();
context.stroke();
}
function function1(x){
return Math.sin(x)-(x/13);
}
function function2(x){
return x/(1-Math.pow(x, 2));
}
function draw(func){
var canvas = $('myCanvas');
var context = canvas.getContext('2d');
var dx = canvas.width;
var dy = canvas.height;
var scale = dx/40; // echelle (nb pixels between x=0 et x=1)
var x0 = dx/2;
var y0 = dy/2;
var iMax = 20;
var x, y;
var iMin = -20;
context.translate(x0,y0);
context.scale(1, -1);
context.strokeStyle = 'rgba(255, 0, 0, 1)';
context.beginPath();
context.arc(-100, 0, 5, 0, 2*Math.PI, false);
context.arc(100, 0, 5, 0, 2*Math.PI, false);
for(i = -100; i<=100; i=i+0.01){
x=i*4;
y = scale * func(x/scale);
context.lineTo(x, y);
}
context.closePath();
context.stroke();
}
function drawF1(){
draw(function1);
}
function drawF2(){
draw(function2);
}
function drawDicho(a, b){
var canvas = $('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.arc(a, 0, 5, 0, 2*Math.PI, false);
context.arc(b, 0, 5, 0, 2*Math.PI, false);
context.closePath();
context.stroke();
}
function dichotomie(func){
var a = -100;
var b = 100;
var fa = func(a);
var fb = func(b);
var delta = 0.01;
while(Math.abs(b-a) > delta){
//drawDicho(a,b);
var m = (a+b)/2;
var fm = func(m);
if(fm * fa <= 0){
b = m;
fb = fm;
}
else{
a = m;
fa = fm;
}
window.requestAnimationFrame(drawDicho(a,b));
}
if(fa * fb <= 0){
return m.toFixed(3);
}
else{
return 'no 0';
}
}
function $(id){
return document.getElementById(id);
}
function solvef1()
{
var result = dichotomie(function1);
alert(result);
}
function solvef2(){
var result = dichotomie(function2);
alert(result);
}
</script>
</head>
<body style="background-color:grey">
<p>
<label>draw fonction: </label>
<input type="button" name="function1" value="fonction 1" id="drawF1" onclick="drawF1()">
<input type="button" name="function2" value="fonction 2" id="drawF2" onclick="drawF2()">
<input type="button" name="solvef1" value="solvef1" id="solvef1" onclick="solvef1()">
<input type="button" name="solvef2" value="solvef2" id="solvef2" onclick="solvef2()">
</p>
<br>
<canvas id="myCanvas" width="500" height="500">
Message bla bla bla
</canvas>
</body>
(当我点击"solve f1“按钮时,会使用计算和绘制圆圈的dichotomie
函数)
谢谢。
发布于 2019-03-14 21:31:01
我用下面的方法更新你的dichotomie
( 300
是画圆圈之间的毫秒数)(在“全页”上运行代码段)
function dichotomie(func){
...
var circs=[];
while(Math.abs(b-a) > delta){
...
circs.push([a,b])
}
circs.map((x,i) => setTimeout(y=> drawDicho(...x),i*300) );
...
}
在此解决方案中,我们使用arrow functions和array map
<script type="text/javascript">
window.onload = function(){
var canvas = $('myCanvas');
if(!canvas){
alert("Impossible to recover canvas");
return;
}
var context = canvas.getContext('2d');
if(!context){
alert("Impossible dto recover canvas context");
return;
}
context.fillStyle = 'rgba(255, 255, 255, 1)';
context.fillRect(0, 0, 500, 500);
context.strokeStyle = 'rgba(0, 0, 0, 1)';
var width = canvas.width;
var height = canvas.height;
//draw axis Y
context.beginPath();
context.moveTo(width/2, 0);
context.lineTo(width/2, height);
context.closePath();
context.stroke();
//draw axis X
context.beginPath();
context.moveTo(0, height/2);
context.lineTo(width, height/2);
context.closePath();
context.stroke();
}
function function1(x){
return Math.sin(x)-(x/13);
}
function function2(x){
return x/(1-Math.pow(x, 2));
}
function draw(func){
var canvas = $('myCanvas');
var context = canvas.getContext('2d');
var dx = canvas.width;
var dy = canvas.height;
var scale = dx/40; // echelle (nb pixels between x=0 et x=1)
var x0 = dx/2;
var y0 = dy/2;
var iMax = 20;
var x, y;
var iMin = -20;
context.translate(x0,y0);
context.scale(1, -1);
context.strokeStyle = 'rgba(255, 0, 0, 1)';
context.beginPath();
context.arc(-100, 0, 5, 0, 2*Math.PI, false);
context.arc(100, 0, 5, 0, 2*Math.PI, false);
for(i = -100; i<=100; i=i+0.01){
x=i*4;
y = scale * func(x/scale);
context.lineTo(x, y);
}
context.closePath();
context.stroke();
}
function drawF1(){
draw(function1);
}
function drawF2(){
draw(function2);
}
function drawDicho(a, b){
var canvas = $('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.arc(a, 0, 5, 0, 2*Math.PI, false);
context.arc(b, 0, 5, 0, 2*Math.PI, false);
context.closePath();
context.stroke();
}
function dichotomie(func){
var a = -100;
var b = 100;
var fa = func(a);
var fb = func(b);
var delta = 0.01;
var circs=[];
while(Math.abs(b-a) > delta){
//drawDicho(a,b);
var m = (a+b)/2;
var fm = func(m);
if(fm * fa <= 0){
b = m;
fb = fm;
}
else{
a = m;
fa = fm;
}
circs.push([a,b])
}
console.log(circs);
circs.map((x,i) => setTimeout(y=> drawDicho(...x),i*300) );
if(fa * fb <= 0){
return m.toFixed(3);
}
else{
return 'no 0';
}
}
function $(id){
return document.getElementById(id);
}
function solvef1()
{
var result = dichotomie(function1);
alert(result);
}
function solvef2(){
var result = dichotomie(function2);
alert(result);
}
</script>
</head>
<body style="background-color:grey">
<p>
<label>draw fonction: </label>
<input type="button" name="function1" value="fonction 1" id="drawF1" onclick="drawF1()">
<input type="button" name="function2" value="fonction 2" id="drawF2" onclick="drawF2()">
<input type="button" name="solvef1" value="solvef1" id="solvef1" onclick="solvef1()">
<input type="button" name="solvef2" value="solvef2" id="solvef2" onclick="solvef2()">
</p>
<br>
<canvas id="myCanvas" width="500" height="500">
Message bla bla bla
</canvas>
</body>
发布于 2019-03-14 20:55:54
window.requestAnimationFrame
需要一个函数引用作为参数,这样一旦浏览器完成渲染,就可以调用给定的函数,但速度不会超过60 the。
通过执行以下操作:
while (…) {
…
window.requestAnimationFrame(drawDicho(a,b));
…
}
您将立即在while
循环中调用drawDicho(a,b)
,并将返回值分配给未定义的requestAnimationFrame
。
你需要的,至少我认为你需要的,是一个这样的动画循环:
const DELAY = 1000;
let
last = new Date().getTime(),
circles = [
[10,10],
[100, 100],
[10, 100]
]
;
//replace while () {} with the loop below,
//this way the execution is scheduled
(function loop () {
const
now = new Date().getTime(),
delta = now - last;
if (delta >= DELAY && circles.length > 0) {
drawCircle(...circles.shift());
last = now;
}
window.requestAnimationFrame(loop);
})();
这样,loop
将被频繁调用。while循环不是动画循环,代码会立即被调用。动画循环以一定的»帧速率运行,而while循环不是这样。
https://stackoverflow.com/questions/55162245
复制相似问题