Skip to content

Commit 00a9bd8

Browse files
authored
more precision
1 parent d6c1f4f commit 00a9bd8

1 file changed

Lines changed: 42 additions & 29 deletions

File tree

index.html

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ <h2>📝 Editor</h2>
298298
ctx.fillRect(0, 0, W, H);
299299
const [xMin, yMax] = toMath(0, 0);
300300
const [xMax, yMin] = toMath(W, H);
301-
302301
let gridStep;
303302
const targetPixels = 60;
304303
const rawStep = targetPixels / scale;
@@ -318,8 +317,6 @@ <h2>📝 Editor</h2>
318317
ctx.moveTo(px, 0);
319318
ctx.lineTo(px, H);
320319
}
321-
ctx.stroke();
322-
ctx.beginPath();
323320
const startY = Math.ceil(yMin / gridStep) * gridStep;
324321
for (let y = startY; y <= yMax; y += gridStep) {
325322
const py = H / 2 - (y - cy) * scale;
@@ -330,7 +327,6 @@ <h2>📝 Editor</h2>
330327
ctx.stroke();
331328
const labelStep = gridStep * (scale > 200 ? 1 : scale > 80 ? 2 : 4);
332329
ctx.fillStyle = '#777';
333-
ctx.font = '11px Consolas';
334330
ctx.textAlign = 'center';
335331
const [, axisY_px] = toScreen(0, 0);
336332
for (let x = Math.ceil(xMin / labelStep) * labelStep; x <= xMax; x += labelStep) {
@@ -354,52 +350,69 @@ <h2>📝 Editor</h2>
354350
ctx.beginPath();
355351
if (axisY_px >= 0 && axisY_px <= H) {
356352
ctx.moveTo(0, axisY_px); ctx.lineTo(W, axisY_px);
357-
ctx.moveTo(W-12, axisY_px-5); ctx.lineTo(W, axisY_px); ctx.lineTo(W-12, axisY_px+5);
358353
}
359354
if (axisX_px >= 0 && axisX_px <= W) {
360355
ctx.moveTo(axisX_px, H); ctx.lineTo(axisX_px, 0);
361-
ctx.moveTo(axisX_px-5, 12); ctx.lineTo(axisX_px, 0); ctx.lineTo(axisX_px+5, 12);
362356
}
363357
ctx.stroke();
364-
if (axisX_px >= 0 && axisX_px <= W && axisY_px >= 0 && axisY_px <= H) {
365-
ctx.textAlign = 'right';
366-
ctx.fillStyle = '#777';
367-
ctx.fillText('0', axisX_px - 8, axisY_px + 16);
368-
}
369358
const W_half = W / 2;
370359
const H_half = H / 2;
371360
const inv_scale = 1 / scale;
372-
const max_y = 1e8;
373-
const step = 2;
361+
function findDomainEdge(fn, xValid, xInvalid) {
362+
let a = xValid, b = xInvalid;
363+
for (let i = 0; i < 16; i++) {
364+
const mid = (a + b) * 0.5;
365+
if (Number.isFinite(fn(mid))) a = mid;
366+
else b = mid;
367+
}
368+
return a;
369+
}
370+
374371
for (let g = 0; g < graphs.length; g++) {
375372
const g_fn = graphs[g].fn;
376373
ctx.strokeStyle = graphs[g].color;
377374
ctx.lineWidth = graphs[g].width;
378375
ctx.globalAlpha = graphs[g].opacity;
379376
ctx.beginPath();
380-
let first = true;
381-
let prev_py = -999999;
382-
for (let px = 0; px < W; px += step) {
377+
let inPath = false;
378+
let prevPx = 0, prevPy = 0, prevX = 0, prevY = 0;
379+
for (let px = 0; px <= W; px++) {
383380
const x = (px - W_half) * inv_scale + cx;
384381
const y = g_fn(x);
385-
if (y !== y || y === Infinity || y === -Infinity || y > max_y || y < -max_y) {
386-
first = true;
387-
continue;
388-
}
389-
const py = H_half - (y - cy) * scale;
390-
if (!first && Math.abs(py - prev_py) > H * 0.8) {
391-
first = true;
392-
}
393-
if (first) {
394-
ctx.moveTo(px, py);
395-
first = false;
382+
const isValid = Number.isFinite(y);
383+
if (isValid) {
384+
const py = H_half - (y - cy) * scale;
385+
if (!inPath) {
386+
const prevX_math = ((px - 1) - W_half) * inv_scale + cx;
387+
const edgeX = findDomainEdge(g_fn, x, prevX_math);
388+
const edgePx = (edgeX - cx) * scale + W_half;
389+
const edgeY = g_fn(edgeX);
390+
const edgePy = H_half - ((Number.isFinite(edgeY) ? edgeY : 0) - cy) * scale;
391+
ctx.moveTo(edgePx, edgePy);
392+
ctx.lineTo(px, py);
393+
inPath = true;
394+
} else {
395+
if (Math.abs(py - prevPy) > H * 0.8 && Math.sign(y) !== Math.sign(prevY)) {
396+
ctx.moveTo(px, py);
397+
} else {
398+
ctx.lineTo(px, py);
399+
}
400+
}
401+
prevPx = px; prevPy = py; prevX = x; prevY = y;
396402
} else {
397-
ctx.lineTo(px, py);
403+
if (inPath) {
404+
const edgeX = findDomainEdge(g_fn, prevX, x);
405+
const edgePx = (edgeX - cx) * scale + W_half;
406+
const edgeY = g_fn(edgeX);
407+
const edgePy = H_half - ((Number.isFinite(edgeY) ? edgeY : 0) - cy) * scale;
408+
ctx.lineTo(edgePx, edgePy);
409+
inPath = false;
410+
}
398411
}
399-
prev_py = py;
400412
}
401413
ctx.stroke();
402414
}
415+
403416
ctx.globalAlpha = 1;
404417
document.getElementById('sc').textContent = (scale / 50).toFixed(2);
405418
}

0 commit comments

Comments
 (0)