#10 ふれてみよう高校数学 解析(微分・積分・極限)

接線と法線の方程式

接線の方程式

「カーブを走る車が急ハンドルをやめた瞬間、まっすぐ進む方向」——これが接線のイメージです。曲線のある点でどの方向に向いているかを示す直線が接線です。

曲線 y=f(x)y = f(x) 上の点 (a, f(a))\bigl(a,\ f(a)\bigr) における接線(tangent line)の方程式は:

yf(a)=f(a)(xa)y - f(a) = f'(a)(x - a)

つまり、傾きが f(a)f'(a) で点 (a,f(a))\bigl(a, f(a)\bigr) を通る直線です——「傾き = 微分係数」がここで役立ちます。


法線の方程式

「接線と直角に交わる直線」——法線(normal line)は接線に直交する直線です。傾き mm の直線に垂直な直線の傾きは 1m-\dfrac{1}{m}m0m \neq 0 のとき)——「傾きの積が 1-1 になると垂直」なので:

yf(a)=1f(a)(xa)(f(a)0)y - f(a) = -\frac{1}{f'(a)}(x - a) \quad (f'(a) \neq 0)

例:y=x2y = x^2 の接線と法線

「放物線のある点での接線と法線を求める」——f(x)=x2f(x) = x^2f(x)=2xf'(x) = 2x なので、x=ax = a での接線:

ya2=2a(xa)    y=2axa2y - a^2 = 2a(x - a) \implies y = 2ax - a^2

法線:

ya2=12a(xa)(a0)y - a^2 = -\frac{1}{2a}(x - a) \quad (a \neq 0)

数値例a=1a = 1 のとき

  • 接線:y=2x1y = 2x - 1(傾き 22)——「x=1x = 1 での放物線の傾きは 2」
  • 法線:y=12x+32y = -\dfrac{1}{2}x + \dfrac{3}{2}(傾き 1/2-1/2)——「接線の傾き 2 の逆数は 12\frac{1}{2}、符号を反転して 12-\frac{1}{2}

デモ:y=x2y = x^2 の接線と法線

マウスを左右に動かして接点 aa を変えてください。接線(黄)と法線(オレンジ)がリアルタイムに更新されます。両者が直交していることを視覚的に確認できます。

y=x² の接線(黄)と法線(橙)。マウスで接点を移動。
function loop() {
ctx.clearRect(0, 0, W, H);
var scale=55;
var ox=W/2, oy=H*0.7;

function toSx(x){return ox+x*scale;}
function toSy(y){return oy-y*scale;}

function drawAxes(){
  ctx.strokeStyle='rgba(255,255,255,0.13)';
  ctx.lineWidth=1;
  ctx.beginPath();ctx.moveTo(0,oy);ctx.lineTo(W,oy);ctx.stroke();
  ctx.beginPath();ctx.moveTo(ox,0);ctx.lineTo(ox,H);ctx.stroke();
  ctx.fillStyle='rgba(255,255,255,0.25)';
  ctx.font='10px monospace';
  ctx.textAlign='center';
  for(var i=-5;i<=5;i++){
    if(i===0)continue;
    ctx.fillText(i,toSx(i),oy+14);
  }
  ctx.textAlign='right';
  for(var j=1;j<=4;j++){
    ctx.fillText(j,ox-6,toSy(j)+4);
  }
}

function plotCurve(fn,color,lw){
  ctx.strokeStyle=color;ctx.lineWidth=lw||2;
  ctx.beginPath();
  var first=true;
  for(var xi=-W/2;xi<=W/2;xi+=1){
    var x=xi/scale;
    var y=fn(x);
    if(!isFinite(y)||y>H/scale+0.5||y<-1){first=true;continue;}
    if(first){ctx.moveTo(toSx(x),toSy(y));first=false;}
    else ctx.lineTo(toSx(x),toSy(y));
  }
  ctx.stroke();
}

function drawInfiniteLine(x0,y0,slope,color,dash){
  // extend to canvas edges
  ctx.strokeStyle=color;ctx.lineWidth=1.5;
  if(dash)ctx.setLineDash(dash);else ctx.setLineDash([]);
  // find x where y goes out of bounds
  var ext=6;
  var sx1=toSx(x0-ext), sy1=toSy(y0+slope*(-ext));
  var sx2=toSx(x0+ext), sy2=toSy(y0+slope*ext);
  ctx.beginPath();ctx.moveTo(sx1,sy1);ctx.lineTo(sx2,sy2);ctx.stroke();
  ctx.setLineDash([]);
}

ctx.fillStyle='#0d1117';
ctx.fillRect(0,0,W,H);
drawAxes();

var f=function(x){return x*x;};
var fd=function(x){return 2*x;};

plotCurve(f,'#4fc3f7',2.5);

// Mouse x
var a=(mx-ox)/scale;
a=Math.max(-2.8,Math.min(2.8,a));
var fa=f(a);
var slope=fd(a);

// Tangent line
drawInfiniteLine(a,fa,slope,'rgba(255,202,40,0.9)',[]);

// Normal line (perpendicular)
if(Math.abs(slope)>0.05){
  var normalSlope=-1/slope;
  drawInfiniteLine(a,fa,normalSlope,'rgba(255,138,101,0.85)',[5,4]);
}

// Right angle marker at tangent point
if(Math.abs(slope)>0.05){
  var ang=Math.atan(slope);
  var sz=10;
  var px1=toSx(a)+Math.cos(ang)*sz;
  var py1=toSy(fa)-Math.sin(ang)*sz; // careful with y-flip
  // just draw a small square
  ctx.save();
  ctx.translate(toSx(a),toSy(fa));
  ctx.rotate(-ang);
  ctx.strokeStyle='rgba(255,255,255,0.5)';
  ctx.lineWidth=1;
  ctx.strokeRect(6,-6,8,8);
  ctx.restore();
}

// Point on curve
ctx.beginPath();ctx.arc(toSx(a),toSy(fa),6,0,Math.PI*2);
ctx.fillStyle='#fff';ctx.fill();
ctx.strokeStyle='#ffca28';ctx.lineWidth=2;ctx.stroke();

// Info panel
ctx.fillStyle='rgba(0,0,0,0.7)';
ctx.fillRect(8,8,280,100);
ctx.font='12px monospace';ctx.textAlign='left';
ctx.fillStyle='#4fc3f7';
ctx.fillText('接点: ('+a.toFixed(3)+', '+fa.toFixed(3)+')',14,28);
ctx.fillStyle='#ffca28';
ctx.fillText("接線傾き f'(a) = "+slope.toFixed(3),14,46);
var tangentEq='y = '+slope.toFixed(2)+'x + '+(fa-slope*a).toFixed(2);
ctx.fillText('接線: '+tangentEq,14,64);
ctx.fillStyle='#ff8a65';
if(Math.abs(slope)>0.05){
  var ns=-1/slope;
  var normalEq='y = '+ns.toFixed(2)+'x + '+(fa-ns*a).toFixed(2);
  ctx.fillText('法線: '+normalEq,14,82);
} else {
  ctx.fillText('法線: x = '+a.toFixed(2)+' (垂直線)',14,82);
}

// Legend
ctx.font='12px sans-serif';ctx.textAlign='right';
ctx.fillStyle='#ffca28';ctx.fillText('── 接線',W-10,H-28);
ctx.fillStyle='#ff8a65';ctx.fillText('- - 法線',W-10,H-10);

requestAnimationFrame(loop);
}
loop();

別の曲線での例

y=sinxy = \sin x の接線

sin\sin のグラフで、x=π/3x = \pi/3 の点に接する直線」——f(x)=cosxf'(x) = \cos x なので x=π3x = \dfrac{\pi}{3} での接線:

ysinπ3=cosπ3(xπ3)y - \sin\frac{\pi}{3} = \cos\frac{\pi}{3}\left(x - \frac{\pi}{3}\right) y32=12(xπ3)y - \frac{\sqrt{3}}{2} = \frac{1}{2}\left(x - \frac{\pi}{3}\right)

y=lnxy = \ln x の接線

x=ex = e での接線は原点を通る」——f(x)=1xf'(x) = \dfrac{1}{x}x=ex = e での接線:

y1=1e(xe)    y=xey - 1 = \frac{1}{e}(x - e) \implies y = \frac{x}{e}

特別なケース

f(a)=0f'(a) = 0(水平接線)

「山頂や谷底では接線が水平になる」——接線が水平(y=f(a)y = f(a) の定数関数)になります。法線は垂直線 x=ax = a

原点を通る接線

「放物線の上のどの点から引いた接線が原点を通るか」——曲線上の点 (a,f(a))(a, f(a)) における接線が原点 (0,0)(0, 0) を通る条件:

0f(a)=f(a)(0a)    f(a)=af(a)0 - f(a) = f'(a)(0 - a) \implies f(a) = a \cdot f'(a)

f(x)=x2f(x) = x^2 の場合、a2=a2a=2a2a2=0a=0a^2 = a \cdot 2a = 2a^2 \Rightarrow a^2 = 0 \Rightarrow a = 0(頂点のみ)。


陰関数の接線

y=y = の形で表せていない円の方程式でも接線を求められる」——x2+y2=5x^2 + y^2 = 5(円)上の点 (1,2)(1, 2) での接線:両辺を xx で微分すると:

2x+2ydydx=0    dydx=xy2x + 2y\frac{dy}{dx} = 0 \implies \frac{dy}{dx} = -\frac{x}{y}

(1,2)(1, 2) での傾き:12-\dfrac{1}{2}。接線:y2=12(x1)y=x2+52y - 2 = -\dfrac{1}{2}(x-1) \Rightarrow y = -\dfrac{x}{2} + \dfrac{5}{2}


まとめ

接線: yf(a)=f(a)(xa),法線: yf(a)=1f(a)(xa)\text{接線: } y - f(a) = f'(a)(x-a), \quad \text{法線: } y - f(a) = -\frac{1}{f'(a)}(x-a)
  • 接線の傾き == 微分係数 f(a)f'(a)——「微分値がそのまま傾きになる」
  • 法線は接線に直交、傾きは 1/f(a)-1/f'(a)——「傾きの積が 1-1 になると直交」
  • 陰関数微分を使えば陰関数でも接線が求められる——「y=y = の形でなくても OK」

次回からは積分——「面積」を計算する逆の演算を学びます。まず不定積分からスタートです。