INTERFACE HI3; (* Oriented projective geometry in three dimensions using integer. Created in Feb. 19, 1997 by Marcus Vinicius A. Andrade Based on H3.pas by J. Stolfi. *) IMPORT I4, I6, LR3; EXCEPTION ValidationError(TEXT); TYPE Point = RECORD c: I4.T END; (* c[0..3] are coords [w,x,y,z]. *) Plane = RECORD f: I4.T END; (* f[0..3] are coeffs . *) Line = RECORD k: I6.T END; (* k[0..5] are Plucker coords [wx,wy,xy,wz,xz,yz] *) Sign = [-1..1]; VAR Origin : Point; PROCEDURE IsInvalidPoint(READONLY p: Point) : BOOLEAN; (* Returns TRUE if "p" is the invalid tuple "[0,0,0,0]" *) PROCEDURE FromCartesian(READONLY c: LR3.T): Point; (* Point on "hither" half of space (i.e, with positive weight) whose Cartesian coordinates are "c". *) PROCEDURE ToCartesian(READONLY p: Point): LR3.T; (* Cartesian coordinates of point "p" (which must be finite). *) PROCEDURE Side(READONLY p: Point; READONLY Q: Plane): Sign; (* Returns the position of point "p" relative to plane "Q": 0 on the plane, +1 in positive halfspace, -1 in negative halfspace. May give inconsistent results for points very close to the plane. *) PROCEDURE Orient(READONLY p, q, r, s: Point): Sign; (* Returns the orientation (handedness) of the tetrahedron "p q r s". Specifically, the tetrahedron "[1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]" has positive orientation. Returns 0 iff the points are coplanar. *) PROCEDURE IsInvalidLine(READONLY l: Line) : BOOLEAN; (* Returns TRUE if "p" is the invalid tuple "<0,0,0,0,0,0>" *) PROCEDURE LineFromTwoPoints(READONLY p, q: Point): Line; (* The line from "p" to "q". *) PROCEDURE PlaneFromThreePoints(READONLY p, q, r: Point): Plane; (* The plane through "p", "q", and "r". *) PROCEDURE PlaneFromLineAndPoint(READONLY n: Line; READONLY p: Point): Plane; (* The plane through "n" and "p". *) PROCEDURE PlaneOrthogToPlaneThroughLine(READONLY p: Plane; READONLY l: Line): Plane; (* The plane orthogonal to the plane "p" and passing through the line "l" where "l" is a line lying on the plane "p"; the returned plane "q" is such that "p \meet q = l". *) PROCEDURE LineFromTwoPlanes(READONLY P, Q: Plane): Line; (* The line where "P" meets "Q". *) PROCEDURE TwoPlanesByLine(READONLY l: Line; VAR p,q: Plane); (* Given a line "l", returns in the variables "p" and "q" two planes such that "p \meet q = l" *) PROCEDURE PointFromThreePlanes(READONLY P, Q, R: Plane): Point; (* The point where "P", "Q", and "R" meet. *) PROCEDURE PointFromLineAndPlane(READONLY n: Line; R: Plane): Point; (* The point where "n" meets "R". *) PROCEDURE LineDir(READONLY n: Line): Point; (* The point at infinity at the same direction that "n", i.e., $meet(n,\Omega)$ *) PROCEDURE FrontMeetOfTwoLines(READONLY n,m: Line): Point; (* The front range point where "n" and "m" meet. Works only if "n" and "m" are coplanar. *) PROCEDURE PolarComplementOfPlane(READONLY P: Plane) : Point; (* Returns the left polar complement of a plane "P", that is, the coordinates of this point are the coefficients of the plane "P". *) PROCEDURE PolarComplementOfPoint(READONLY p: Point) : Plane; (* Returns the right polar complement of a point "p", that is, the coefficients of this plane are the coordinates of the point "p". *) PROCEDURE PolarComplementOfLine(READONLY n: Line) : Line; (* Returns the right polar complement of a line "n", that is, retuns <> *) PROCEDURE Dir(READONLY frm, tto: Point): LR3.T; (* Direction (a unit-length vector) of point "tto" seen from point "frm". Works even if one of them is at infinity. Does not work if both are at infinity, or coincident, or antipodal. *) PROCEDURE AntipPoint(READONLY a: Point): Point; (* Returns the antipodal point to "a", that is, returns "-a". *) PROCEDURE OppLine(READONLY l: Line): Line; (* Returns the line opposite to "l", that is, returns "\neg l". *) PROCEDURE OppPlane(READONLY P: Plane): Plane; (* Returns the plane opposite to "P", that is, returns "\neg P". *) PROCEDURE ReflectPlaneAcrossOrg(READONLY P: Plane): Plane; (* Returns the plane "P" reflected across the origin, tha is, returns "<-P0,P1,P2,P3>". *) PROCEDURE MiddlePoint(READONLY l: Line) : Point; (* Returns the point on "l" closest to the origin of "T3" *) PROCEDURE Dist(READONLY a, b: Point): LONGREAL; (* Distance between "a" and "b", which must lie in the front half-plane. *) PROCEDURE DistSqr(READONLY a, b: Point): LONGREAL; (* Distance squared between "a" and "b", which must lie in the front half-plane. *) PROCEDURE Normal(READONLY P: Plane): LR3.T; (* The normal direction of plane "P", on the hither side, pointing into "P"'s positive halfspace. Assumes "P" is not at infinity. *) PROCEDURE SideOfSphere(READONLY p : Point) : Sign; (* Returns the relative position between the point $p$ and the sphere. Returns, -1 if the point is inside the sphere, 0 if the point belongs to the sphere e +1 if the point is outside. *) PROCEDURE SPolarOfPoint(READONLY p : Point) : Plane; (* Returns the plane which is the spherical polar of "p", that is returns "<-p0,p1,p2,p3>" *) PROCEDURE SPolarOfPlane(READONLY P : Plane) : Point; (* Returns the point which is the spherical polar of "P", that is returns "[-P0,P1,P2,P3]" *) PROCEDURE SPolarOfLine(READONLY l : Line) : Line; (* Returns the line which is the spherical polar of "l", that is returns "<-l5,l4,l3,-l2,-l1,l0>" *) PROCEDURE ArePlanesParallel(READONLY P,Q : Plane) : Sign; (* Tests if the planes "P" and "Q" are parallel and returns +1 if they are co-parallel, -1 if they contra-parallel AND 0 if they are NOT parallel. *) PROCEDURE IsLineThroughOrigin(READONLY l: Line) : BOOLEAN; (* Returns TRUE if the line "l" passes through the origin "[1,0,0,0]" *) PROCEDURE IsLineTangent(READONLY l: Line) : BOOLEAN; (* Returns TRUE if the line "l" is tangent to the sphere "S2" *) PROCEDURE IsPointOnLine(READONLY p: Point; READONLY l: Line): BOOLEAN; (* Returns TRUE if the point "p" in on line "l". *) PROCEDURE IsLineOnPlane(READONLY l: Line; P: Plane) : BOOLEAN; (* Retuns TRUE if the line "l" is on the plane "P". *) PROCEDURE AreLinesCoplanar(READONLY l,m : Line) : BOOLEAN; (* Returns TRUE if the lines "l" and "m" are coplanar. *) PROCEDURE AreLinesParallel(READONLY l,m : Line) : Sign; (* Tests if the lines "l" and "m" are parallel and returns +1 if they are co-parallel, -1 if they contra-parallel and 0 if they are NOT parallel. *) PROCEDURE AreLinesConcurrent(READONLY l,m : Line) : BOOLEAN; (* Returns TRUE if the lines "l" and "m" are coplanar and not parallel; FALSE otherwise. *) PROCEDURE Ahead2PlanesAroundLine(READONLY A,B : Plane; READONLY dl: Point) : Sign RAISES {ValidationError}; (* Given two planes "A" and "B" and the direction "dl" of the common line "l", checks whether "A" is ahead or behind "B" considering the external orientation of "l". Returns +1 if "A" is ahead "B", -1 if "A" is behind "B" and 0 if "A=B" or "A=\neg B". *) PROCEDURE CircOrdOf3PlanesAroundALine(READONLY P0,P1,P2: Plane; READONLY l: Line) : Sign RAISES {ValidationError}; (* Returns +1 if the circular order of the planes "P0","P1", "P2" around the common line "l" coincides with the external orientation of "l"; returns -1 if they are on opposite orientation to "l" and returns 0 if any two planes are equal. *) PROCEDURE CircOrdOf3PointsOnALine(READONLY p,q,r: Point; READONLY l: Line) : Sign RAISES {ValidationError}; (* Returns +1 if circular order of the points "p","q","r" coincides with the orientation of "l"; returns -1 if they are on opposite orientation to "l" and returns 0 if any two points are equal. *) END HI3.