import * as d3 from 'd3'; import { Point } from '../types/Point'; import { Path, transformed } from './Path'; class QuadraticBezier extends Path { private readonly _start: Point; private readonly _control: Point; private readonly _end: Point; constructor (start: Point, control: Point, end: Point) { super(); this._start = start; this._control = control; this._end = end; } angleAlong (t: number, x: d3.ScaleLinear, y: d3.ScaleLinear): number { const s = transformed(this._start, x, y); const c = transformed(this._control, x, y); const e = transformed(this._end, x, y); const u = 1 - t; const dx = 2 * u * (c.x - s.x) + 2 * t * (e.x - c.x); const dy = 2 * u * (c.y - s.y) + 2 * t * (e.y - c.y); return Math.atan2(dx, dy) - Math.PI; } apply (context: CanvasRenderingContext2D, x: d3.ScaleLinear, y: d3.ScaleLinear): void { const s = transformed(this._start, x, y); const c = transformed(this._control, x, y); const e = transformed(this._end, x, y); context.moveTo(s.x, s.y); context.quadraticCurveTo(c.x, c.y, e.x, e.y); } pointAlong (t: number, x: d3.ScaleLinear, y: d3.ScaleLinear): Point { const s = transformed(this._start, x, y); const c = transformed(this._control, x, y); const e = transformed(this._end, x, y); const u = 1 - t; return { x: u * u * s.x + 2 * u * t * c.x + t * t * e.x, y: u * u * s.y + 2 * u * t * c.y + t * t * e.y }; } points (): Point[] { return [this._start, this._control, this._end]; } } export { QuadraticBezier }