import { vec3 } from "./Vector";
import { CollisionInformation, IAbstractBounds, Ray } from "../Types";
import { Line, LineSegment, Plane, PlaneSegment, Transformation } from "./MathTypes";
/**
 * Function to decide whether two components would collide if they were transformed according to the parameters
 * @param first The first component Id
 * @param second The second component Id
 * @param firstTransformation desired world position and rotation of first component
 * @param secondTransformation desired world position and rotation of second component
 * @param error
 */
export declare function wouldComponentsCollide(first: string, second: string, firstTransformation: Transformation, secondTransformation: Transformation, error?: number): CollisionInformation;
/**
 * @param angleYRad The angle to rotate around the y axis. Given in radians.
 * @param previousPoint The previous position
 * @param fixPoint The fixed point of the rotation (the rotation center)
 */
export declare function AdaptToRotation(angleYRad: number, previousPoint: vec3, fixPoint: vec3): vec3;
/**
 * Get the height of the passed Id. Calculated via the points (max - min)
 * TODO 2018-09-19 is this still working? (better use bounding box?)
 * @param componentId the id of the component
 * @returns its height
 */
export declare function GetHeight(componentId: string): number;
/**
 * Get the intersection point of the ray and the plane if there is one
 * @param ray the ray
 * @param plane the plane
 * @returns WorldCoordinates or null if there is no intersection point, null if direction leads away
 */
export declare function GetIntersectionPoint(ray: Ray, plane: Plane): vec3 | null;
/**
 * Gets a factor t so that (ray.direction * t) is an intersection point on the plane.
 * If the ray is parallel to the plane or leads away from it, it returns null.
 * @param ray
 * @param plane
 */
export declare function FactorOfDirectionFromRayToPlane(ray: Ray, plane: Plane): number | null;
/**
 * Projects the point to the plane, returning the point in the plane that is closest to the given point.
 * @param point
 * @param plane
 * @returns {vec3}
 */
export declare function ProjectToPlane(point: vec3, plane: Plane): vec3 | null;
/**
 * Determine if the given point is in the upper half space of the plane.
 * Note that this depends on the direction of the plane normal.
 * @param point
 * @param plane
 * @returns {boolean}
 */
export declare function IsInUpperHalfSpace(point: vec3, plane: Plane): boolean;
/**
 * Determine if the given point is in the lower half space of the plane.
 * Note that this depends on the direction of the plane normal.
 * @param point
 * @param plane
 * @returns {boolean}
 */
export declare function IsInLowerHalfSpace(point: vec3, plane: Plane): boolean;
/**
 * The distance between two objects.
 * Note that this function probably returns inconsistent values for boxes in general locations.
 * It works fine for boxes with just one rotation component.
 * TODO 2018-09-19 testing
 * @param firstComponentId
 * @param secondComponentId
 * @returns {number}
 */
export declare function DistanceOfObjects(firstComponentId: string, secondComponentId: string): number;
/**
 * The middle of the bounding box of the object
 * @param componentId
 * @returns {vec3}
 */
export declare function MiddleOfObject(componentId: string): vec3;
/**
 * The average middle point of all objects
 * @param componentIds
 * @returns {vec3}
 */
export declare function MiddleOfObjects(componentIds: string[]): vec3;
/**
 * The distance of a point to the plane.
 * Calculated by the distance of the point to its projection on the plane.
 * @param point
 * @param plane
 * @returns {number}
 */
export declare function DistanceToPlane(point: vec3, plane: Plane): number;
/**
 * Finds the point on the line with minimal distance to the given point.
 * For this, use the direction of the line as a normal vector for a plane containing the point.
 * The closest point then is the projection of the line to this plane.
 * @param line
 * @param point
 * @returns {vec3}
 */
export declare function ClosestPointOnLine(line: Line, point: vec3): vec3 | null;
/**
 * Calulcates the distance a point has to the plane segment.
 * There are two cases:
 * 		- The point projected to the plane of the segment is inside the plane segment.
 * 		Then the distance is the distance the point has to its projection
 * 		- Otherwise the projection is not in the segment. Calculate the distance to the closest border of the segment.
 * 		Applying the pythagorean rule we obtain the distance.
 *
 * 		, .
 * 		, |\
 * 		, | \
 * 		a |  \  c
 * 		, |   \
 * 		, |    \
 * 		, p-----
 * 		, _______
 * 				b
 * 		. is the point in 3D space
 * 		p is the projection to the plane of the segment
 * 		_____ is the segment
 * 		Pythargoras: a^2 + b^2 = c^2
 * @param segment
 * @param point
 * @returns {number}
 */
export declare function DistanceToPlaneSegment(segment: PlaneSegment, point: vec3): number;
/**
 * Projects the point to the plane segment.
 * For this, we first project the point to the plane containing the plane segment.
 * Then there are two cases to consider:
 * 		a) the point is already inside the plane segment
 * 		b) the point is not in the plane segment
 *
 * 	In the first case the projection is the same as the projection to the plane.
 * 	In the second case we also have to consider the borders of the segment and project to them,
 * 	choosing the smallest distance line segment.
 * @param segment
 * @param point
 * @returns {vec3}
 */
export declare function ProjectToPlaneSegment(segment: PlaneSegment, point: vec3): vec3;
/**
 * Calculate the distance to the line segment.
 * This is either the closest point on the line containing the segment, or one of the border points.
 * @param segment
 * @param point
 * @returns {number}
 */
export declare function DistanceToLineSegment(segment: LineSegment, point: vec3): number;
/**
 * Check if point is on the line segment. Assumes that the point is already on the line containing the segment.
 * For this, effectively project the point to the line and check if the projection is between the two points.
 * This can be achieved by comparing innerProducts.
 * @param segment
 * @param point
 * @returns {boolean}
 */
export declare function IsPointOnLineSegment(segment: LineSegment, point: vec3): boolean;
/**
 * Find the closest point to the given point on a line segment.
 * @param segment
 * @param point
 * @returns {vec3}
 */
export declare function ProjectToLineSegment(segment: LineSegment, point: vec3): vec3;
/**
 * Checks if the point is contained in the plane segment. This assumes that the point is already in the plane of the segment!
 * @param segment
 * @param point
 * @returns {boolean}
 */
export declare function IsInsidePlaneSegment(segment: PlaneSegment, point: vec3): boolean;
/**
 * Get the line segments of the plane segment, e.g. the borders of the segment
 * @param segment
 * @returns {LineSegment[]}
 */
export declare function LineSegmentsOfPlaneSegment(segment: PlaneSegment): LineSegment[];
/**
 * Gets the distance of a point the the abstract bounds.
 * For this get the minimal distance of all plane segments of the bounds.
 * @param bounds
 * @param point
 * @returns {number}
 */
export declare function DistanceToAbstractBounds(bounds: IAbstractBounds, point: vec3): number;
/**
 * Check whether a point is inside the given bounds.
 * @param bounds
 * @param point
 * @returns {boolean}
 */
export declare function IsPointInsideBounds(bounds: IAbstractBounds, point: vec3): boolean;
/**
 * Rotation of vector a around vector b considering c as axis and
 * @param a
 * @param b
 * @param n
 * @param angle
 */
export declare function rotateVectorAAroundPointBByNormalCWithRadiantAngle(a: vec3, b: vec3, n: vec3, angle: number): vec3;
export declare function getOrderedIntersectionFactor(ray: Ray, plane: Plane): number | null;
export declare function intersectPlanes(p1: Plane, p2: Plane): Ray | null;
