일차 함수 그래프: 기울기와 y절편으로 이해하는 선형 관계
일차 함수의 수학적 정의부터 기울기 시각화, 실생활 응용, JavaScript 그래프 렌더링까지 완벽 분석
접선(Tangent)은 곡선의 특정 지점에서 그 곡선에 접하는 직선입니다. 접선은 곡선이 그 지점에서 어떤 방향으로 변화하는지, 즉 순간적인 기울기를 나타냅니다.
예: 자동차 핸들
- 원형 핸들을 돌릴 때, 손이 닿는 점에서의 이동 방향
→ 그 점에서 원의 접선 방향
예: 롤러코스터
- 레일의 특정 지점에서 탑승자가 느끼는 방향
→ 그 지점에서 레일 곡선의 접선 방향
함수 의 점 에서의 접선 기울기는 미분으로 정의됩니다:
접선의 방정식:
의 에서의 접선을 구해보겠습니다.
미분 계산:
에서의 기울기:
점:
접선의 방정식:
접선은 곡선이 그 지점에서 어디로 향하는지 보여줍니다.
원의 접선 시각화 (ASCII):
|
. . | . .
. | .
. ──┼── . ← 접선 (수평)
. | .
. . | . .
|
물체가 곡선을 따라 움직일 때, 접선 방향이 속도 벡터입니다.
Cubic Bezier 곡선은 4개의 제어점 으로 정의됩니다:
특별한 경우:
의미:
/**
* Cubic Bezier 곡선의 점과 접선 계산
*/
class CubicBezier {
constructor(p0, p1, p2, p3) {
this.p0 = p0; // { x, y }
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
// 곡선 위의 점 계산
point(t) {
const mt = 1 - t;
const mt2 = mt * mt;
const t2 = t * t;
return {
x:
mt2 * mt * this.p0.x +
3 * mt2 * t * this.p1.x +
3 * mt * t2 * this.p2.x +
t2 * t * this.p3.x,
y:
mt2 * mt * this.p0.y +
3 * mt2 * t * this.p1.y +
3 * mt * t2 * this.p2.y +
t2 * t * this.p3.y,
};
}
// 접선 벡터 계산
tangent(t) {
const mt = 1 - t;
const mt2 = mt * mt;
const t2 = t * t;
return {
x:
3 * mt2 * (this.p1.x - this.p0.x) +
6 * mt * t * (this.p2.x - this.p1.x) +
3 * t2 * (this.p3.x - this.p2.x),
y:
3 * mt2 * (this.p1.y - this.p0.y) +
6 * mt * t * (this.p2.y - this.p1.y) +
3 * t2 * (this.p3.y - this.p2.y),
};
}
// 정규화된 접선 (단위 벡터)
normalizedTangent(t) {
const tan = this.tangent(t);
const length = Math.sqrt(tan.x * tan.x + tan.y * tan.y);
return {
x: tan.x / length,
y: tan.y / length,
};
}
}
// 사용 예
const curve = new CubicBezier(
{ x: 0, y: 0 }, // P0
{ x: 50, y: 100 }, // P1
{ x: 150, y: 100 }, // P2
{ x: 200, y: 0 } // P3
);
console.log('t=0에서의 점:', curve.point(0));
console.log('t=0에서의 접선:', curve.tangent(0));
console.log('t=0.5에서의 점:', curve.point(0.5));
console.log('t=0.5에서의 접선:', curve.tangent(0.5));CSS transition의 cubic-bezier() 함수도 접선 개념을 사용합니다.
.box {
transition: transform 1s cubic-bezier(0.25, 0.1, 0.25, 1);
}매개변수: cubic-bezier(x1, y1, x2, y2)
/**
* CSS cubic-bezier 타이밍 함수
*/
function cubicBezierTiming(x1, y1, x2, y2) {
return function (t) {
// 1차원 Bezier 곡선 (y 값만 계산)
const mt = 1 - t;
return (
3 * mt * mt * t * y1 +
3 * mt * t * t * y2 +
t * t * t
);
};
}
// 내장 easing 함수들
const ease = cubicBezierTiming(0.25, 0.1, 0.25, 1);
const easeIn = cubicBezierTiming(0.42, 0, 1, 1);
const easeOut = cubicBezierTiming(0, 0, 0.58, 1);
const easeInOut = cubicBezierTiming(0.42, 0, 0.58, 1);
// 사용 예
for (let t = 0; t <= 1; t += 0.2) {
console.log(`t=${t}: ease=${ease(t).toFixed(3)}`);
}/**
* 객체가 Bezier 곡선을 따라 이동하며 회전
*/
class PathFollower {
constructor(curve, element) {
this.curve = curve;
this.element = element;
this.progress = 0;
}
update(deltaTime) {
this.progress += deltaTime * 0.001; // 속도 조절
if (this.progress > 1) this.progress = 0;
const point = this.curve.point(this.progress);
const tangent = this.curve.tangent(this.progress);
// 위치 설정
this.element.style.left = `${point.x}px`;
this.element.style.top = `${point.y}px`;
// 접선 방향으로 회전
const angle = Math.atan2(tangent.y, tangent.x) * (180 / Math.PI);
this.element.style.transform = `rotate(${angle}deg)`;
}
}
// 사용
const curve = new CubicBezier(
{ x: 100, y: 100 },
{ x: 200, y: 50 },
{ x: 300, y: 150 },
{ x: 400, y: 100 }
);
const follower = new PathFollower(curve, document.querySelector('.car'));
let lastTime = 0;
function animate(time) {
const deltaTime = time - lastTime;
lastTime = time;
follower.update(deltaTime);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);class Character {
constructor() {
this.position = { x: 0, y: 0 };
this.velocity = { x: 0, y: 0 };
}
update(dt) {
// 위치 업데이트
this.position.x += this.velocity.x * dt;
this.position.y += this.velocity.y * dt;
// 속도 벡터(접선)로 회전 각도 계산
if (this.velocity.x !== 0 || this.velocity.y !== 0) {
this.angle = Math.atan2(this.velocity.y, this.velocity.x);
}
}
draw(ctx) {
ctx.save();
ctx.translate(this.position.x, this.position.y);
ctx.rotate(this.angle); // 이동 방향으로 회전
ctx.fillRect(-10, -5, 20, 10); // 캐릭터 그리기
ctx.restore();
}
}접선에 수직인 법선 벡터는 3D 조명 계산에 필수입니다.
/**
* 접선으로부터 법선 계산 (2D)
*/
function getNormal(tangent) {
// 90도 회전
return {
x: -tangent.y,
y: tangent.x,
};
}
// 정규화
function normalize(vec) {
const length = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
return {
x: vec.x / length,
y: vec.y / length,
};
}
// 사용 예
const curve = new CubicBezier(
{ x: 0, y: 0 },
{ x: 50, y: 100 },
{ x: 150, y: 100 },
{ x: 200, y: 0 }
);
const tangent = curve.tangent(0.5);
const normal = normalize(getNormal(tangent));
console.log('법선 벡터:', normal);/**
* 그래프 위의 점에 접선 표시
*/
function drawTangentLine(ctx, func, x, length = 50) {
const y = func(x);
const h = 0.001;
const slope = (func(x + h) - func(x - h)) / (2 * h); // 수치 미분
// 접선의 시작점과 끝점
const x1 = x - length;
const y1 = y - slope * length;
const x2 = x + length;
const y2 = y + slope * length;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = 'red';
ctx.stroke();
}
// 사용 예: y = x^2의 접선
const parabola = (x) => x * x;
drawTangentLine(ctx, parabola, 2);접선의 변화율인 2차 미분은 곡선의 휘어진 정도(곡률)를 나타냅니다.
class CubicBezier {
// ... (이전 메서드들)
// 2차 미분 (가속도)
secondDerivative(t) {
const mt = 1 - t;
return {
x:
6 * mt * (this.p2.x - 2 * this.p1.x + this.p0.x) +
6 * t * (this.p3.x - 2 * this.p2.x + this.p1.x),
y:
6 * mt * (this.p2.y - 2 * this.p1.y + this.p0.y) +
6 * t * (this.p3.y - 2 * this.p2.y + this.p1.y),
};
}
// 곡률 계산
curvature(t) {
const d1 = this.tangent(t);
const d2 = this.secondDerivative(t);
const numerator = d1.x * d2.y - d1.y * d2.x;
const denominator = Math.pow(d1.x * d1.x + d1.y * d1.y, 1.5);
return Math.abs(numerator / denominator);
}
}
// 사용: 곡선에서 가장 급격하게 휘는 지점 찾기
const curve = new CubicBezier(
{ x: 0, y: 0 },
{ x: 50, y: 100 },
{ x: 150, y: 100 },
{ x: 200, y: 0 }
);
let maxCurvature = 0;
let maxT = 0;
for (let t = 0; t <= 1; t += 0.01) {
const k = curve.curvature(t);
if (k > maxCurvature) {
maxCurvature = k;
maxT = t;
}
}
console.log(`최대 곡률: ${maxCurvature.toFixed(4)} at t=${maxT.toFixed(2)}`);접선(Tangent)은 다음과 같은 이유로 애니메이션과 그래픽스의 핵심입니다:
주요 활용:
cubic-bezier)접선을 이해하면 부드럽고 자연스러운 곡선 애니메이션을 만들 수 있으며, 미적분학과 컴퓨터 그래픽스의 다리 역할을 합니다.
일차 함수의 수학적 정의부터 기울기 시각화, 실생활 응용, JavaScript 그래프 렌더링까지 완벽 분석
선형 보간을 통한 Cubic-bezier 곡선 생성 원리와 CSS 애니메이션에서의 활용
선형 보간의 수학적 증명부터 애니메이션, 게임 개발, 데이터 시각화까지 실전 활용법 완벽 분석