@@ -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