/******************************************************************************
* Bsc_Geom.c - Basic geometry interface.				      *
*******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                 *
*******************************************************************************
* Written by Gershon Elber, March 1990.					      *
******************************************************************************/

#include <math.h>
#include <stdio.h>
#include "program.h"
#include "iritprsr.h"
#include "allocate.h"
#include "geomat3d.h"
#include "bsc_geom.h"

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to compute the distance between two 3d points.         M
*                                                                            *
* PARAMETERS:                                                                M
*   P1, P2:   Two points to compute the distance between.                    M
*                                                                            *
* RETURN VALUE:                                                              M
*   double:    Computed distance.                                            M
*									     M
* SEE ALSO:                                                                  M
*   CGDistPointPoint                                                         M
*                                                                            *
* KEYWORDS:                                                                  M
*   DistPointPoint, point point distance                                     M
*****************************************************************************/
double DistPointPoint(PointType P1, PointType P2)
{
    return CGDistPointPoint(P1, P2);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to construct the plane from given 3 points. If two of  M
* the points are the same it returns FALSE, otherwise (successful) returns   M
* TRUE.									     M
*                                                                            *
* PARAMETERS:                                                                M
*   Pt1, Pt2, Pt3:  Three points to fit a plane through.                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct:     The Plane, or NULL if invalid.			     M
*									     M
* SEE ALSO:                                                                  M
*   CGPlaneFrom3Points                                                       M
*                                                                            *
* KEYWORDS:                                                                  M
*   PlaneFrom3Points, plane                                                  M
*****************************************************************************/
IPObjectStruct *PlaneFrom3Points(PointType Pt1, PointType Pt2, PointType Pt3)
{
    PlaneType Plane;

    if (CGPlaneFrom3Points(Plane, Pt1, Pt2, Pt3))
        return GenPLANEObject(&Plane[0], &Plane[1], &Plane[2], &Plane[3]);
    else
	return NULL;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to compute the closest point on a given 3d line to a   M
* given 3d point. the line is prescribed using a point on it (Pl) and vector M
* (Vl).									     M
*                                                                            *
* PARAMETERS:                                                                M
*   Point:         To find the closest to on the line.                       M
*   Pl, Vl:        Position and direction that defines the line.             M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *:  The closest point.				     M
*									     M
* SEE ALSO:                                                                  M
*   CGPointFromPointLine                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   PointFromPointLine, point line distance                                  M
*****************************************************************************/
IPObjectStruct *PointFromPointLine(PointType Point, PointType Pl, PointType Vl)
{
    PointType ClosestPt;

    CGPointFromPointLine(Point, Pl, Vl, ClosestPt);

    return GenPTObject(&ClosestPt[0], &ClosestPt[1], &ClosestPt[2]);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to compute the disstance between a 3d point and a 3d   M
* line.									     M
*   The line is prescribed using a point on it (Pl) and vector (Vl).         M
*                                                                            *
* PARAMETERS:                                                                M
*   Point:         To find the distance to on the line.                      M
*   Pl, Vl:        Position and direction that defines the line.             M
*                                                                            *
* RETURN VALUE:                                                              M
*   double:        The computed distance.                                    M
*									     M
* SEE ALSO:                                                                  M
*   CGDistPointLine                                                          M
*                                                                            *
* KEYWORDS:                                                                  M
*   DistPointLine, point line distance                                       M
*****************************************************************************/
double DistPointLine(PointType Point, PointType Pl, PointType Vl)
{
    return CGDistPointLine(Point, Pl, Vl);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to compute the distance between a Point and a Plane.   M
* The Plane is prescribed using its four coefficients : Ax + By + Cz + D = 0 M
* given as four elements vector.					     M
*                                                                            *
* PARAMETERS:                                                                M
*   Point:         To find the distance to on the plane.                     M
*   Plane:         To find the distance to on the point.                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   double:        The computed distance.                                    M
*									     M
* SEE ALSO:                                                                  M
*   CGDistPointPlane                                                         M
*                                                                            *
* KEYWORDS:                                                                  M
*   DistPointPlane, point plane distance                                     M
*****************************************************************************/
double DistPointPlane(PointType Point, PlaneType Plane)
{
    return CGDistPointPlane(Point, Plane);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to find the intersection point of a line and a plane   M
* (if any). 								     M
*   The Plane is prescribed using four coefficients : Ax + By + Cz + D = 0   M
* given as four elements vector. The line is define via a point on it Pl and M
* a direction vector Vl. Returns TRUE only if such point exists.             M
*                                                                            *
* PARAMETERS:                                                                M
*   Pl, Vl:        Position and direction that defines the line.             M
*   Plane:         To find the intersection with the line.                   M
*   InterPoint:    Where the intersection occured.                           M
*   t:             Parameter along the line of the intersection location     M
*                  (as Pl + Vl * t).                                         M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *:  The intersection point, or NULL if none.              M
*									     M
* SEE ALSO:                                                                  M
*   CGPointFromLinePlane                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   PointFromLinePlane, line plane intersection                              M
*****************************************************************************/
IPObjectStruct *PointFromLinePlane(PointType Pl, PointType Vl, PlaneType Plane)
{
    RealType t;
    PointType InterPoint;

    if (CGPointFromLinePlane(Pl, Vl, Plane, InterPoint, &t))
        return GenPTObject(&InterPoint[0], &InterPoint[1], &InterPoint[2]);
    else
        return NULL;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to find the two points Pti on the lines (Pli, Vli) ,   M
*   i = 1, 2 with the minimal Euclidian distance between them. In other      M
* words, the distance between Pt1 and Pt2 is defined as distance between the M
* two lines.								     M
*   The two points are calculated using the fact that if V = (Vl1 cross Vl2) M
* then these two points are the intersection point between the following:    M
* Point 1 - a plane (defined by V and line1) and the line line2.             M
* Point 2 - a plane (defined by V and line2) and the line line1.             M
*   This function returns TRUE iff the two lines are not parallel!           M
*                                                                            M
* PARAMETERS:                                                                M
*   Pl1, Vl1:  Position and direction defining the first line.               M
*   Pl2, Vl2:  Position and direction defining the second line.              M
*   Pt1:       Point on Pt1 that is closest to line 2.                       M
*   t1:        Parameter value of Pt1 as (Pl1 + Vl1 * t1).                   M
*   Pt2:       Point on Pt2 that is closest to line 1.                       M
*   t2:        Parameter value of Pt2 as (Pl2 + Vl2 * t2).                   M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *:     List of two closest points, NULL if none.	     M
*									     M
* SEE ALSO:                                                                  M
*   CG2PointsFromLineLine                                                    M
*                                                                            *
* KEYWORDS:                                                                  M
*   2PointsFromLineLine, line line distance                                  M
*****************************************************************************/
IPObjectStruct *TwoPointsFromLineLine(PointType Pl1,
				      PointType Vl1,
				      PointType Pl2,
				      PointType Vl2)
{
    PointType Pt1, Pt2;
    RealType t1, t2;

    if (CG2PointsFromLineLine(Pl1, Vl1, Pl2, Vl2, Pt1, &t1, Pt2, &t2)) {
	IPObjectStruct
	    *PObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);

	ListObjectInsert(PObj, 0, GenPTObject(&Pt1[0], &Pt1[1], &Pt1[2]));
	ListObjectInsert(PObj, 1, GenPTObject(&Pt2[0], &Pt2[1], &Pt2[2]));
	ListObjectInsert(PObj, 2, NULL);
	return PObj;
    }
    else
        return NULL;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface routine to find the distance between two lines (Pli, Vli) ,    M
* i = 1, 2.								     M
*                                                                            *
* PARAMETERS:                                                                M
*   Pl1, Vl1:  Position and direction defining the first line.               M
*   Pl2, Vl2:  Position and direction defining the second line.              M
*                                                                            *
* RETURN VALUE:                                                              M
*   double:   Distance between the two lines.		                     M
*									     M
* SEE ALSO:                                                                  M
*   CGDistLineLine                                                           M
*                                                                            *
* KEYWORDS:                                                                  M
*   DistLineLine, line line distance                                         M
*****************************************************************************/
double DistLineLine(PointType Pl1, PointType Vl1, PointType Pl2, PointType Vl2)
{
    return CGDistLineLine(Pl1, Vl1, Pl2, Vl2);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Interface to compute the Barycentric coordinates of given point Pt with  M
* respect to given Trainagle Pt1 Pt2 Pt3. All points are assumed to be	     M
* coplanar.								     M
*                                                                            *
* PARAMETERS:                                                                M
*   Pt1, Pt2, Pt3:   Three points forming a triangular in general position.  M
*   Pt:		     A point for which the barycentric coordinates are to be M
*		     computed.						     M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *: A vector holding the three Barycentric		     M
*	coefficients, or NULL if point Pt is outside the triangle	     M
*	Pt1 Pt2 Pt3.							     M
*									     M
* SEE ALSO:                                                                  M
*   CGBaryCentric3Pts                                                        M
*                                                                            *
* KEYWORDS:                                                                  M
*   BaryCentric3Pts				                             M
*****************************************************************************/
IPObjectStruct *BaryCentric3Pts(PointType Pt1,
				PointType Pt2,
				PointType Pt3,
				PointType Pt)
{
    RealType *V;

    if ((V = CGBaryCentric3Pts(Pt1, Pt2, Pt3, Pt)) != NULL)
        return GenPTObject(&V[0], &V[1], &V[2]);
    else
        return NULL;
}
