//#region src/types.d.ts
export type Point2D = {
  x: number;
  y: number;
};
export type Point3D = {
  x: number;
  y: number;
  z: number;
};
export type ProjectedPoint = Point2D & {
  projected: Point2D;
};
export type RotatedPoint = Point2D & {
  rotated: Point3D;
};
export type TransformedPoint<T> = T & {
  rotated: Point3D;
  projected: Point2D;
};
/**
 * The fields a shape carries on its array besides its points, such as a
 * `color` set with `Object.assign(points, { color })`. `.data` keeps them.
 * The indices of a tuple are string keys, so `${number}` leaves them out.
 */
export type ShapeFields<Shape extends unknown[]> = Omit<Shape, keyof unknown[] | `${number}`>;
export interface RotationAngles {
  x: number;
  y: number;
  z: number;
  rotateCenter: Point3D;
}
export interface TransformOptions<Datum> {
  origin: Point2D;
  rotateCenter: Point3D;
  rotateX: number;
  rotateY: number;
  rotateZ: number;
  scale: number;
  /** The distance of the eye from the rotation center; `Infinity`, the default, is orthographic. */
  perspective?: number;
  x: (point: Datum) => number;
  y: (point: Datum) => number;
  z: (point: Datum) => number;
}
/**
 * An axis aligned box in world space.
 *
 * `x`, `y` and `z` are the corner of the box, `w`, `d` and `h` its extent
 * along the three axes and `r` the corner radius of its plan outline.
 */
export interface IsoBoxSpec {
  x: number;
  y: number;
  z: number;
  w: number;
  d: number;
  h: number;
  r?: number;
}
/**
 * A rectangle in world space, described by its corner and the two vectors
 * that span it.
 */
export interface IsoPlaneSpec {
  origin: Point3D;
  u: Point3D;
  v: Point3D;
}
/**
 * One axis of a chart box in data units: its extent, from the first to the
 * last value of `domain`, and the values of its ticks.
 */
export interface AxisSpec {
  domain: number[];
  ticks: number[];
}
/**
 * The three axes of a chart box.
 */
export interface AxesSpec {
  x: AxisSpec;
  y: AxisSpec;
  z: AxisSpec;
}
/**
 * The viewport that frames a projected scene.
 */
export interface IsoFrame {
  viewBox: string;
  width: number;
  height: number;
}
//#endregion
//#region src/shapes/shape.d.ts
/**
 * The view of a scene: how it is turned, scaled and placed on the screen.
 * Every shape is a camera, and `camera3D()` is a camera without data.
 */
interface Camera3DInstance {
  scale(): number;
  scale(scale: number): this;
  origin(): Point2D;
  origin(origin: Point2D): this;
  perspective(): number;
  perspective(distance: number): this;
  rotateX(): number;
  rotateX(angle: number): this;
  rotateY(): number;
  rotateY(angle: number): this;
  rotateZ(): number;
  rotateZ(angle: number): this;
  rotationCenter(): Point3D;
  rotationCenter(center: Point3D): this;
  rotationCenter(center?: Point3D): this | Point3D;
  camera(camera: Camera3DInstance): this;
  unproject(point: Point2D, planePoint: Point3D, planeNormal: Point3D): Point3D | null;
  matrix(viewport?: {
    width: number;
    height: number;
    depth?: number;
  }): Float32Array;
  viewDirection(): Point3D;
}
interface ShapeInstance<Datum = Point3D> extends Camera3DInstance {
  x(): (point: Datum) => number;
  x(x: (point: Datum) => number): this;
  y(): (point: Datum) => number;
  y(y: (point: Datum) => number): this;
  z(): (point: Datum) => number;
  z(z: (point: Datum) => number): this;
}
/**
 * A camera without data: one view for several shapes, for a canvas or for a
 * WebGL shader.
 */
export declare function camera3D(): Camera3DInstance;
//#endregion
//#region src/shapes/axes.d.ts
/**
 * One wall of the chart box: its four corners, whether it faces the camera
 * and its gridlines, one segment per tick inside the box. `axis` is the axis
 * the wall stands across and `side` the end of its domain the wall sits at,
 * 0 at the first value and 1 at the last.
 */
type AxisWall = TransformedPoint<Point3D>[] & {
  axis: keyof AxesSpec;
  side: 0 | 1;
  ccw: boolean;
  centroid: Point3D;
  grid: TransformedPoint<Point3D>[][];
};
/**
 * One edge of the chart box along an axis: its ticks, which keep their
 * value under the axis key, and the screen direction away from the box.
 * `sides` are the ends of the two other axes the edge runs at, in the order
 * of the walls they span, and `chosen` marks the edge `axes` puts the axis on.
 */
type AxisEdge = TransformedPoint<Point3D>[] & {
  axis: keyof AxesSpec;
  normal: Point2D;
  sides: [0 | 1, 0 | 1];
  chosen: boolean;
};
interface Axes3DInstance extends ShapeInstance<Point3D> {
  data(spec: AxesSpec): AxisWall[];
  draw(wall: AxisWall): string;
  axes(spec: AxesSpec): AxisEdge[];
  edges(spec: AxesSpec): AxisEdge[];
}
export declare function axes3D(): Axes3DInstance;
//#endregion
//#region src/shapes/cubes.d.ts
type CubeFaceName = "front" | "back" | "left" | "right" | "top" | "bottom";
type CubeFace<Datum = Point3D> = TransformedPoint<Datum>[] & {
  centroid: Point3D;
  ccw: boolean;
  face: CubeFaceName;
};
type Cube<Datum = Point3D, Shape extends Datum[] = Datum[]> = TransformedPoint<Datum>[] & ShapeFields<Shape> & {
  faces: CubeFace<Datum>[];
  centroid: Point3D;
};
interface Cubes3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data<Shape extends Datum[]>(data: Shape[]): Cube<Datum, Shape>[];
  draw(face: TransformedPoint<Datum>[]): string;
}
export declare function cubes3D<Datum = Point3D>(): Cubes3DInstance<Datum>;
//#endregion
//#region src/shapes/gridPlanes.d.ts
type GridPlane<Datum> = TransformedPoint<Datum>[] & {
  ccw: boolean;
  centroid: Point3D;
  plane: string;
};
interface GridPlanes3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  rows(): number;
  rows(rows: number): this;
  data(data: Datum[]): GridPlane<Datum>[];
  draw(gridPlanes: TransformedPoint<Datum>[]): string;
}
export declare function gridPlanes3D<Datum = Point3D>(): GridPlanes3DInstance<Datum>;
//#endregion
//#region src/shapes/iso.d.ts
/**
 * The affine frame of a face: the transform that carries the local
 * coordinates of the face onto the screen.
 */
type IsoPlane = {
  matrix: string;
};
/**
 * A projected box: the two visible paths and the frames of its faces.
 */
type IsoBox = {
  /** The rotated centre of the box, ready for `sort`. */
  centroid: Point3D;
  /** The path of the visible side of the box. */
  wall: string;
  /** The path of the top face. */
  top: string;
  topPlane: IsoPlane;
  frontPlane: IsoPlane;
  sidePlane: IsoPlane;
};
interface Iso3DInstance extends ShapeInstance<Point3D> {
  data(data: IsoBoxSpec[]): IsoBox[];
  plane(spec: IsoPlaneSpec): IsoPlane;
  path(points: Point3D[]): string;
  project(points: Point3D[]): Point2D[];
  frame(points: Point3D[], margin?: number, aspect?: number): IsoFrame;
}
export declare function iso3D(): Iso3DInstance;
//#endregion
//#region src/shapes/lines.d.ts
type Line<Datum, Shape extends Datum[] = Datum[]> = TransformedPoint<Datum>[] & ShapeFields<Shape> & {
  centroid: Point3D;
};
interface Lines3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data<Shape extends Datum[]>(data: Shape[]): Line<Datum, Shape>[];
  draw(line: TransformedPoint<Datum>[]): string;
}
export declare function lines3D<Datum = Point3D>(): Lines3DInstance<Datum>;
//#endregion
//#region src/shapes/lineStrips.d.ts
type LineStrip<Datum, Shape extends Datum[] = Datum[]> = TransformedPoint<Datum>[] & ShapeFields<Shape> & {
  centroid: Point3D;
};
interface LineStrips3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data<Shape extends Datum[]>(data: Shape[]): LineStrip<Datum, Shape>[];
  draw(lineStrip: TransformedPoint<Datum>[]): string;
}
export declare function lineStrips3D<Datum = Point3D>(): LineStrips3DInstance<Datum>;
//#endregion
//#region src/shapes/planes.d.ts
type Plane<Datum, Shape extends Datum[] = Datum[]> = TransformedPoint<Datum>[] & ShapeFields<Shape> & {
  ccw: boolean;
  centroid: Point3D;
};
interface Planes3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data<Shape extends Datum[]>(data: Shape[]): Plane<Datum, Shape>[];
  draw(plane: TransformedPoint<Datum>[]): string;
}
export declare function planes3D<Datum = Point3D>(): Planes3DInstance<Datum>;
//#endregion
//#region src/shapes/points.d.ts
type Point<Datum> = TransformedPoint<Datum> & {
  centroid: Point3D;
};
interface Points3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data(data: Datum[]): Point<Datum>[];
}
export declare function points3D<Datum = Point3D>(): Points3DInstance<Datum>;
//#endregion
//#region src/shapes/polygons.d.ts
type Polygon<Datum, Shape extends Datum[] = Datum[]> = TransformedPoint<Datum>[] & ShapeFields<Shape> & {
  ccw: boolean;
  centroid: Point3D;
};
interface Polygons3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data<Shape extends Datum[]>(data: Shape[]): Polygon<Datum, Shape>[];
  draw(polygon: TransformedPoint<Datum>[]): string;
}
export declare function polygons3D<Datum = Point3D>(): Polygons3DInstance<Datum>;
//#endregion
//#region src/shapes/triangles.d.ts
type Triangle<Datum, Shape extends Datum[] = Datum[]> = TransformedPoint<Datum>[] & ShapeFields<Shape> & {
  ccw: boolean;
  centroid: Point3D;
};
interface Triangles3DInstance<Datum = Point3D> extends ShapeInstance<Datum> {
  data<Shape extends Datum[]>(data: Shape[]): Triangle<Datum, Shape>[];
  draw(triangle: TransformedPoint<Datum>[]): string;
}
export declare function triangles3D<Datum = Point3D>(): Triangles3DInstance<Datum>;
//#endregion
//#region src/sort.d.ts
interface HasCentroid {
  centroid: {
    z: number;
  };
}
export declare function sort<T extends HasCentroid>(a: T, b: T): number;
//#endregion
//#region src/counter-clockwise.d.ts
export declare function ccw<T>(polygon: ReadonlyArray<TransformedPoint<T>>): boolean;
//#endregion
//#region src/centroid.d.ts
export declare function centroid<T>(polygon: ReadonlyArray<TransformedPoint<T>>): Point3D;
//#endregion
//#region src/normal.d.ts
/**
 * The unit normal of a polygon, by Newell's method: exact for a flat
 * polygon of any size, an average for a slightly bent one.
 *
 * It points to the side from which the vertices run counter-clockwise on
 * the screen, where y grows downwards: the side `ccw` reports. So the faces
 * of `cubes3D` point outwards, and a face faces the camera where
 * `dot(normal, viewDirection) > 0`, or in perspective where
 * `dot(normal, eye − vertex) > 0`.
 *
 * Returns the zero vector for a polygon without an area.
 */
export declare function normal(polygon: ReadonlyArray<Point3D>): Point3D;
//#endregion
//#region src/box.d.ts
/**
 * The eight corners of a box in the order `cubes3D` expects: front top
 * left, front bottom left, front bottom right and front top right, then
 * the same four at the back.
 *
 * The box stands on the point (x, y, z): its footprint is centered on x and
 * z, `width` along x and `depth` along z, and it rises `height` from y
 * upwards, towards -y as on the screen. Its front is the side at +z.
 *
 * `topWidth` and `topDepth` size the top apart from the footprint, for a
 * tapered shaft; a top of zero width is a ridge, one of zero size an apex.
 */
export declare function box(spec: {
  x: number;
  y: number;
  z: number;
  width: number;
  height: number;
  depth: number;
  topWidth?: number;
  topDepth?: number;
}): Point3D[];
//#endregion
//#region src/lathe.d.ts
/**
 * The surface of revolution of a profile: the triangles that `triangles3D`
 * expects.
 *
 * The profile lies in the x-y plane, x the radius and y the height, and is
 * turned around the y axis in `segments` steps. Between two rings every step
 * is a quad of two triangles. A ring of radius 0 is a single point, so a
 * quad next to it is one triangle, and a profile that starts and ends on the
 * axis closes into a solid.
 *
 * The profile runs upwards, from a large y to a small one as on the screen.
 * Then every triangle runs counter-clockwise when it is seen from outside:
 * its `normal` points outwards and `ccw` tells the outside from the inside.
 * A profile that runs downwards turns the surface inside out.
 */
export declare function lathe(profile: ReadonlyArray<Point2D>, segments: number): Point3D[][];
//#endregion
//#region src/sphere.d.ts
/**
 * The triangles of a sphere around the point (x, y, z): the triangles that
 * `triangles3D` expects.
 *
 * A half circle from the bottom pole to the top one is turned around the y
 * axis by `lathe` in `segments` steps, and half as many bands, rounded up,
 * run from pole to pole, so the quads between them are close to square. The
 * poles lie on the axis, so the bands next to them close in fans. Below 3
 * segments there is no sphere and the list is empty.
 *
 * Every triangle runs counter-clockwise when it is seen from outside: its
 * `normal` points outwards and `ccw` tells the front of the sphere from its
 * back.
 */
export declare function sphere(spec: {
  x: number;
  y: number;
  z: number;
  radius: number;
}, segments: number): Point3D[][];
//#endregion
//#region src/strips.d.ts
/**
 * Cuts a polyline into strips of `size` points that share their end points,
 * the last one shorter if the points run out.
 *
 * `sort` orders a line strip by the depth of its middle, so a long line that
 * passes in front of a shape and behind it again is painted wrong as a
 * whole. Cut into strips, every piece sorts on its own depth. A `size` of 2
 * cuts the line into its segments.
 */
export declare function strips<T>(points: ReadonlyArray<T>, size: number): T[][];
//#endregion
//#region src/catmull-rom.d.ts
/**
 * The uniform Catmull–Rom spline through `points`, `steps` samples per
 * segment: a smooth curve that passes through every point, ready for
 * `lineStrips3D`.
 *
 * The end points stand in for their missing neighbours, so the curve starts
 * on the first point and ends on the last.
 */
export declare function catmullRom(points: ReadonlyArray<Point3D>, steps: number): Point3D[];
//#endregion
//#region src/axis-spec.d.ts
/**
 * A continuous scale with ticks, such as d3's `scaleLinear`.
 */
interface TickScale {
  domain(): number[];
  ticks(count?: number): number[];
}
/**
 * One axis of `axes3D` from a scale: the domain of the scale and about
 * `count` of its ticks.
 *
 * Call `.nice()` on the scale first, so the box ends on a tick.
 */
export declare function axisSpec(scale: TickScale, count?: number): AxisSpec;
//#endregion
//#region src/transform.d.ts
export declare function transform<Datum = Point3D>(data: Datum[], options: TransformOptions<Datum>): TransformedPoint<Datum>[];
//#endregion
//#region src/projection-orthographic.d.ts
interface OrthographicOptions {
  origin: Point2D;
  scale: number;
}
export declare function orthographic(d: Point3D, options: OrthographicOptions): Point2D;
//#endregion
//#region src/projection-perspective.d.ts
interface PerspectiveOptions extends OrthographicOptions {
  rotateCenter: Point3D;
  /** The distance of the eye from the rotation center, in model units. */
  distance: number;
}
/**
 * Projects a rotated point as seen from an eye `distance` in front of the
 * rotation center, on the rotated z axis that points towards the viewer.
 *
 * A point in the plane of the center keeps the scale of `orthographic`, a
 * nearer one is drawn larger and a farther one smaller, by
 * `k = distance / (distance − (z − center.z))`. An infinite distance gives
 * `k = 1`: the orthographic projection. The point has to lie in front of
 * the eye.
 */
export declare function perspective(d: Point3D, options: PerspectiveOptions): Point2D;
//#endregion
//#region src/projection-matrix.d.ts
/**
 * Projects packed x, y, z triples through `matrix` into `out`: screen x,
 * screen y and depth, three numbers per point. Pass the same `out` every
 * frame to project a large point cloud without allocating.
 *
 * x and y are divided by w, which is 1 unless the matrix is perspective.
 * The depth is not, so it stays the rotated z that `sort` reads.
 */
export declare function projectPositions(positions: ArrayLike<number>, matrix: ArrayLike<number>, out?: Float32Array): Float32Array;
//#endregion
export type { Axes3DInstance, AxisEdge, AxisWall, Camera3DInstance, Cube, CubeFace, CubeFaceName, Cubes3DInstance, GridPlane, GridPlanes3DInstance, HasCentroid, Iso3DInstance, IsoBox, IsoPlane, Line, LineStrip, LineStrips3DInstance, Lines3DInstance, OrthographicOptions, PerspectiveOptions, Plane, Planes3DInstance, Point, Points3DInstance, Polygon, Polygons3DInstance, ShapeInstance, TickScale, Triangle, Triangles3DInstance };
//# sourceMappingURL=index.d.ts.map