// ****************************************************************************
//
//  $Id: cisAbstractSegment3D.h,v 1.1.1.1 2001/09/27 20:12:22 anton Exp $
//
//  Description:
//
//  Usage:
//
//  See Also:
//
//  Author(s):	Ofri Sadowsky
//  Created on: 2003-04-01
//
//
//              Developed by the Engineering Research Center for
//          Computer-Integrated Surgical Systems & Technology (CISST)
//
//               Copyright(c) 2001, The Johns Hopkins University
//                          All Rights Reserved.
//
//  Experimental Software - Not certified for clinical use.
//  For use only by CISST sponsored research projects.  For use outside of
//  CISST, please contact Dr. Russell Taylor, CISST Director, at rht@cs.jhu.edu
//  or Dr. Gabor Fichtinger, CISST Engineering Director, at gabor@cs.jhu.edu.
//  
// ****************************************************************************

#ifndef _cisAbstractSegment3D_h
#define _cisAbstractSegment3D_h


#include <cisVecs.h>
#include <cisGeomObj3DCommon.h>
#include <cisGeomObj3DExport.h>

// class cisAbstractSegment3D
// Provides an abstract base type for a segment in 3D space.
// A segment is represented by its two vertices and their order. Note that the
// segment [P1, P2] is not equal to the segment [P2, P1].
// A segment is parametrized by a value in the interval [0,1], where 0 parametrized
// P1 and 1 parametrized P2 in the segment [P1,P2]. The implementation may assert the
// parametrization range. Any point projected on the segment yields a valid 
// parametrization.
// This class is declared abstract, as the vertices of the segment may come from different
// sources. For example, the concrete Segment object may store the vertices, or
// may store references to the segments. Therefore, all operations on a cisAbstractSegment3D
// should first obtain the vertices using GetVertex(), GetVertex0(), GetVertex1(), then
// perform the computations.
class cisEXPORT cisAbstractSegment3D
{
public:
	// The type used for local parametrization of points on the line
	typedef cisScalar ParametrizationType;

	// Type of angles
	typedef double AngleType;

	// The type that represents a point on the line
	typedef cisVec3 LocalPointType;

	// The type that represents the direction of the line
	typedef cisVec3 LocalDirectionType;

	// The type that represents any point in space
	typedef cisVec3 GlobalPointType;

	// The type that represents any direction in space
	typedef cisVec3 GlobalDirectionType;

	// Type of this class
	typedef cisAbstractSegment3D SelfType;

	// declare virtual destructor for better cleanup
	virtual ~cisAbstractSegment3D()
	{}

	enum {NUM_VERTICES = 2};

	unsigned int GetNumVertices() const
	{ return NUM_VERTICES; }
	
	// Return a vertex of the segment by index
	virtual const LocalPointType & GetVertex(unsigned int index) const = 0;

	// Return the first (base) vertex of the segment
	virtual const LocalPointType & GetVertex0() const = 0;

	// Return the second (offset) vertex of the segment
	virtual const LocalPointType & GetVertex1() const = 0;


	// return the length of this segment
	cisScalar GetLength() const;
	
	// return the normalized direction vector, from Point1 to Point2 of this segment
	LocalDirectionType GetDirection() const;
	
	// return the difference vector Point2 - Point1
	LocalDirectionType GetDiffVector() const;
	
	// return the midpoint of this segment
	LocalPointType GetMidPoint() const;
	
	// evaluate the point parameterized by p: 
	// V = Point1 + p * (Point2 - Point1) == (1-p) * Point1 + p * Point2
	// Note: The current implementation asserts that p is in the interval [0,1].
	LocalPointType EvalAt(ParametrizationType p) const;

	// Return a scalar that scales the difference vector to the projection
	// of pt on this segment. The return value is bounded to the interval [0,1].
	// That is, if the orthogonal projection of pt to the segment is outside
	// the segment bounds, the return value reflects the nearest vertex.
	ParametrizationType ProjectPointLocal(const GlobalPointType & pt) const;
	
	// Return the closest point to pt which is on this segment. It may be
	// one of the vertices.
	LocalPointType ProjectPoint(const GlobalPointType & pt) const;
	
	cisScalar DistanceSquareToPoint(const GlobalPointType & pt) const;
	cisScalar DistanceToPoint(const GlobalPointType & pt) const;
	
};


#define _cisAbstractSegment3D_inl_h
#include "cisAbstractSegment3D-inl.h"
#undef _cisAbstractSegment3D_inl_h


#endif // _cisAbstractSegment3D_h

// ****************************************************************************
//                              Change History
// ****************************************************************************
//
//  $Log: cisSegment3D.h,v $
//  Revision 1.1.1.1  2001/09/27 20:12:22  anton
//  Creation of new repository for CIS 2.
//
//
//  Older:
//
//  Revision 1.2  2001/04/26 15:30:19  anton
//  Include CISGeomObjExport.hpp and added EXPORT_xxx macros
//
//  Revision 1.1  2001/03/26 19:32:05  anton
//  Import of GeomObj within CIS from Andy Bzostek code with some formating and cleaning.  Add some -inl.hpp files.
//
//
// ****************************************************************************


