#ifndef _TCGVISIONCAMERA_H_
#define _TCGVISIONCAMERA_H_

#if defined(__cplusplus)
extern "C" {
#endif

/************************************************************************************************/
/* Finds the homography matrix H[9] (3x3, described by lines) pre-allocated, from pairs of      */
/* lines (l1[i], l2[i]), so that {l2[i]} = [H]*{l1[i]}.                                         */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   nl - number of pairs of lines;                                                             */
/*   l1 - lines of the model;                                                                   */
/*   l2 - lines of the image;                                                                   */
/*  Out:                                                                                        */
/*   H - homography.                                                                            */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int tcgVisionCameraFindTransf2DLines(double *H, int nl, tcgVisionLine2D *l1, tcgVisionLine2D *l2);

/************************************************************************************************/
/* Finds the homography matrix H[9] (3x3, described by lines) pre-allocated, from pairs of      */
/* points (p1[i], p2[i]), so that {p2[i]} = [H]*{p1[i]}.                                        */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   np - number of pairs of points;                                                            */
/*   p1 - points of the model;                                                                  */
/*   p2 - points of the image;                                                                  */
/*  Out:                                                                                        */
/*   H - homography.                                                                            */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int tcgVisionCameraFindTransf2DPoints(double *H, int np, tcgVisionPoint2D *p1, tcgVisionPoint2D *p2);

/************************************************************************************************/
/* Finds the homography matrix H[12] (3x4, described by lines) pre-allocated, from pairs of     */
/* points (p1[i], p2[i]), so that {p2[i]} = [H]*{p1[i]}.                                        */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   np - number of pairs of points;                                                            */
/*   p1 - points of the model;                                                                  */
/*   p2 - points of the image;                                                                  */
/*  Out:                                                                                        */
/*   H - homography.                                                                            */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int tcgVisionCameraFindTransf3Dto2DPoints(double *H, int np, tcgVisionPoint3D *p1, tcgVisionPoint2D *p2);

/************************************************************************************************/
/* Finds the homography matrix H[9] (3x3, described by lines) pre-allocated, from pairs of      */
/* lines (l1[i], l2[i]) and pairs of points (p1[i], p2[i]), so that                             */
/* {l2[i]} = [inv(trans(H))]*{l1[i]} and {p2[i]} = [H]*{p1[i]}.                                 */
/* Função para encontrar a tranformação de homografia H[9] (3x3, descrita por linhas)           */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   nl - number of pairs of lines;                                                             */
/*   l1 - lines of the model;                                                                   */
/*   l2 - lines of the image;                                                                   */
/*   np - number of pairs of points;                                                            */
/*   p1 - points of the model;                                                                  */
/*   p2 - points of the image;                                                                  */
/*  Out:                                                                                        */
/*   H - homography.                                                                            */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int tcgVisionCameraFindTransf2D(double *H, int nl, tcgVisionLine2D *l1, tcgVisionLine2D *l2, int np, tcgVisionPoint2D *p1, tcgVisionPoint2D *p2);

/************************************************************************************************/
/* Convert the transformation of lines into transformation of points and vice-versa.            */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   h1 - homography (lines or points);                                                         */
/*  Out:                                                                                        */
/*   h2 - homography (points or lines);                                                         */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int tcgVisionCameraTransfConvert_LinesPoints(double h1[9], double h2[9]);

/************************************************************************************************/
/* Transforms p1 in p2 by H.                                                                    */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   H - homography (points);                                                                   */
/*   p1 - point to be transformed.                                                              */
/*  Out:                                                                                        */
/*   p2 - transformed point.                                                                    */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int  tcgVisionCameraTransfPoint(double *H, tcgVisionPoint2D p1, tcgVisionPoint2D *p2);

/************************************************************************************************/
/* Transforms 'a.x + b.y + c = 0' in 'A.x + B.y + C = 0' by H.                                  */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   H - homography (lines);                                                                    */
/*   a, b, c - coefficients of the line.                                                        */
/*  Out:                                                                                        */
/*   A, B, C - coefficients of the line.                                                        */
/************************************************************************************************/
void tcgVisionCameraTransfLine(double *H, double a, double b, double c, double *A, double *B, double *C);

/************************************************************************************************/
/* Finds new pairs of points according to pairs of original points.                             */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   minx, miny, maxx, maxy - bounding-box of the points of the model;                          */
/*   width - width of the image in pixels;                                                      */
/*   height - height of the image in pixels;                                                    */
/*   clip - Indicated if wants adjust the points inside the image only;                         */
/*   H - homography (points);                                                                   */
/*   npnx - number of pairs of new points in the direction x of the model (Max. 10);            */
/*   npny - number of pairs of new points in the direction y of the model (Max. 10).            */
/*  Out:                                                                                        */
/*   p1n - new points of the world;                                                             */
/*   p2n - new points in coordinates of the screen in pixel.                                    */
/* Returns the number of new points.                                                            */
/************************************************************************************************/
int tcgVisionCameraBuildNewData(double minx, double miny, double maxx, double maxy, int width, int height, 
                                int clip, double *H, int npnx, int npny, tcgVisionPoint2D *p1n, tcgVisionPoint2D *p2n);

/************************************************************************************************/
/* Finds the camera according to the pairs of points, through the method described in           */
/* "Image-based Modeling Using a Two-step Camera Calibration Method" (SIBGRAPI'98).             */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   nl - number of lines;                                                                      */
/*   lm - lines of the real world;                                                              */
/*   lt - lines of the screen.                                                                  */
/*   np - number of points;                                                                     */
/*   p3d - points of the real world;                                                            */
/*   p2d - points of the screen.                                                                */
/*  Out:                                                                                        */
/*   Q1 - matrix of the first step of the method;                                               */
/*   Q2 - matrix of the second step of the method;                                              */
/*   pobs - camera position;                                                                    */
/*   pref - reference point;                                                                    */
/*   vup - up vector.                                                                           */
/* The function returns 1 if ok case and 0 otherwise.                                           */
/************************************************************************************************/
int tcgVisionCameraCalibration (int nl, tcgVisionLine2D *lm, tcgVisionLine2D *lt, int np, tcgVisionPoint3D *p3d, tcgVisionPoint2D *p2d,
                                double Q1[3][4], double Q2[3][4],
                                tcgVisionPoint3D *pobs, tcgVisionPoint3D *pref, tcgVisionPoint3D *vup);

/************************************************************************************************/
/* Find the angle of vision of the camera.                                                      */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   img_height - height of the image;                                                          */
/*   Q - matrix resultant of the method tcgVisionCameraCalibration;                              */
/*   pobs - camera position;                                                                    */
/*   pref - reference point;                                                                    */
/************************************************************************************************/
double tcgVisionCameraFindVisionAngle(int img_height, double Q[3][4], tcgVisionPoint3D pobs, tcgVisionPoint3D vref);

/************************************************************************************************/
/* Projects by the transformation given by transformation matrix Q the point pm in pc.          */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   Q - matrix resultant of the method tcgVisionCameraCalibration;                             */
/*   pm - point of the real world.                                                              */
/*  Out:                                                                                        */
/*   pc - point calculated in the world screen.                                                 */
/************************************************************************************************/
void tcgVisionCameraProject (double Q[3][4], tcgVisionPoint3D pm, tcgVisionPoint2D *pc);

/************************************************************************************************/
/* Find the point in the real world (3D) with coordinate z equal to  0 that is projected in pt  */
/* in the screen.                                                                               */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   Q - matrix resultant of the method tcgVisionCameraCalibration;                             */
/*   pt - point of the screen.                                                                  */
/*  Out:                                                                                        */
/*   pc - point calculated in the real world.                                                   */
/************************************************************************************************/
void tcgVisionCameraUnproject (double Q[3][4], tcgVisionPoint2D pt, tcgVisionPoint3D *pc);

/************************************************************************************************/
/* Find the point in the real world (3D) that is projected in pt1, and its coordinates 'x' and  */
/* 'y' are the coordinates of the point that is projected in pt2. The point is approached.      */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   Q - matrix resultant of the method tcgVisionCameraCalibration;                             */
/*   pt1 - first point of the screen.                                                           */
/*   pt2 - second point of the screen.                                                          */
/*  Out:                                                                                        */
/*   pc - point calculated in the real world.                                                   */
/************************************************************************************************/
void tcgVisionCameraUnprojectAir (double Q[3][4], tcgVisionPoint2D pt1, tcgVisionPoint2D pt2, tcgVisionPoint3D *pc);

/************************************************************************************************/
/* Find the point in the real world (3D) with coordinate z given that is projected in pt in the */
/* screen.                                                                                      */
/* Parameters:                                                                                  */
/*  In:                                                                                         */
/*   Q - matrix resultant of the method tcgVisionCameraCalibration;                             */
/*   pt - point of the screen.                                                                  */
/*   z - given height.                                                                          */
/*  Out:                                                                                        */
/*   pc - point calculated in the real world.                                                   */
/************************************************************************************************/
void tcgVisionCameraUnprojectAirZ (double Q[3][4], tcgVisionPoint2D pt, double z, tcgVisionPoint3D *pc);

#if defined(__cplusplus)
}
#endif

#endif
