/*-------------------------------------------------------------------------*
	* Coord                                                                   *
	*                                                                         *
	* Compute the two coordinates (x1,x2) corresponding to a point in the     *
	* spherical triangle.  This is the inverse of "Chart".                    *
	*                                                                         *
	*-------------------------------------------------------------------------*/
	Vec2 SphericalTriangle::Coord( const Vec3 &P1 ) const
	{
		Vec3 P = Unit( P1 );

		// Compute the new C vertex, which lies on the arc defined by B-P
		// and the arc defined by A-C.

		Vec3 C_new = Unit( ( B() ^ P ) ^ ( C() ^ A() ) );

		// Adjust the sign of C_new.  Make sure it's on the arc between A and C.

		if( C_new * ( A() + C() ) < 0.0 ) C_new = -C_new;

		// Compute x1, the area of the sub-triangle over the original area.

		float cos_beta  = CosDihedralAngle( A(), B(), C_new  );
		float cos_gamma = CosDihedralAngle( A(), C_new , B() );
		float sub_area  = Alpha() + acos( cos_beta ) + acos( cos_gamma ) - Pi;
		float x1        = sub_area / SolidAngle();

		// Now compute the second coordinate using the new C vertex.

		float z  = P * B();
		float x2 = ( 1.0 - z ) / ( 1.0 - C_new * B() );

		if( x1 < 0.0 ) x1 = 0.0;  if( x1 > 1.0 ) x1 = 1.0;
		if( x2 < 0.0 ) x2 = 0.0;  if( x2 > 1.0 ) x2 = 1.0;
		return Vec2( x1, x2 );
	}
/*-------------------------------------------------------------------------*
 * Init                                                                    *
 *                                                                         *
 * Construct the spherical triange from three vertices.  Assume that the   *
 * sphere is centered at the origin.  The vectors A, B, and C need not     *
 * be normalized.                                                          *
 *                                                                         *
 *-------------------------------------------------------------------------*/
    void SphericalTriangle::Init( 
        const Vector3d &A0, const Vector3d &B0, const Vector3d &C0 
    )
    {
        // Normalize the three vectors -- these are the vertices.

        A_ = Unit( A0 ) ;
        B_ = Unit( B0 ) ;
        C_ = Unit( C0 ) ;

        // Compute and save the cosines of the edge lengths.

        cos_a = B_ * C_;
        cos_b = A_ * C_;
        cos_c = A_ * B_;

        // Compute and save the edge lengths.

        a_ = ArcCos( cos_a );
        b_ = ArcCos( cos_b );
        c_ = ArcCos( cos_c );

        // Compute the cosines of the internal (i.e. dihedral) angles.

        cos_alpha = CosDihedralAngle( C_, A_, B_ );
        cos_beta  = CosDihedralAngle( A_, B_, C_ );
        cos_gamma = CosDihedralAngle( A_, C_, B_ );

        // Compute the (dihedral) angles.

        alpha = ArcCos( cos_alpha );
        beta  = ArcCos( cos_beta  );
        gamma = ArcCos( cos_gamma );

        // Compute the solid angle of the spherical triangle.

        area = alpha + beta + gamma - M_PI ;

        // Compute the orientation of the triangle.

		double mix = A_ * ( B_ ^ C_ ) ;
		orient = (mix > 0) ? 1 : ((mix < 0) ? -1 : 0) ;

        // Initialize three variables that are used for sampling the triangle.

        U         = Unit( C_ / A_ );  // In plane of AC orthogonal to A.
        sin_alpha = sin( alpha );
        product   = sin_alpha * cos_c;
    }