/* -*- coding: utf-8 -*- */
/**
\ingroup geom
@{
\file arco.h
\brief Declaración de funciones para la realización de cálculos con arcos de
       circunferencia.
\author José Luis García Pallero, jgpallero@gmail.com
\date 08 de agosto de 2013
\copyright
Copyright (c) 2013-2014, José Luis García Pallero. All rights reserved.
\par
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
\par
- Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.
- Neither the name of the copyright holders nor the names of its contributors
  may be used to endorse or promote products derived from this software without
  specific prior written permission.
\par
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/******************************************************************************/
/******************************************************************************/
#ifndef _ARCO_H_
#define _ARCO_H_
/******************************************************************************/
/******************************************************************************/
#include<math.h>
#include"libgeoc/constantes.h"
#include"libgeoc/fgeneral.h"
#include"libgeoc/geocnan.h"
#include"libgeoc/mate.h"
#include"libgeoc/ptopol.h"
/******************************************************************************/
/******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_RES_ANG
\brief Resolución angular por debajo de la cual no se distinguirán dos valores
       angulares en radianes.
\note Esta constante ha de ser \b SIEMPRE positiva.
\date 14 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_RES_ANG (1.0e-12)
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_NO_INTERSEC
\brief Identificador de que dos arcos no se cortan.
\date 08 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_NO_INTERSEC 0
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_INTERSEC
\brief Identificador de que dos arcos se cortan en un punto, pero no son
       colineales.
\date 08 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_INTERSEC 1
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_INTERSEC_EXTREMO_NO_COLIN
\brief Identificador de que dos arcos se cortan en un punto, el cual es un
       extremo que está encima del otro arco, pero no son colineales.
\date 08 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_INTERSEC_EXTREMO_NO_COLIN 2
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_INTERSEC_EXTREMOS_NO_COLIN
\brief Identificador de que dos arcos tienen un extremo común, pero no son
       colineales.
\date 13 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_INTERSEC_EXTREMOS_NO_COLIN 3
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_INTERSEC_EXTREMOS_COLIN
\brief Identificador de que dos arcos tienen un punto común y son colineales.
\date 08 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_INTERSEC_EXTREMOS_COLIN 4
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_INTERSEC_MISMO_ARC
\brief Identificador de que dos arcos tienen todos sus puntos extremos en común.
\date 08 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_INTERSEC_MISMO_ARC 5
/******************************************************************************/
/******************************************************************************/
/**
\def GEOC_ARC_INTERSEC_COLIN
\brief Identificador de que dos arcos tienen más de un punto en común, es decir,
       se solapan, pero no son el mismo arco.
\date 08 de agosto de 2013: Creación de la constante.
*/
#define GEOC_ARC_INTERSEC_COLIN 6
/******************************************************************************/
/******************************************************************************/
/**
\brief Comprueba si dos rectángulos sobre la superficie de la esfera son
       disjuntos, atendiendo únicamente a la coordenada longitud geodésica.
\param[in] tol Tolerancia angular, en radianes. Indica el valor por debajo del
           cual dos ángulos se consideran iguales. Este argumento ha de ser un
           número \b POSITIVO (no se comprueba internamente).
\param[in] lonMin1 Longitud mínima del rectángulo 1, en radianes.
\param[in] lonMax1 Longitud máxima del rectángulo 1, en radianes.
\param[in] lonMin2 Longitud mínima del rectángulo 2, en radianes.
\param[in] lonMax2 Longitud máxima del rectángulo 2, en radianes.
\return Dos posibilidades:
        - 0: Los rectángulos no son disjuntos, es decir, tienen alguna parte
             común (se cortan o se tocan) o uno está completamente contenido en
             el otro.
        - Distinto de 0: Los rectángulos son disjuntos.
\note Esta función asume que \em lonMin1<lonyMax1 y \em lonMin2<lonMax2.
\note Hay casos sobre la superficie de la esfera en los que el solapamiento de
      rectángulos es muy difícil de determinar, como aquéllos en que algún
      rectángulo tiene incrementos de longitud mayores que \f$\pi\f$ o los que
      alguno de los lados tiene igual latitud. Por todo ello, esta función sólo
      tiene en cuenta longitudes. Si hay solapamiento en longitud, se considera
      que los rectángulos no son disjuntos.
\date 09 de junio de 2012: Creación de la función.
\date 23 de septiembre de 2013: Adición del argumento \em tol.
\todo Esta función no está probada.
*/
int ArcosCircMaxDisjuntos(const double tol,
                          const double lonMin1,
                          const double lonMax1,
                          const double lonMin2,
                          const double lonMax2);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula el acimut de un arco de círculo máximo AB sobre la esfera.
\param[in] tol Tolerancia angular, en radianes. Indica el valor por debajo del
           cual dos ángulos se consideran iguales. Este argumento ha de ser un
           número \b POSITIVO (no se comprueba internamente).
\param[in] latA Latitud del punto A, en radianes.
\param[in] lonA Longitud del punto A, en radianes.
\param[in] latB Latitud del punto B, en radianes.
\param[in] lonB Longitud del punto B, en radianes.
\param[out] mRot Matriz de rotación aplicada al arco AB para llevar el punto A
            al punto de coordenadas \f$(\varphi=0,\lambda=0)\f$. Este
            argumento ha de ser una matriz de 3x3 almacenada en el formato de C.
\return Acimut del arco AB, en radianes.
\note El argumento \em mRot ha de ser pasado como una matriz en formato de C;
      esto es, se accederá a sus elementos como <em>mRot[fil][com]</em>.
\note El dominio de salida del acimut es \f$[0,2\pi[\f$.
\date 13 de agosto de 2013: Creación de la función.
\date 23 de septiembre de 2013: Adición del argumento \em tol.
\todo Esta función no está probada.
*/
double AcimutArcoCircMaxEsf(const double tol,
                            const double latA,
                            const double lonA,
                            const double latB,
                            const double lonB,
                            double mRot[][3]);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula una matriz de rotación tal que, aplicada a un arco de círculo
       máximo AB sobre la esfera, el punto A sea el punto de coordenadas
       \f$(\varphi=0,\lambda=0)\f$ y el B esté contenido en el ecuador.
\param[in] tol Tolerancia angular, en radianes. Indica el valor por debajo del
           cual dos ángulos se consideran iguales. Este argumento ha de ser un
           número \b POSITIVO (no se comprueba internamente).
\param[in] latA Latitud del punto A, en radianes.
\param[in] lonA Longitud del punto A, en radianes.
\param[in] latB Latitud del punto B, en radianes.
\param[in] lonB Longitud del punto B, en radianes.
\param[out] mRot Matriz de rotación para aplicar a las coordenadas cartesianas
            tridimensionales geocéntricas de los extremos de un segmento para
            llevarlos al sistema descrito anteriormente. Este argumento ha de
            ser una matriz de 3x3, almacenada en el formato de C.
\param[out] lonBR Longitud del punto B en el sistema rotado, en el dominio
            \f$]-\pi,\pi]\f$, en radianes. Este argumento sólo es tenido en
            cuenta si se pasa un puntero distinto de \p NULL.
\note El argumento \em mRot ha de ser pasado como una matriz en formato de C;
      esto es, se accederá a sus elementos como <em>mRot[fil][com]</em>.
\date 13 de agosto de 2013: Creación de la función.
\date 23 de septiembre de 2013: Adición del argumento \em tol.
\todo Esta función no está probada.
*/
void RotaArco00Ecuador(const double tol,
                       const double latA,
                       const double lonA,
                       const double latB,
                       const double lonB,
                       double mRot[][3],
                       double* lonBR);
/******************************************************************************/
/******************************************************************************/
/**
\brief Aplica una matriz de rotación a un punto en coordenadas cartesianas
       tridimensionales geocéntricas.
\param[in] sentido Identificador para realizar la rotación directa o la inversa.
           Dos posibilidades:
           - Mayor o igual que 0: Se realiza la transformación directa.
           - Menor que 0: Re realiza la transformación inversa.
\param[in] x Coordenada X del punto.
\param[in] y Coordenada Y del punto.
\param[in] z Coordenada Z del punto.
\param[in] mRot Matriz de rotación de 3x3, almacenada en el formato de C.
\param[out] xR Coordenada X rotada. Este argumento sólo es tenido en cuenta si
            se pasa un puntero distinto de \p NULL.
\param[out] yR Coordenada Y rotada. Este argumento sólo es tenido en cuenta si
            se pasa un puntero distinto de \p NULL.
\param[out] zR Coordenada Z rotada. Este argumento sólo es tenido en cuenta si
            se pasa un puntero distinto de \p NULL.
\note El argumento \em mRot ha de ser pasado como una matriz en formato de C;
      esto es, se accederá a sus elementos como <em>mRot[fil][com]</em>.
\date 13 de agosto de 2013: Creación de la función.
\todo Esta función no está probada.
*/
void AplicaMatrizRotacionCoorCart(const int sentido,
                                  const double x,
                                  const double y,
                                  const double z,
                                  double mRot[][3],
                                  double* xR,
                                  double* yR,
                                  double* zR);
/******************************************************************************/
/******************************************************************************/
/**
\brief Aplica una matriz de rotación a un punto en coordenadas geodésicas.
\param[in] sentido Identificador para realizar la rotación directa o la inversa.
           Dos posibilidades:
           - Mayor o igual que 0: Se realiza la transformación directa.
           - Menor que 0: Re realiza la transformación inversa.
\param[in] lat Latitud del punto, en radianes.
\param[in] lon Longitud del punto, en radianes.
\param[in] mRot Matriz de rotación de 3x3, almacenada en el formato de C.
\param[out] latR Latitud del punto en el sistema rotado, en radianes. Este
            argumento sólo es tenido en cuenta si se pasa un puntero distinto de
            \p NULL.
\param[out] lonR Longitud del punto en el sistema rotado, en radianes. Este
            argumento sólo es tenido en cuenta si se pasa un puntero distinto de
            \p NULL.
\note El argumento \em mRot ha de ser pasado como una matriz en formato de C;
      esto es, se accederá a sus elementos como <em>mRot[fil][com]</em>.
\note El dominio de la variable de salida \em lat1 es
      \f$[-\frac{\pi}{2},\frac{\pi}{2}]\f$.
\note El dominio de la variable de salida \em lon1 es \f$]-\pi,\pi]\f$.
\date 13 de agosto de 2013: Creación de la función.
\todo Esta función no está probada.
*/
void AplicaMatrizRotacionCoorGeod(const int sentido,
                                  const double lat,
                                  const double lon,
                                  double mRot[][3],
                                  double* latR,
                                  double* lonR);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula los puntos de intersección de dos círculos máximos sobre la
       superfice de la esfera, estando uno de ellos, que se omite, contenido en
       el ecuador.
\param[in] tol Tolerancia. Indica el valor por debajo del cual la componente de
           un vector se considera igual a 0.0. Este argumento ha de ser un
           número \b POSITIVO (no se comprueba internamente).
\param[in] xC Coordenada X cartesiana geocéntrica del primer extremo del arco.
\param[in] yC Coordenada Y cartesiana geocéntrica del primer extremo del arco.
\param[in] zC Coordenada Z cartesiana geocéntrica del primer extremo del arco.
\param[in] xD Coordenada X cartesiana geocéntrica del segundo extremo del arco.
\param[in] yD Coordenada Y cartesiana geocéntrica del segundo extremo del arco.
\param[in] zD Coordenada Z cartesiana geocéntrica del segundo extremo del arco.
\param[out] xP Coordenada X cartesiana geocéntrica de uno de los puntos de
            intersección, sobre la esfera de radio unidad. La coordenada del
            otro punto será -\em xP.
\param[out] yP Coordenada Y cartesiana geocéntrica de uno de los puntos de
            intersección, sobre la esfera de radio unidad. La coordenada del
            otro punto será -\em yP.
\param[out] zP Coordenada Z cartesiana geocéntrica de uno de los puntos de
            intersección, sobre la esfera de radio unidad. La coordenada del
            otro punto será -\em zP.
\return Dos posibilidades:
        - #GEOC_ARC_INTERSEC: Hay intersección.
        - #GEOC_ARC_NO_INTERSEC: No se ha podido calcular intersección, por lo
          que \em xP, \em yP y \em zP no se utilizan internamente. Las razones
          pueden ser:
          - El arco CD es coindidente con el ecuador.
          - Los vectores OC y OD forman un ángulo de \f$0\f$ o \f$\pi\f$, y no
            se puede calcular su vector normal.
\note Esta función no es robusta, es decir, puede dar resultados incorrectos
      debido a errores de redondeo.
\note Aunque los puntos C y D pertenezcan a una esfera de radio arbitrario, las
      coordenadas de los puntos de intersección de los círculos máximos se dan
      sobre la esfera de radio unidad.
\note Para que se devuelvan las coordnadas del punto intersección, los
      argumentos \em xP, \em yP y \em zP han de ser, \b TODOS, distintos de
      \p NULL.
\date 13 de agosto de 2013: Creación de la función.
\date 22 de septirmbre de 2013: Adición del argumento \em tol.
*/
int IntersecCircMaxEsfAux(const double tol,
                          const double xC,
                          const double yC,
                          const double zC,
                          const double xD,
                          const double yD,
                          const double zD,
                          double* xP,
                          double* yP,
                          double* zP);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula la intersección de dos arcos de círculo máximo sobre la
       superfice de la esfera que tienen, al menos, un extremo común. Uno de los
       arcos, que se omite, está en el ecuador, con su extremo inicial en el
       punto \f$(\varphi=0,\lambda=0)\f$.
\param[in] tol Tolerancia, en radianes. Indica el valor por debajo del cual la
           diferencia entre dos ángulos se considera igual a 0.0. Este argumento
           ha de ser un número \b POSITIVO (no se comprueba internamente).
\param[in] lonB Longitud, en radianes, del segundo extremo del arco AB, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] latC Latitud, en radianes, del primer extremo del arco CD.
\param[in] lonC Longitud, en radianes, del primer extremo del arco CD, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] latD Latitud, en radianes, del segundo extremo del arco CD.
\param[in] lonD Longitud, en radianes, del segundo extremo del arco CD, en el
           dominio \f$]-\pi,\pi]\f$.
\param[out] latP Latitud, en radianes, del punto de intersección. Siempre 0.0.
\param[out] lonP Longitud, en radianes, del punto de intersección, en el
            dominio \f$]-\pi,\pi]\f$.
\return Cinco posibilidades:
        - #GEOC_ARC_NO_INTERSEC: Los arcos no tienen ningún punto en común.
        - #GEOC_ARC_INTERSEC_EXTREMOS_NO_COLIN: Los arcos tienen un extremo
          común, pero no son colineales.
        - #GEOC_ARC_INTERSEC_EXTREMOS_COLIN: Los arcos tienen un extremo común y
          son colineales.
        - #GEOC_ARC_INTERSEC_COLIN: Los arcos tienen más de un punto en común.
        - #GEOC_ARC_INTERSEC_MISMO_ARC: Los dos arcos son idénticos.
\note Para que se devuelvan las coordnadas del punto intersección, los
      argumentos \em latP y \em lonP han de ser, \b TODOS, distintos de \p NULL.
\note Si los arcos no se tocan, las variables devueltos en \em latP y \em lonP
      almacenan 0.0.
\note Los arcos implicados no pueden subtender un ángulo mayor o igual que
      \f$\pi\f$. Esta condición no se comprueba internamente, por lo que \b NO
      se informa de su posible inclumplimiento, y la función se ejecutará
      normalmente.
\note Esta función no es robusta, es decir, puede dar resultados incorrectos
      debido a errores de redondeo.
\note Si hay intersección, las coordenadas devueltas coinciden exactamente con
      las del vértice implicado, A, B, C o D.
\note Si los arcos se tocan en los dos extremos (son el mismo arco), las
      coordenadas devueltas son siempre las del vértice A.
\note Un buen valor para \em tol puede ser #GEOC_ARC_RES_ANG.
\note Las longitudes de trabajo han de estar, obligatoriamente, en el dominio
      \f$]-\pi,\pi]\f$.
\date 22 de septiembre de 2013: Creación de la función.
*/
int IntersecArcCirMaxEsferaVertComunAux(const double tol,
                                        const double lonB,
                                        const double latC,
                                        const double lonC,
                                        const double latD,
                                        const double lonD,
                                        double* latP,
                                        double* lonP);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula la intersección de dos arcos de círculo máximo sobre la
       superfice de la esfera que tienen partes en común (se solapan
       parcialmente o el vértice de uno está apoyado en el otro arco-pero no en
       un vértice del segundo-). Uno de los arcos, que se omite, está en el
       ecuador, con su extremo inicial en el punto \f$(\varphi=0,\lambda=0)\f$.
\param[in] tol Tolerancia, en radianes. Indica el valor por debajo del cual la
           diferencia entre dos ángulos se considera igual a 0.0. Este argumento
           ha de ser un número \b POSITIVO (no se comprueba internamente).
\param[in] lonB Longitud, en radianes, del segundo extremo del arco AB, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] latC Latitud, en radianes, del primer extremo del arco CD.
\param[in] lonC Longitud, en radianes, del primer extremo del arco CD, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] latD Latitud, en radianes, del segundo extremo del arco CD.
\param[in] lonD Longitud, en radianes, del segundo extremo del arco CD, en el
           dominio \f$]-\pi,\pi]\f$.
\param[out] latP Latitud, en radianes, del punto de intersección. Siempre 0.0.
\param[out] lonP Longitud, en radianes, del punto de intersección, en el
            dominio \f$]-\pi,\pi]\f$.
\return Tres posibilidades:
        - #GEOC_ARC_NO_INTERSEC: Los arcos no tienen ningún punto en común.
        - #GEOC_ARC_INTERSEC_EXTREMO_NO_COLIN: El extremo de un arco toca al
          otro arco en un punto (excluidos los extremos del segundo), pero los
          arcos no son colineales.
        - #GEOC_ARC_INTERSEC_COLIN: Los arcos tienen más de un punto en común.
\note Esta función considera los casos de arcos colineales que sólo coincidan en
      un vértice como #GEOC_ARC_INTERSEC_COLIN. Para tratar correctamente esos
      casos especiales, se recomienda ejecutar antes la función
      \ref IntersecArcCirMaxEsferaVertComunAux.
\note Para que se devuelvan las coordnadas del punto intersección, los
      argumentos \em latP y \em lonP han de ser, \b TODOS, distintos de \p NULL.
\note Si los arcos no se tocan, las variables devueltos en \em latP y \em lonP
      almacenan 0.0.
\note Los arcos implicados no pueden subtender un ángulo mayor o igual que
      \f$\pi\f$. Esta condición no se comprueba internamente, por lo que \b NO
      se informa de su posible inclumplimiento, y la función se ejecutará
      normalmente.
\note Esta función no es robusta, es decir, puede dar resultados incorrectos
      debido a errores de redondeo.
\note Si hay intersección, las coordenadas devueltas coinciden exactamente con
      las del vértice implicado, A, B, C o D.
\note Un buen valor para \em tol puede ser #GEOC_ARC_RES_ANG.
\note Las longitudes de trabajo han de estar, obligatoriamente, en el dominio
      \f$]-\pi,\pi]\f$.
\date 22 de septiembre de 2013: Creación de la función.
*/
int IntersecArcCirMaxEsferaVertApoyadoAux(const double tol,
                                          const double lonB,
                                          const double latC,
                                          const double lonC,
                                          const double latD,
                                          const double lonD,
                                          double* latP,
                                          double* lonP);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula la intersección de dos arcos de círculo máximo sobre la
       superfice de la esfera, uno de los cuales, que se omite, está en el
       ecuador, con su extremo inicial en el punto \f$(\varphi=0,\lambda=0)\f$.
\param[in] tol Tolerancia, en radianes. Indica el valor por debajo del cual la
           diferencia entre dos ángulos se considera igual a 0.0. Este argumento
           ha de ser un número \b POSITIVO (no se comprueba internamente).
\param[in] lonB Longitud, en radianes, del segundo extremo del arco AB, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] latC Latitud, en radianes, del primer extremo del arco CD.
\param[in] lonC Longitud, en radianes, del primer extremo del arco CD, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] latD Latitud, en radianes, del segundo extremo del arco CD.
\param[in] lonD Longitud, en radianes, del segundo extremo del arco CD, en el
           dominio \f$]-\pi,\pi]\f$.
\param[in] xGC Coordenada X cartesiana geocéntrica para esfera de radio
           unidad, en el sistema original, correspondiente al punto C. Este
           argumento sólo se tiene en cuenta si es distinto del valor devuelto
           por \ref GeocNan.
\param[in] yGC Coordenada Y cartesiana geocéntrica para esfera de radio
           unidad, en el sistema original, correspondiente al punto C. Este
           argumento sólo se tiene en cuenta si es distinto del valor devuelto
           por \ref GeocNan.
\param[in] zGC Coordenada Z cartesiana geocéntrica para esfera de radio
           unidad, en el sistema original, correspondiente al punto C. Este
           argumento sólo se tiene en cuenta si es distinto del valor devuelto
           por \ref GeocNan.
\param[in] xGD Coordenada X cartesiana geocéntrica para esfera de radio
           unidad, en el sistema original, correspondiente al punto C. Este
           argumento sólo se tiene en cuenta si es distinto del valor devuelto
           por \ref GeocNan.
\param[in] yGD Coordenada Y cartesiana geocéntrica para esfera de radio
           unidad, en el sistema original, correspondiente al punto C. Este
           argumento sólo se tiene en cuenta si es distinto del valor devuelto
           por \ref GeocNan.
\param[in] zGD Coordenada Z cartesiana geocéntrica para esfera de radio
           unidad, en el sistema original, correspondiente al punto C. Este
           argumento sólo se tiene en cuenta si es distinto del valor devuelto
           por \ref GeocNan.
\param[out] latP Latitud, en radianes, del punto de intersección. Siempre 0.0.
\param[out] lonP Longitud, en radianes, del punto de intersección, en el
            dominio \f$]-\pi,\pi]\f$.
\return Siete posibilidades:
        - #GEOC_ARC_NO_INTERSEC: Los arcos no tienen ningún punto en común.
        - #GEOC_ARC_INTERSEC: Los arcos se cortan en un punto.
        - #GEOC_ARC_INTERSEC_EXTREMO_NO_COLIN: El extremo de un arco toca al
          otro arco en un punto (excluidos los extremos del segungo), pero los
          arcos no son colineales.
        - #GEOC_ARC_INTERSEC_EXTREMOS_NO_COLIN: Los arcos tienen un extremo
          común, pero no son colineales.
        - #GEOC_ARC_INTERSEC_EXTREMOS_COLIN: Los arcos tienen un extremo común y
          son colineales.
        - #GEOC_ARC_INTERSEC_MISMO_ARC: Los dos arcos son idénticos.
        - #GEOC_ARC_INTERSEC_COLIN: Los arcos tienen más de un punto en común.
\note Para que se devuelvan las coordnadas del punto intersección, los
      argumentos \em latP y \em lonP han de ser, \b TODOS, distintos de \p NULL.
\note Si los arcos no se tocan, las variables devueltos en \em latP y \em lonP
      almacenan 0.0.
\note Los arcos implicados no pueden subtender un ángulo mayor o igual que
      \f$\pi\f$. Esta condición no se comprueba internamente, por lo que \b NO
      se informa de su posible inclumplimiento, y la función se ejecutará
      normalmente.
\note Esta función no es robusta, es decir, puede dar resultados incorrectos
      debido a errores de redondeo.
\note Un buen valor para \em tol puede ser #GEOC_ARC_RES_ANG.
\note Las longitudes de trabajo han de estar, obligatoriamente, en el dominio
      \f$]-\pi,\pi]\f$.
\note Los argumentos \em xGC, \em yGC, \em zGC, \em xGD, \em yGD y \em zGD sólo
      son tenidos en cuenta si se trabaja sobre la esfera y cada tríada es
      distinta de \ref GeocNan, en cuyo caso las coordenadas cartesianas
      tridimensionales geocéntricas, necesarias para los cálculos llevados a
      cabo por la función, son calculadas internamente a partir de los
      argumentos \em latC, \em lonC, \em latD y \em latD.
\date 22 de septiembre de 2013: Creación de la función.
\date 28 de marzo de 2014: Adición de los argumentos \em xGC, \em yGC, \em zGC,
      \em xGD, \em yGD y \em zGD.
*/
int IntersecArcCircMaxEsferaAux(const double tol,
                                const double lonB,
                                const double latC,
                                const double lonC,
                                const double latD,
                                const double lonD,
                                const double xGC,
                                const double yGC,
                                const double zGC,
                                const double xGD,
                                const double yGD,
                                const double zGD,
                                double* latP,
                                double* lonP);
/******************************************************************************/
/******************************************************************************/
/**
\brief Calcula la intersección de dos arcos de círculo máximo sobre la
       superfice de la esfera.
\param[in] latA Latitud, en radianes, del primer extremo del arco AB.
\param[in] lonA Longitud, en radianes, del primer extremo del arco AB.
\param[in] latB Latitud, en radianes, del segundo extremo del arco AB.
\param[in] lonB Longitud, en radianes, del segundo extremo del arco AB.
\param[in] latC Latitud, en radianes, del primer extremo del arco CD.
\param[in] lonC Longitud, en radianes, del primer extremo del arco CD.
\param[in] latD Latitud, en radianes, del segundo extremo del arco CD.
\param[in] lonD Longitud, en radianes, del segundo extremo del arco CD.
\param[out] latP Latitud, en radianes, del punto de intersección. El dominio de
            la latitud utilizado es, independientemente del usado en las
            variables de entrada, \f$[-\frac{\pi}{2},\frac{\pi}{2}]\f$.
\param[out] lonP Longitud, en radianes, del punto de intersección. El dominio de
            la longitud utilizado es, independientemente del usado en las
            variables de entrada, \f$]-\pi,\pi]\f$.
\return Siete posibilidades:
        - #GEOC_ARC_NO_INTERSEC: Los arcos no tienen ningún punto en común.
        - #GEOC_ARC_INTERSEC: Los arcos se cortan en un punto.
        - #GEOC_ARC_INTERSEC_EXTREMO_NO_COLIN: El extremo de un arco toca al
          otro arco en un punto (excluidos los extremos del segungo), pero los
          arcos no son colineales.
        - #GEOC_ARC_INTERSEC_EXTREMOS_NO_COLIN: Los arcos tienen un extremo
          común, pero no son colineales.
        - #GEOC_ARC_INTERSEC_EXTREMOS_COLIN: Los arcos tienen un extremo común y
          son colineales.
        - #GEOC_ARC_INTERSEC_MISMO_ARC: Los dos arcos son idénticos.
        - #GEOC_ARC_INTERSEC_COLIN: Los arcos tienen más de un punto en común.
\note Para que se devuelvan las coordnadas del punto intersección, los
      argumentos \em latP y \em lonP han de ser, \b TODOS, distintos de \p NULL.
\note Si los arcos no se tocan, las variables devueltos en \em latP y \em lonP
      almacenan 0.0.
\note Los arcos implicados no pueden subtender un ángulo mayor o igual que
      \f$\pi\f$. Esta condición no se comprueba internamente, por lo que \b NO
      se informa de su posible inclumplimiento, y la función se ejecutará
      normalmente.
\note Esta función no es robusta, es decir, puede dar resultados incorrectos
      debido a errores de redondeo.
\note Esta función considera dos puntos iguales a aquellos que estén en un
      entorno de #GEOC_ARC_RES_ANG radianes.
\note Si los arcos se tocan en los dos extremos (son el mismo arco), las
      coordenadas devueltas son siempre las del vértice A.
\note Si los arcos tienen más de un punto en común, pero no son el mismo arco,
      las coordenadas de salida siempre son las de un punto extremo de un arco.
      Este punto extremo se intentará que sea uno de los puntos iniciales de
      algún arco, anque no se puede asegurar.
\date 13 de agosto de 2013: Creación de la función.
*/
int IntersecArcCircMaxEsfera(const double latA,
                             const double lonA,
                             const double latB,
                             const double lonB,
                             const double latC,
                             const double lonC,
                             const double latD,
                             const double lonD,
                             double* latP,
                             double* lonP);
/******************************************************************************/
/******************************************************************************/
#ifdef __cplusplus
}
#endif
/******************************************************************************/
/******************************************************************************/
#endif
/******************************************************************************/
/******************************************************************************/
/** @} */
/******************************************************************************/
/******************************************************************************/
/* kate: encoding utf-8; end-of-line unix; syntax c; indent-mode cstyle; */
/* kate: replace-tabs on; space-indent on; tab-indents off; indent-width 4; */
/* kate: line-numbers on; folding-markers on; remove-trailing-space on; */
/* kate: backspace-indents on; show-tabs on; */
/* kate: word-wrap-column 80; word-wrap-marker-color #D2D2D2; word-wrap off; */
