@chapsummary
This library provides geometric primitive entities, like points and
lines and planes.  The goal is to provide very lightweight structures
than are just slightly more costly than matrices or vectors.  At the
same time these classes can support all the routine geometric
computations that are needed in basic computer vision operations.  The
idea is that more complex spatial objects would use the vgl operations
to carry out basic geometric computations without duplicating
operations like line intersection.
@endchapsummary

@section Geometric primitives
The core geometry library @code{vgl} is intended to provide an environment for
geometric primitives, both in Cartesian and homogeneous representations, and
for both 2D and 3D.

This includes classes for
@itemize @bullet
@item Points, lines and planes.
@item Direction vectors.
@item 2D conics and 3D spheres, cones, cylinders and ellipsoids.
@item Rectangular, axes-parallel bounding boxes (2D and 3D).
@item Polygons.
@item Region scan iterators.
@end itemize

In addition, the @code{vgl/algo} library contains functions to perform elementary
geometric operations like intersecting a bundle of planes, finding the nearest
point on a line or a conic, computing the cross ratio of four points or lines, ...
For convenience, most of this functionality is put in a "name space", separate
for 2D and 3D, and separate for Cartesian and homogeneous representations.
Some of the most elementary operations like distance calculations and simple
intersections are implemented in the @code{vgl} library, often through class
methods.

All representation classes are templated on the computational numeric type,
typically @code{double} or @code{float}, but it could make sense to use other
types like @code{int} (especially with homogeneous representations) or e.g.
@code{vnl_rational} or @code{vcl_complex<double>}.

@subsection Homogeneous 2D classes and operations
The most general geometric framework is based on projective geometry
and homogeneous coordinates.  Projective operations arise in the
analysis of image geometry and its relationship to the world geometry
projected into the image by perspective cameras.

The basic 2D classes using homogeneous (3-argument) representations are:

@itemize @bullet
@item @code{vgl_homg_point_2d<T>}
@item @code{vgl_homg_line_2d<T>}
@item @code{vgl_conic<T>}
@end itemize
Some useful functions can be found in @code{vgl_intersection.h}, @code{vgl_distance.h} and @code{vgl_closest_point.h}, like e.g.:
@itemize @bullet
@item @code{bool vgl_intersection(vgl_line_2d<T> const& line0, vgl_line_2d<T> const& l2, vgl_point_2d<T> & pt)}
@item @code{vgl_point_3d<T> vgl_intersection(vgl_line_3d_2_points<T> const& l1, vgl_line_3d_2_points<T> const& l2)}
@item @code{double vgl_distance(vgl_homg_point_2d<T> const& p1, vgl_homg_point_2d<T> const& p2)}
@item @code{double vgl_distance(vgl_homg_point_2d<T> const& p, vgl_homg_line_2d<T> const& l)}
@item @code{vgl_homg_point_2d<T> vgl_closest_point(vgl_homg_line_2d<T> const& l, vgl_homg_point_2d<T> const& p)}
@end itemize
Some of the most useful static functions in namespace @code{vgl_homg_operators_2d<T>} are:
@itemize @bullet
@item @code{double distance_squared(vgl_homg_point_2d<T> const& point1, vgl_homg_point_2d<T> const& point2)}
@item @code{vgl_homg_line_2d<T> join(vgl_homg_point_2d<T> const& point1, vgl_homg_point_2d<T> const& point2)}
   to get the line through two points.
@item @code{vgl_homg_point_2d<T> intersection(vgl_homg_line_2d<T> const& line1, vgl_homg_line_2d<T> const& line2)}
   to get the intersection point of two lines.
@item @code{void unitize(vgl_homg_point_2d<T> &a)}
   to normalize a point representation (3-tuple) to unit magnitude.
@item @code{double cross_ratio(vgl_homg_point_2d<T> const& p1, vgl_homg_point_2d<T> const& p2,
                               vgl_homg_point_2d<T> const& p3, vgl_homg_point_2d<T> const& p4)}
@item @code{double angle_between_oriented_lines(vgl_homg_line_2d<T> const& line1, vgl_homg_line_2d<T> const& line2)}
    Return the angle between the (oriented) lines (in radians).
@item @code{double perp_distance_squared(vgl_homg_line_2d<T> const& line, vgl_homg_point_2d<T> const& point)}
@item @code{vgl_homg_line_2d<T> perp_line_through_point(vgl_homg_line_2d<T> const& line, vgl_homg_point_2d<T> const& point)}
@item @code{vgl_homg_point_2d<T> perp_projection(vgl_homg_line_2d<T> const& line, vgl_homg_point_2d<T> const& point)}
@item @code{vgl_homg_point_2d<T> midpoint(vgl_homg_point_2d<T> const& p1, vgl_homg_point_2d<T> const& p2)}
@item @code{vgl_homg_point_2d<T> lines_to_point(vcl_list<vgl_homg_line_2d<T> > const& lines)}
   to intersect a set of 2D lines to find the least-square point of intersection.
@item @code{vcl_list<vgl_homg_point_2d<T> > intersection(vgl_conic<T> const &c, vgl_homg_line_2d<T> const &l)}
   to find all real intersection points of a conic and a line (between 0 and 2).
@item @code{vcl_list<vgl_homg_point_2d<T> > intersection(vgl_conic<T> const &c1, vgl_conic<T> const &c2)}
   to find all real intersection points of two conics (between 0 and 4).
@item @code{vcl_list<vgl_homg_line_2d<T> > tangent_from(vgl_conic<T> const &c, vgl_homg_point_2d<T> const &p)}
   returns the (at most) two tangent lines that pass through p and are tangent to the conic.
@item @code{vgl_homg_point_2d<T> closest_point(vgl_conic<T> const& c, vgl_homg_point_2d<T> const& p)}
   returns the point on the conic closest to the given point.
@end itemize

Homogeneous projective geometry can be converted to standard Euclidean or Cartesian coordinates
by normalizing by the third homogeneous coordinate.  In general there will be need to convert back
and forth between the two geometries to carry out operations efficiently.  For example intersection
of lines in homogeneous coordinates can be carried out simply using the cross-product of vectors.

@subsection Cartesian (Euclidean) 2D classes

The basic 2D classes using non-homogeneous (2-argument) representations are:

@itemize @bullet
@item @code{vgl_point_2d<T>}
@item @code{vgl_vector_2d<T>}
@item @code{vgl_line_2d<T>}
@item @code{vgl_box_2d<T>}
@end itemize

A vector is a directional difference between two points, i.e., something having a direction and a length.

A box is a rectangular bounding box, represented by two corner points: the "min" and the "max" coordinate points.
All points inside the box have x coordinates between min-x and max-x, and y coordinates between min-y and max-y.

There are also two ``composite'' 2D curve objects:

@itemize @bullet
@item @code{vgl_line_segment_2d<T>}
@item @code{vgl_conic_segment_2d<T>}
@end itemize

A line segment is a bounded part of a line, between two end points.

A conic segment is built on a @code{vgl_conic<T>} and two end points.
This curve only consists of those points of the conic between the two given end points.
(See the detailed documentation of this class for a precise definition of "between".)

@subsection Homogeneous 3D classes and operations

The basic 3D classes using homogeneous (4-argument) representations are:

@itemize @bullet
@item @code{vgl_homg_point_3d<T>}
@item @code{vgl_homg_plane_3d<T>}
@item @code{vgl_homg_line_3d_2_points<T>}
@end itemize
Some useful functions can be found in @code{vgl_distance.h} and @code{vgl_closest_point.h}:
@itemize @bullet
@item @code{double vgl_distance(vgl_homg_point_3d<T> const& p1, vgl_homg_point_3d<T> const& p2)}
@item @code{double vgl_distance(vgl_homg_plane_3d<T> const& p1, vgl_homg_point_3d<T> const& p2)}
@item @code{double vgl_distance(vgl_homg_line_3d_2_points<T> const& p1, vgl_homg_point_3d<T> const& p2)}
@item @code{double vgl_distance(vgl_homg_line_3d_2_points<T> const& p1, vgl_homg_line_3d_2_points<T> const& p2)}
@item @code{vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_plane_3d<T> const& l, vgl_homg_point_3d<T> const& p)}
@item @code{vgl_homg_point_3d<T> vgl_closest_point(vgl_homg_line_3d_2_points<T> const& l, vgl_homg_point_3d<T> const& p)}
@item @code{std::pair<vgl_homg_point_3d<T>,vgl_homg_point_3d<T> > vgl_closest_points(vgl_homg_line_3d_2_points<T> const& l1,
                                                                                     vgl_homg_line_3d_2_points<T> const& l2)}
@end itemize
The most useful static functions in namespace @code{vgl_homg_operators_3d<T>} are:
@itemize @bullet
@item @code{T distance(vgl_homg_point_3d<T> const& point1, vgl_homg_point_3d<T> const& point2)}
@item @code{T distance_squared(vgl_homg_point_3d<T> const& point1, vgl_homg_point_3d<T> const& point2)}
@item @code{double perp_distance_squared(vgl_homg_line_3d const& line, vgl_homg_point_3d<T> const& point)}
@item @code{vgl_homg_point_3d<T> intersect_line_and_plane(vgl_homg_line_3d const& , vgl_homg_plane_3d<T> const& )}
    Return the intersection point of the line and plane.
@item @code{vgl_homg_point_3d<T> perp_projection(vgl_homg_line_3d const& line, vgl_homg_point_3d<T> const& point)}
    Compute the perpendicular projection point of p onto l.
@item @code{double angle_between_oriented_lines(vgl_homg_line_3d const& line1, vgl_homg_line_3d const& line2)}
    Return the angle between the (oriented) lines (in radians).
@item @code{vgl_homg_point_3d<T> lines_to_point(vcl_vector<vgl_homg_line_3d> const& line_list)}
@item @code{vgl_homg_line_3d points_to_line(vcl_vector<vgl_homg_point_3d<T> > const& point_list)}
@item @code{vgl_homg_line_3d planes_to_line(vcl_vector<vgl_homg_plane_3d<T> > const& plane_list)}
    Return the intersection line of the planes.
@item @code{vgl_homg_plane_3d<T> points_to_plane(vcl_vector<vgl_homg_point_3d<T> > const& point_list)}
@item @code{vgl_homg_point_3d<T> intersection_point(vcl_vector<vgl_homg_plane_3d<T> > const& ) double }
    Compute best-fit intersection of planes in a point.
@end itemize

@subsection Cartesian 3D classes

The basic 3D classes using non-homogeneous (3-argument) representations are:

@itemize @bullet
@item @code{vgl_point_3d<T>}
@item @code{vgl_vector_3d<T>}
@item @code{vgl_plane_3d<T>}
@item @code{vgl_box_3d<T>}
@end itemize

``Non-basic'' 3D classes, i.e. those built from the basic ones, include:

@itemize @bullet
@item @code{vgl_line_segment_3d<T>}
@item @code{vgl_line_3d_2_points<T>}
@item @code{vgl_sphere_3d<T>}
@end itemize

@subsection Homogeneous 1D classes

For sake of completeness, the following 1D representation classes are present:
@itemize @bullet
@item @code{vgl_homg_point_1d<T>}
@item @code{vgl_1d_basis<T>}
@end itemize

A 1D basis is an arbitrary set of 3 (collinear) points.  One receives coordinate
0 or (0,1), one has coordinate infinity or (1,0) and the unit point has
coordinate 1 or (1,1).  Such a set is an essential ingredient for any projective
transformation.

@section 2D regions and iterators

The @code{vgl_polygon<T>} class represents a more complex region or area in 2D space.
The @code{vgl_region_scan_iterator} class allows for iterating through regions.
More specifically, the derived classes @code{vgl_polygon_scan_iterator<T>},
@code{vgl_triangle_scan_iterator<T>}, @code{vgl_ellipse_scan_iterator<T>} and
@code{vgl_window_scan_iterator<T>} can be used to iterate over the points of a
discrete grid that are interior to the region.
The general case for the polygon scan is shown in Figure 1.
@figure
@image{polygon-scan,,3in}
@caption{1}
The general situation for a polygon scan iterator.  The polygon defines a set of
discrete scan lines which are bounded by the polygon or by an optional clipping window.
@endcaption
@endfigure
The scan is initiated by calling @code{::reset()}.  The boolean method @code{::next()}
then iterates over the spans until all spans have been produced.  When no more spans
are available @code{::next()} returns false.
Thus an iteration over the interior of the polygon is executed as:
@example
...
vgl_polygon<double> my_polygon;
...
// do something to define the polygon
...
vgl_polygon_scan_iterator<double> psi(mypolygon);
psi.set_include_boundary(true); // optional flag, default is true
for (psi.reset(); psi.next(); ) @{
  int y = psi.scany();
  for (int x = psi.startx(); x <= psi.endx(); ++x)
    ....
    // do something with x and y, e.g. compute the center of gravity of
    // the interior points.
@}
@end example
The @code{vgl_polygon_scan_iterator<T>} also supports the specification
of an optional clipping window.  The window is intersected with the polygon
to define scan region as shown in Figure 1.  The window is specified by
an alternative constructor:
@example
vgl_polygon_scan_iterator<float>(vgl_polygon<float> const& face, bool boundaryp,
                                 vgl_box_2d<float> const& window)
@end example
Note that the boundaryp flag is defined to determine if points on the boundary
of the polygon or window are to be included in the scan.

The area of a polygon can be determined with the @code{vgl_area} function.

@section Projective transformations
One of the goals of vgl is to support the basic operations of
projective geometry.  This goal inevitably entails the use of
projective transformations which are typically represented as square
matrices of dimension n+1, where n is the dimension of the geometric
space in which a point set is embedded.  Because of the strict rules of
core libraries, vgl is not permitted to require other core libraries
in order to carry out its operations.  At the same time there is no
justification to re-invent a numerical library within vxl simply to
avoid library cross-linking.  The solution is to define a @code{vgl/algo}
library that can link to vnl and thus make use of the necessary vnl
functions.  A user can cleanly link to very basic vgl classes without
including vnl, but the full operations of projective geometry will
require the use of vnl matrix algorithms.
@figure
@image{homography,,2in}
@caption{2}
The mapping of points from one projective plane to another.  The transformation can be represented by a 3x3 matrix.
@endcaption
@endfigure
@subsection 2-d projective transformations
Much of the discussion here will center on the projective plane (2-d
points and lines) but a partial set of operations are available for
both 1-d and 3-d geometry.  The basic operation is to transform a point
or line, and in the projective plane this corresponds to multiplying
the vector of corresponding homogeneous coordinates by a 3x3
transformation matrix.  This basic operation is illustrated in Figure
2.  The projective transformation between planes is often called a
planar homography, thus the symbol h, or H, is used to represent transformations.

The class @code{vgl_h_matrix_2d<T>} defines the basic operations of a planar homography.
Points and lines are transformed by the operator @code{()} or the @code{*} operator as for example,
@example
...
vnl_matrix_fixed <double, 3,3> M;
...
//define M somehow
...
vgl_h_matrix_2d <double> H(M);
vgl_homg_point_2d<double> X(1.0, 0.0, 1.0), x1, x2;
x1 = H(X);
x2 = H*X;
...

@end example
and x1 ~ x2, where ~ indicates that the two points are projectively
equivalent.  That is, their three homogeneous coordinates are within a
scale factor of each other.

The method @code{preimage} effects the
inverse transformation.  So continuing with our example,
@example
...
vgl_homg_point_2d <double> Xpre;
Xpre = H.preimage(x1);
..
@end example
and X ~ Xpre.  This operation is carried out by inverting the forward transformation matrix.

The process is similar for lines, but it should be noted that the
transformation for lines requires a different matrix then that for
points.  It can be shown that,

H_line = (H_point)^-t

where ^-t indicates the transpose of the inverse of a matrix.  Thus,
the forward transformation of a line from plane 1 to plane 2 requires
a matrix inverse.  On the other hand, the pre-image operation is
easier, only requiring a matrix transpose.

The ambiguity as to whether an @code{vgl_h_matrix_2d<T>} is a point
mapping or a line mapping is avoided by the convention that the class
only refers to point mappings.  The matrix inverse could be cached to
avoid extra computation, but currently it is not, since there hasn't
been performance issues to motivate the extra machinery.  Still, the
user should be aware that inversion is occurring on every forward line
transformation.

@subsection 3-d projective transformations
@code{vgl/algo} also provides a basic capability for carrying out 3-d
to 3-d projective transformations, based on a 4x4 linear matrix
multiplication.  The most common application is to implement Euclidean
transformations (rotation and translation) in a unified, compact framework.
For example the following code defines a Euclidean transformation
based on a given axis of rotation:
@example
vgl_h_matrix_3d <double> Hrot, Htrans, H;

//Setup the rotation transformation
vnl_vector_fixed<double, 3> axis(0.0,0.0,1.0);//The z axis
double angle = vnl_math::pi/4.0;//45 degree rotation
Hrot.set_rotation_about_axis(axis, angle);

//Set up the translation transformation
Htrans.set_translation(1.0, 2.0, 3.0);

//compose the two.  The rotation is applied first and then the translation
H = Htrans*Hrot;
...
// Transform a 3-d homogeneous point
vgl_homg_point_3d<double> X(1.0, 0.0, 0.0, 1.0), x;
x = H(X);
//
//The resulting transformed point
// x = (1.707, 2.707, 3.0, 1.0)
@end example
In 3-d projective space, points and planes hold the same dual relationship as points and lines do
in 2-d projective space.  In 3-d, planes are transformed by H^-t, where H is a 3-d projective transformation on points.

Lines in 3-d are considerably more complicated than points and
planes.  The representation called Plucker coordinates which allows
computations involving lines to be carried out using matrix and vector
operations.  It is planned to introduce Plucker geometry into @code{vgl/algo}
when the need arises.

@section Computing 2-d projective transformations
A standard coordinate frame is defined in projective geometry, called the
@emph{projective basis}.  The basis is constructed from four points and in the
coordinate frame of the basis these points have coordinates as follows:
@example
   p[0] p[1] p[2] p[3]
    1    0    0    1
    0    1    0    1
    0    0    1    1
@end example
Note that the first two points are @emph{points at infinity}, or
@emph{ideal} points that indicate the direction of the x and y
coordinate axes.  The third point is the origin and the last point is
called the @emph{unit} point and is at Euclidean coordinates (1,1).
The method @code{bool projective_basis(vcl_vector<vgl_homg_point_2d<T> > const & four_points)}
sets the transformation so as to map points from their projective plane to the plane defined by the canonical basis.


The more general case is based on classes that compute a plane projective
transformations based on sets of corresponding points or lines.  For example,
@example

vgl_h_matrix_2d_compute_linear hcl;
vcl_vector <vgl_homg_point_2d <double> > point_set1, point_set2;
...
//fill these two vectors with corresponding points
//taken from two projective planes,
//e.g. a world plane and the image plane.
//
vgl_h_matrix_2d <double> H = hcl.compute(point_set1, point_set2);
// H represents the homography that
// transforms points from plane1 into plane2.

@end example

This functionality is very useful in tracking planar surfaces in images and
in the calibration of perspective cameras.  Currently, only linear
algorithms are available for finding the homography that best fits the
mapping between two sets of corresponding points or two sets of
corresponding lines.  It is planned to add
non-linear compute methods, such as Levenberg-Marquardt.

