(fn)
| 380 | } |
| 381 | |
| 382 | function drawDiagram(fn) { |
| 383 | const SIZE = 300 |
| 384 | const canvas = document.getElementById("merge-canvas") |
| 385 | canvas.height = canvas.width = SIZE |
| 386 | const ctx = canvas.getContext("2d") |
| 387 | |
| 388 | // Draw coordinate system |
| 389 | ctx.scale(1, -1) |
| 390 | ctx.translate(0, -canvas.height) |
| 391 | ctx.lineWidth = 1 |
| 392 | ctx.beginPath() |
| 393 | |
| 394 | ctx.strokeStyle = "white" |
| 395 | ctx.moveTo(0, 0) |
| 396 | ctx.lineTo(0, SIZE) |
| 397 | ctx.lineTo(SIZE, SIZE) |
| 398 | ctx.lineTo(SIZE, 0) |
| 399 | ctx.lineTo(0, 0) |
| 400 | ctx.lineTo(SIZE, SIZE) |
| 401 | ctx.stroke() |
| 402 | ctx.beginPath() |
| 403 | ctx.setLineDash([1, 2]) |
| 404 | const n = SIZE / 10 |
| 405 | for (let i = n; i < SIZE; i += n) { |
| 406 | ctx.moveTo(0, i) |
| 407 | ctx.lineTo(SIZE, i) |
| 408 | ctx.moveTo(i, 0) |
| 409 | ctx.lineTo(i, SIZE) |
| 410 | } |
| 411 | ctx.stroke() |
| 412 | ctx.beginPath() |
| 413 | ctx.setLineDash([]) |
| 414 | ctx.beginPath() |
| 415 | ctx.strokeStyle = "black" |
| 416 | ctx.lineWidth = 3 |
| 417 | // Plot function |
| 418 | const numSamples = 20 |
| 419 | for (let i = 0; i <= numSamples; i++) { |
| 420 | const x = i / numSamples |
| 421 | const y = fn(x) |
| 422 | |
| 423 | const canvasX = x * SIZE |
| 424 | const canvasY = y * SIZE |
| 425 | |
| 426 | if (i === 0) { |
| 427 | ctx.moveTo(canvasX, canvasY) |
| 428 | } else { |
| 429 | ctx.lineTo(canvasX, canvasY) |
| 430 | } |
| 431 | } |
| 432 | ctx.stroke() |
| 433 | // Plot alpha values (yellow boxes) |
| 434 | let start = parseFloat(document.querySelector("#merge-start").value) |
| 435 | let step = parseFloat(document.querySelector("#merge-step").value) |
| 436 | let iterations = document.querySelector("#merge-count").value >> 0 |
| 437 | ctx.beginPath() |
| 438 | ctx.fillStyle = "yellow" |
| 439 | for (let i = 0; i < iterations; i++) { |
no test coverage detected