/* MLIPRI.f -- translated by f2c (version 19960827).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/

#include "Data_f2c.h"
#include <Data_Data.h>
/* Common Block Declarations */

/*extern __Data_API struct {*/
extern struct {
    integer nbr[1001];
} minombr_;

#define minombr_1 minombr_

/*extern __Data_API struct {*/
extern struct {
    doublereal pi, deuxpi, pisur2, pis180, c180pi, zero, one, a180, a360, a90;
} mdnombr_;

#define mdnombr_1 mdnombr_

/* Subroutine */ int mmlipri_(ndimen, nbrpnt, nbcntr, tabpnt, typcnt, tabcnt, 
	numpnt, vtange, iercod)
integer *ndimen, *nbrpnt, *nbcntr;
doublereal *tabpnt;
integer *typcnt;
doublereal *tabcnt;
integer *numpnt;
doublereal *vtange;
integer *iercod;
{
    /* Initialized data */

    static doublereal epsiln = 1e-9;

    /* System generated locals */
    integer tabpnt_dim1, tabpnt_offset, tabcnt_dim1, tabcnt_offset, i__1;

    /* Local variables */
    static logical ldbg;
    static doublereal vcnt[3], wcnt, wpnt;
    static integer idcnt;
    static doublereal denom;
    static integer ii;
    static doublereal parbol[9];
    extern /* Subroutine */ int mmli3pt_();
    static integer ier;
    extern integer mnfndeb_();
    extern /* Subroutine */ int maermsg_(), mgenmsg_(), mmdrvck_(), mswrdbg_()
	    , msrfill_(), mgsomsg_(), mvriraz_(), mmunivt_();



/* < */
/* **NOTICE */
/*  THIS SOFTWARE IS THE PROPERTY OF CISIGRAPH. */
/*  THIS CODE MUST NOT BE DISTRIBUTED OR COPIED WITHOUT THE PRIOR */
/*  WRITTEN PERMISSION OF CISIGRAPH AND IS ONLY TO BE USED ON THE */
/*  SITE WHERE IT IS INSTALLED BY CISIGRAPH */
/* **NOTICE */

/* ***********************************************************************
 */

/*     FONCTION : */
/*     ---------- */
/*       Estimation de la tangente norme au point ti */

/*     MOTS CLES : */
/*     ----------- */
/*      RESERVE, LISSAGE, ESTIMATION, TANGENTE, COURBE, EN_DEVELOPPEMENT 
*/

/*     ARGUMENTS D'ENTREE : */
/*     -------------------- */
/*     NDIMEN : Dimension de l'espace */
/*     NBRPNT : Nombre de points a lisser  (>= 2) */
/*     NBCNTR : Nombre de point contraints (<= NBRPNT) */
/*     TABPNT : Tableau des points a lisser */
/*     TYPCNT : Tableau caracterisant les points contraints */
/*     TYPCNT(1,i) :  Indice du point contraints */
/*     TYPCNT(2,i) :  Type de la contrainte */
/*                    0 -> de passage (G0) */
/*                    1 -> de tangence (G1) */
/*                    2 -> de courbure (G2) */
/*     TABCNT(*,1,i) : Vecteur tangent a respecter */
/*     TABCNT(*,2,i) : Vecteur courbure a respecter */
/*     TABPAR : Tableaux des paramtres corespondant aux points a lisser */
/*     NUMPNT : Numero du point ou l'on fait l'estimation */

/*     ARGUMENTS DE SORTIE : */
/*     --------------------- */

/*       VTANGE  : Le vecteur tangent estime */
/*       IERCOD : code d'erreur */
/*          - 3 : Non convergence */
/*          - 2 : Non respect de l'ecart max */
/*          - 1 : Non respect des contraintes */
/*          0   : Ok */
/*         > 0 : Echec */

/*     COMMONS UTILISES : */
/*     ------------------ */


/*     REFERENCES APPELEES : */
/*     --------------------- */


/*     DESCRIPTION/REMARQUES/LIMITATIONS : */
/*     ----------------------------------- */


/* $    HISTORIQUE DES MODIFICATIONS : */
/*     ------------------------------ */
/*     17-11-1995: PMN; Probleme dans le numero de contraintes. */
/*      5-09-1995: PMN; ECRITURE VERSION ORIGINALE. */
/* > */
/* ***********************************************************************
 */
/*                            DECLARATIONS */
/* ***********************************************************************
 */

/*     INCLUDE MINOMBR */
/* < */
/* **NOTICE */
/*  THIS SOFTWARE IS THE PROPERTY OF CISIGRAPH. */
/*  THIS CODE MUST NOT BE DISTRIBUTED OR COPIED WITHOUT THE PRIOR */
/*  WRITTEN PERMISSION OF CISIGRAPH AND IS ONLY TO BE USED ON THE */
/*  SITE WHERE IT IS INSTALLED BY CISIGRAPH */
/* **NOTICE */

/* ***********************************************************************
 */

/*     FONCTION : */
/*     ---------- */
/*        Sert a fournir les constantes entieres de 0 a 1000 */

/*     MOTS CLES : */
/*     ----------- */
/*        TOUS,ENTIERS */

/*     DEMSCRIPTION/REMARQUES/LIMITATIONS : */
/*     ----------------------------------- */

/* $    HISTORIQUE DES MODIFICATIONS : */
/*     ------------------------------ */
/*     11-10-89 : DH ; Creation version originale */
/* > */
/* ***********************************************************************
 */


/* ***********************************************************************
 */


/*     INCLUDE MDNOMBR */
/* < */
/* **NOTICE */
/*  THIS SOFTWARE IS THE PROPERTY OF CISIGRAPH. */
/*  THIS CODE MUST NOT BE DISTRIBUTED OR COPIED WITHOUT THE PRIOR */
/*  WRITTEN PERMISSION OF CISIGRAPH AND IS ONLY TO BE USED ON THE */
/*  SITE WHERE IT IS INSTALLED BY CISIGRAPH */
/* **NOTICE */

/* ***********************************************************************
 */

/*     FONCTION : */
/*     ---------- */
/*      LE COMMON DES NOMBRES REELS REMARQUABLES */

/*     MOTS CLES : */
/*     ----------- */
/*      TOUS - LECTURE SEULEMENT */

/*     DEMSCRIPTION/REMARQUES/LIMITATIONS : */
/*     ----------------------------------- */

/* $    HISTORIQUE DES MODIFICATIONS : */
/*     ------------------------------ */
/*     18-12-89 : NAK ; ENTETE STANDARD */
/*     20-10-87 : NAK; CREATION VERSION ORIGINALE */
/* > */
/* ***********************************************************************
 */

/*        PI     : 3.1415.... */
/*        DEUXPI : 2*PI */
/*        PISUR2 : PI/2 */
/*        PIS180 : PI/180 */
/*        C180PI : 180/PI */
/*        ZERO   : 0.D0 */
/*        ONE    : 1.D0 */
/*        A180   : 180 DEGRES */
/*        A360   : 360 DEGRES */
/*        A90    : 90 DEGRES */




/* ---  Variables statiques */


/*     VARIABLES LOCALES */


    /* Parameter adjustments */
    --vtange;
    tabcnt_dim1 = *ndimen;
    tabcnt_offset = tabcnt_dim1 * 3 + 1;
    tabcnt -= tabcnt_offset;
    tabpnt_dim1 = *ndimen;
    tabpnt_offset = tabpnt_dim1 + 1;
    tabpnt -= tabpnt_offset;
    typcnt -= 3;

    /* Function Body */

/* ***********************************************************************
 */
/*                      INITIALISATIONS */
/* ***********************************************************************
 */

    ldbg = mnfndeb_() >= 4;
    if (ldbg) {
	mgenmsg_("MMLIPRI", 7L);
    }
    *iercod = 0;

    if (*numpnt == 1) {
	idcnt = 1;
    }

/* ***********************************************************************
 */
/*                     TRAITEMENT */
/* ***********************************************************************
 */

    if (*ndimen > 3) {
	goto L9101;
    }


/* (1) Estimation via les points */

    wpnt = (float)1.;

/* (1.1) Estimation au premier point */

    if (*numpnt == 1) {
	if (*nbrpnt < 3) {
	    wpnt = (float)0.;
	} else {
	    mmli3pt_(ndimen, &tabpnt[tabpnt_dim1 + 1], &tabpnt[(tabpnt_dim1 <<
		     1) + 1], &tabpnt[tabpnt_dim1 * 3 + 1], parbol, &ier);
	    if (ier > 0) {
		i__1 = *ndimen;
		for (ii = 1; ii <= i__1; ++ii) {
		    vtange[ii] = tabpnt[ii + (tabpnt_dim1 << 1)] - tabpnt[ii 
			    + tabpnt_dim1];
		}
	    } else {
		mmdrvck_(&minombr_1.nbr[3], ndimen, parbol, &minombr_1.nbr[1],
			 &mdnombr_1.zero, &vtange[1]);
	    }
	}

/* (1.2) Estimation au dernier point */

    } else if (*numpnt == *nbrpnt) {
	if (*nbrpnt < 3) {
	    wpnt = (float)0.;
	} else {
	    mmli3pt_(ndimen, &tabpnt[(*nbrpnt - 2) * tabpnt_dim1 + 1], &
		    tabpnt[(*nbrpnt - 1) * tabpnt_dim1 + 1], &tabpnt[*nbrpnt *
		     tabpnt_dim1 + 1], parbol, &ier);
	    if (ier > 0) {
		i__1 = *ndimen;
		for (ii = 1; ii <= i__1; ++ii) {
		    vtange[ii] = tabpnt[ii + *nbrpnt * tabpnt_dim1] - tabpnt[
			    ii + (*nbrpnt - 1) * tabpnt_dim1];
		}
	    } else {
		mmdrvck_(&minombr_1.nbr[3], ndimen, parbol, &minombr_1.nbr[1],
			 &mdnombr_1.one, &vtange[1]);
	    }
	}

/* (1.3) Estimation ailleur */

    } else {
	i__1 = *ndimen;
	for (ii = 1; ii <= i__1; ++ii) {
	    vtange[ii] = tabpnt[ii + (*numpnt + 1) * tabpnt_dim1] - tabpnt[ii 
		    + (*numpnt - 1) * tabpnt_dim1];
	}
    }

    mmunivt_(ndimen, &vtange[1], &vtange[1], &epsiln, &ier);
    if (ier > 0) {
	mvriraz_(ndimen, &vtange[1]);
    }

/* (2) Estimation via les contraintes */

    wcnt = 0.;
    if (*nbcntr > 0) {

	if (idcnt > *nbcntr || idcnt < 1) {
	    idcnt = 1;
	}

/*           ---> Recherche d'une contrainte en NUMPNT */
	if (typcnt[(idcnt << 1) + 1] > *numpnt) {
	    idcnt = 1;
	}
	while(typcnt[(idcnt << 1) + 1] < *numpnt && idcnt <= *nbcntr) {
	    ++idcnt;
	}

/*           ---> Affectation de la contrainte */
	if (typcnt[(idcnt << 1) + 1] == *numpnt) {
	    if (typcnt[(idcnt << 1) + 2] >= 1) {
		msrfill_(ndimen, &tabcnt[((idcnt << 1) + 1) * tabcnt_dim1 + 1]
			, vcnt);
		wcnt = 1.;
	    }
	} else {
	    --idcnt;
	}
    }

/* (3) Moyenne des estimations */

    denom = wpnt + wcnt;
    if (denom == (float)0.) {
	denom = 1.;
    } else {
	denom = 1. / denom;
    }
    i__1 = *ndimen;
    for (ii = 1; ii <= i__1; ++ii) {
	vtange[ii] = (wpnt * vtange[ii] + wcnt * vcnt[ii - 1]) * denom;
    }

    mmunivt_(ndimen, &vtange[1], &vtange[1], &epsiln, &ier);
    if (ier > 0) {
	mvriraz_(ndimen, &vtange[1]);
    }

    goto L9999;

/* ***********************************************************************
 */
/*                   TRAITEMENT DES ERREURS */
/* ***********************************************************************
 */

L9101:
    mswrdbg_("MMLIVAR: PROBLEME AVEC LES ARGUMENTS", 36L);
    *iercod = 1;
    goto L9999;

/* ***********************************************************************
 */
/*                   RETOUR PROGRAMME APPELANT */
/* ***********************************************************************
 */

L9999:

    if (*iercod > 0) {
	maermsg_("MMLIPRI", iercod, 7L);
    }
    if (ldbg) {
	mgsomsg_("MMLIPRI", 7L);
    }
 return 0 ;
} /* mmlipri_ */

