我的目标是检测我的功能在哪一侧首先越过A轴X。为此,我首先从所有范围进行检查,然后根据结果在一侧之一中除以二。 我想一圈一画。第一次我有这样的东西:
然后我搜索并尝试了此方法:
window.requestAnimationFrame(drawDicho(a,b));
我认为它将分别绘制每个圆圈。但是,它仅在坐标(0,0)上绘制圆。如果我再次单击,它将再次在其上绘制。
¨
我尝试过window.setInterval(...),但也没有任何反应。
我可以恢复正确的值,但是我想一圈一圈地显示圆圈,而不是同时显示所有圆圈。 有人有主意吗?也许我不知道将代码放置在错误的位置。
@UPDATE完整代码:
<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>
(当我单击“解决f1”按钮时,会使用计算和绘制圆的dichotomie
函数)
谢谢。
答案 0 :(得分:1)
window.requestAnimationFrame
希望将函数引用作为参数,以便可以在浏览器完成渲染后立即调用给定函数,但不要超过60Hz。
这样做:
while (…) {
…
window.requestAnimationFrame(drawDicho(a,b));
…
}
您正在drawDicho(a,b)
循环内立即调用while
,并将返回值分配给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循环则没有。
答案 1 :(得分:1)
我以以下方式更新您的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>