geometry/0000755000175000017500000000000012130276034012245 5ustar juanpijuanpigeometry/src/0000755000175000017500000000000012130276034013034 5ustar juanpijuanpigeometry/src/octclip/0000755000175000017500000000000012130276034014471 5ustar juanpijuanpigeometry/src/octclip/errores.c0000644000175000017500000001353512035672422016332 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup anespec errores eop fichero general geodesia geom geopot gshhs marea \ingroup matriz mmcc orden snx texto @{ \file errores.c \brief Definición de funciones para el tratamiento de errores. En el momento de la compilación ha de seleccionarse el comportamiento de la función \ref GeocError. Para realizar la selección es necesario definir las variables para el preprocesador \em ESCRIBE_MENSAJE_ERROR si se quiere que la función imprima un mensaje de error y/o \em FIN_PROGRAMA_ERROR si se quiere que la función termine la ejecución del programa en curso. Si no se define ninguna variable, la función no ejecuta ninguna acción. En \p gcc, las variables para el preprocesador se pasan como \em -DXXX, donde \em XXX es la variable a introducir. \author José Luis García Pallero, jgpallero@gmail.com \date 09 de enero de 2011 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/errores.h" /******************************************************************************/ /******************************************************************************/ int GeocTipoError(void) { //variable de salida int valor=GEOC_TIPO_ERR_NADA; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //distinguimos los posibles casos según las variables del preprocesador #if defined(ESCRIBE_MENSAJE_ERROR) && defined(FIN_PROGRAMA_ERROR) //mensaje de error y terminación del programa valor = GEOC_TIPO_ERR_MENS_Y_EXIT; #elif defined(ESCRIBE_MENSAJE_ERROR) //mensaje de error valor = GEOC_TIPO_ERR_MENS; #elif defined(FIN_PROGRAMA_ERROR) //terminación del programa valor = GEOC_TIPO_ERR_EXIT; #endif //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return valor; } /******************************************************************************/ /******************************************************************************/ void GeocError(const char mensaje[], const char funcion[]) { //hacemos una copia para que en la compilación no dé warning si sólo se //termina la ejecución del programa o no se hace nada mensaje = mensaje; funcion = funcion; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //distinguimos los posibles casos según las variables del preprocesador #if defined(ESCRIBE_MENSAJE_ERROR) && defined(FIN_PROGRAMA_ERROR) //imprimimos el nombre de la función y el mensaje fprintf(stderr,"En la función '%s'\n",funcion); fprintf(stderr,"%s\n",mensaje); //indicamos que el programa finalizará fprintf(stderr,"El programa finalizará mediante la llamada a la función " "'exit(EXIT_FAILURE)'\n"); //detenemos la ejecución del programa exit(EXIT_FAILURE); #elif defined(ESCRIBE_MENSAJE_ERROR) //imprimimos el nombre de la función y el mensaje fprintf(stderr,"En la función '%s'\n",funcion); fprintf(stderr,"%s\n",mensaje); //salimos de la función return; #elif defined(FIN_PROGRAMA_ERROR) //indicamos que el programa finalizará fprintf(stderr,"El programa finalizará mediante la llamada a la función " "'exit(EXIT_FAILURE)'\n"); //detenemos la ejecución del programa exit(EXIT_FAILURE); #else //salimos de la función return; #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; */ geometry/src/octclip/geocomp.c0000644000175000017500000001201612035672422016273 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup anespec general geocomp geodesia geom geopot gravim mmcc @{ \file geocomp.c \brief Definición de funciones para la obtención de información de la implementación de OpenMP usada. \author José Luis García Pallero, jgpallero@gmail.com \date 25 de agosto de 2011 \version 1.0 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/geocomp.h" /******************************************************************************/ /******************************************************************************/ void VersionOpenMP(const int macro_OPENMP, char version[]) { //vamos comprobando los valores de la macro if(macro_OPENMP==GEOC_OMP_F_1_0) { //versión 1.0 strcpy(version,GEOC_OMP_V_1_0); } else if(macro_OPENMP==GEOC_OMP_F_2_0) { //versión 2.0 strcpy(version,GEOC_OMP_V_2_0); } else if(macro_OPENMP==GEOC_OMP_F_2_5) { //versión 2.5 strcpy(version,GEOC_OMP_V_2_5); } else if(macro_OPENMP==GEOC_OMP_F_3_0) { //versión 3.0 strcpy(version,GEOC_OMP_V_3_0); } else if(macro_OPENMP==GEOC_OMP_F_3_1) { //versión 3.1 strcpy(version,GEOC_OMP_V_3_1); } else { //versión desconocida strcpy(version,GEOC_OMP_V_DESC); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int FechaVersionOpenMP(const char version[]) { //variable de salida int fecha=GEOC_OMP_F_DESC; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //vamos comprobando los valores de la versión if(!strcmp(version,GEOC_OMP_V_1_0)) { //versión 1.0 fecha = GEOC_OMP_F_1_0; } else if(!strcmp(version,GEOC_OMP_V_2_0)) { //versión 2.0 fecha = GEOC_OMP_F_2_0; } else if(!strcmp(version,GEOC_OMP_V_2_5)) { //versión 2.5 fecha = GEOC_OMP_F_2_5; } else if(!strcmp(version,GEOC_OMP_V_3_0)) { //versión 3.0 fecha = GEOC_OMP_F_3_0; } else if(!strcmp(version,GEOC_OMP_V_3_1)) { //versión 3.1 fecha = GEOC_OMP_F_3_1; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return fecha; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/fgeneral.c0000644000175000017500000010303612035672422016430 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup eop general geom geopot matriz @{ \file fgeneral.c \brief Definición de funciones de utilidad general. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 10 de octubre de 2009 \version 1.0 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/fgeneral.h" /******************************************************************************/ /******************************************************************************/ int GeocParOmpFgeneral(char version[]) { //comprobamos si hay paralelización #if defined(_OPENMP) //comprobamos si hay que extraer versión if(version!=NULL) { //calculamos la versión VersionOpenMP(_OPENMP,version); } //salimos de la función return 1; #else if(version!=NULL) { //utilizamos la variable version para que no dé warming al compilar strcpy(version,""); } //salimos de la función return 0; #endif } /******************************************************************************/ /******************************************************************************/ double PonAnguloDominio(const double angulo) { //signo del ángulo de trabajo double signo=0.0; //2.0*pi double dosPi=2.0*GEOC_CONST_PI; //variable auxiliar double aux=angulo; //variable de salida double sal=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //sólo trabajamos si el valor de entrada está fuera de los límites if((angulo<=-dosPi)||(angulo>=dosPi)) { //extraemos el signo del ángulo pasado signo = GEOC_SIGNO(angulo); //valor absoluto del ángulo pasado aux = fabs(angulo); //metemos el ángulo en dominio eliminando la cantidad que se pase de //2.0*pi sal = signo*(aux-floor(aux/dosPi)*dosPi); } else { //el valor de entrada no cambia sal = angulo; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ void BuscaSegmento1DInc(const double valor, const double* lista, const size_t nDatos, const size_t incDatos, size_t* posInicio, size_t* posFin) { //variable para recorrer bucles size_t i=0; //variable indicadora de búsqueda secuencial int busca=0; //variables para calcular posiciones size_t pos1=0,pos2=0; //posiciones en memoria size_t posm=0,pos1m=0,pos2m=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //CONSIDERAMOS QUE LA LISTA CONTIENE ENTEROS EQUIESPACIADOS UNA UNIDAD //posición del valor anterior al de trabajo pos1 = (size_t)(floor(valor)-lista[0]); //posición del valor posterior al de trabajo pos2 = (size_t)(ceil(valor)-lista[0]); //si pos1==pos2, valor puede ser un extremo de la lista if(pos1==pos2) { if(pos1!=(nDatos-1)) { //calculamos el punto final del segmento pos2++; } else { //calculamos el punto inicial del segmento pos1--; } } //calculamos las posiciones en memoria pos1m = pos1*incDatos; pos2m = pos2*incDatos; //comprobamos si el segmento detectado es válido if((lista[pos1m]!=round(lista[pos1m]))|| (lista[pos2m]!=round(lista[pos2m]))|| ((lista[pos2m]-lista[pos1m])!=1.0)|| (valorlista[pos2m])) { //indicamos que se ha de hacer una búsqueda secuencial busca = 1; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //LA LISTA CONTIENE REALES NO EQUIESPACIADOS if(busca) { //recorremos todos los elementos de la lista for(i=0;i=valor) { //comprobamos el tipo de límite if(lista[posm]>valor) { //extraemos las posiciones pos1 = i-1; pos2 = i; } else { //comprobamos si estamos trabajando con el último elemento if(i==(nDatos-1)) { //extraemos las posiciones pos1 = i-1; pos2 = i; } else { //extraemos las posiciones pos1 = i; pos2 = i+1; } } //salimos del bucle break; } } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos las variables de salida *posInicio = pos1; *posFin = pos2; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void BuscaSegmento1D(const double valor, const double* lista, const size_t nDatos, size_t* posInicio, size_t* posFin) { //realizamos la búsqueda con incremento igual a 1 BuscaSegmento1DInc(valor,lista,nDatos,1,posInicio,posFin); } /******************************************************************************/ /******************************************************************************/ void BuscaPosNWEnMalla(const double xPto, const double yPto, const double xMin, const double xMax, const double yMin, const double yMax, const double pasoX, const double pasoY, size_t* fil, size_t* col) { //dimensiones de la matriz size_t f=0,c=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos las dimensiones de la matriz de trabajo f = (size_t)(round((yMax-yMin)/pasoY)+1.0); c = (size_t)(round((xMax-xMin)/pasoX)+1.0); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos la fila y comprobamos si es el extremo S *fil = (size_t)(fabs(yPto-yMax)/pasoY); if(*fil==(f-1)) { //retrasamos una fila (*fil)--; } //calculamos la columna y comprobamos si es el extremo E *col = (size_t)((xPto-xMin)/pasoX); if(*col==(c-1)) { //retrasamos una columna (*col)--; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ double Minimo(const double* lista, const size_t nDatos, const size_t incDatos) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //variable de salida, inicializada como el máximo valor para un double double salida=DBL_MAX; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP, sólo si la versión es superior a la 3.0 //en versiones anteriores no existe la posibilidad de usar reduction(min:) #if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1) #pragma omp parallel for default(none) \ shared(lista) \ private(i,pos) \ reduction(min:salida) #endif //recorremos el resto de elementos de la lista for(i=0;i fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ double Maximo(const double* lista, const size_t nDatos, const size_t incDatos) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //variable de salida, inicializada como el mínimo valor para un double double salida=DBL_MIN; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP, sólo si la versión es superior a la 3.0 //en versiones anteriores no existe la posibilidad de usar reduction(max:) #if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1) #pragma omp parallel for default(none) \ shared(lista) \ private(i,pos) \ reduction(max:salida) #endif //recorremos el resto de elementos de la lista for(i=0;isalida) { //asignamos el nuevo valor menor salida = lista[pos]; } } // --> fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ double MinimoAbs(const double* lista, const size_t nDatos, const size_t incDatos) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //variable de salida, inicializada como el máximo valor para un double double salida=DBL_MAX; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP, sólo si la versión es superior a la 3.0 //en versiones anteriores no existe la posibilidad de usar reduction(min:) #if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1) #pragma omp parallel for default(none) \ shared(lista) \ private(i,pos) \ reduction(min:salida) #endif //recorremos el resto de elementos de la lista for(i=0;i fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ double MaximoAbs(const double* lista, const size_t nDatos, const size_t incDatos) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //variable de salida, inicializada como 0.0 (trabajamos en valor absoluto) double salida=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP, sólo si la versión es superior a la 3.0 //en versiones anteriores no existe la posibilidad de usar reduction(max:) #if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1) #pragma omp parallel for default(none) \ shared(lista) \ private(i,pos) \ reduction(max:salida) #endif //recorremos el resto de elementos de la lista for(i=0;isalida) { //asignamos el nuevo valor menor salida = fabs(lista[pos]); } } // --> fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ size_t MinimoSizeT(const size_t* lista, const size_t nDatos, const size_t incDatos) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //variable de salida, inicializada como el máximo valor para un size_t size_t salida=SIZE_MAX; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP, sólo si la versión es superior a la 3.0 //en versiones anteriores no existe la posibilidad de usar reduction(min:) #if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1) #pragma omp parallel for default(none) \ shared(lista) \ private(i,pos) \ reduction(min:salida) #endif //recorremos el resto de elementos de la lista for(i=0;i fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ size_t MaximoSizeT(const size_t* lista, const size_t nDatos, const size_t incDatos) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //variable de salida, inicializada como 0 (size_t es sólo positivo) size_t salida=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP, sólo si la versión es superior a la 3.0 //en versiones anteriores no existe la posibilidad de usar reduction(max:) #if defined(_OPENMP)&&(_OPENMP>=GEOC_OMP_F_3_1) #pragma omp parallel for default(none) \ shared(lista) \ private(i,pos) \ reduction(max:salida) #endif //recorremos el resto de elementos de la lista for(i=0;isalida) { //asignamos el nuevo valor menor salida = lista[pos]; } } // --> fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ void MinMax(const double* lista, const size_t nDatos, const size_t incDatos, size_t* posMin, size_t* posMax) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //consideramos que el primer elemento es el mayor y el menor *posMin = 0; *posMax = 0; //recorremos el resto de elementos de la lista for(i=1;ilista[(*posMax)*incDatos]) { //asignamos la nueva posición *posMax = i; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void MinMaxAbs(const double* lista, const size_t nDatos, const size_t incDatos, size_t* posMin, size_t* posMax) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //consideramos que el primer elemento es el mayor y el menor *posMin = 0; *posMax = 0; //recorremos el resto de elementos de la lista for(i=1;ifabs(lista[(*posMax)*incDatos])) { //asignamos la nueva posición *posMax = i; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void MinMaxSizeT(const size_t* lista, const size_t nDatos, const size_t incDatos, size_t* posMin, size_t* posMax) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //consideramos que el primer elemento es el mayor y el menor *posMin = 0; *posMax = 0; //recorremos el resto de elementos de la lista for(i=1;ilista[(*posMax)*incDatos]) { //asignamos la nueva posición *posMax = i; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ double** AsigMemMatrizC(const size_t fil, const size_t col) { //índices para recorrer bucles size_t i=0; //matriz de salida double** matriz=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos memoria para el array principal matriz = (double**)malloc(fil*sizeof(double*)); //comprobamos los errores if(matriz==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos toda la memoria al primer puntero matriz[0] = (double*)malloc(fil*col*sizeof(double)); //comprobamos los errores if(matriz[0]==NULL) { //liberamos la memoria previamente asignada free(matriz); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //recorremos el resto de filas for(i=1;ix)&&(x>xB)); } else { //segmento vertical, utilizamos las coordenadas Y cod = ((yAy)&&(y>yB)); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return cod; } /******************************************************************************/ /******************************************************************************/ int PtoComunSegmParalelos2D(const double xA, const double yA, const double xB, const double yB, const double xC, const double yC, const double xD, const double yD, double* x, double* y) { //variable de salida int cod=GEOC_SEG_NO_INTERSEC; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si los puntos son colineales if(!TresPuntosColineales2D(xA,yA,xB,yB,xC,yC)) { //los segmentos son paralelos, pero no se cortan return GEOC_SEG_NO_INTERSEC; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si los segmentos son el mismo if(((xA==xC)&&(yA==yC)&&(xB==xD)&&(yB==yD))|| ((xA==xD)&&(yA==yD)&&(xB==xC)&&(yB==yC))) { //coordenadas de salida *x = xA; *y = yA; //los segmentos son el mismo return GEOC_SEG_INTERSEC_MISMO_SEG; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si algún punto está entre medias del otro segmento if(PuntoEntreDosPuntos2DColin(xA,yA,xC,yC,xD,yD)) { //el punto A está en el segmento CD *x = xA; *y = yA; //salimos return GEOC_SEG_INTERSEC_COLIN; } else if(PuntoEntreDosPuntos2DColin(xC,yC,xA,yA,xB,yB)) { //el punto C está en el segmento AB *x = xC; *y = yC; //salimos return GEOC_SEG_INTERSEC_COLIN; } else if(PuntoEntreDosPuntos2DColin(xB,yB,xC,yC,xD,yD)) { //el punto B está en el segmento CD *x = xB; *y = yB; //salimos return GEOC_SEG_INTERSEC_COLIN; } else if(PuntoEntreDosPuntos2DColin(xD,yD,xA,yA,xB,yB)) { //el punto D está en el segmento AB *x = xD; *y = yD; //salimos return GEOC_SEG_INTERSEC_COLIN; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si sólo comparten el extremo A if(((xA==xC)&&(yA==yC))||((xA==xD)&&(yA==yD))) { //coordenadas de salida *x = xA; *y = yA; //los segmentos comparten un extremo return GEOC_SEG_INTERSEC_EXTREMO_COLIN; } //comprobamos si sólo comparten el extremo B if(((xB==xC)&&(yB==yC))||((xB==xD)&&(yB==yD))) { //coordenadas de salida *x = xB; *y = yB; //los segmentos comparten un extremo return GEOC_SEG_INTERSEC_EXTREMO_COLIN; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return cod; } /******************************************************************************/ /******************************************************************************/ int IntersecSegmentos2D(const double xA, const double yA, const double xB, const double yB, const double xC, const double yC, const double xD, const double yD, double* x, double* y) { //parámetros de las ecuaciones double s=0.0,t=0.0,num=0.0,den=0.0; //variable de salida int cod=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si los rectángulos que encierran a los segmentos son disjuntos if(RectDisjuntos(GEOC_MIN(xA,xB),GEOC_MAX(xA,xB),GEOC_MIN(yA,yB), GEOC_MAX(yA,yB),GEOC_MIN(xC,xD),GEOC_MAX(xC,xD), GEOC_MIN(yC,yD),GEOC_MAX(yC,yD))) { //si los rectángulos son disjuntos, los segmentos no se tocan cod = GEOC_SEG_NO_INTERSEC; //salimos de la función return cod; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el denominador den = xA*(yD-yC)+xB*(yC-yD)+xD*(yB-yA)+xC*(yA-yB); //si el denominador es 0.0, los segmentos son paralelos if(den==0.0) { //calculamos el punto común cod = PtoComunSegmParalelos2D(xA,yA,xB,yB,xC,yC,xD,yD,x,y); //salimos de la función return cod; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el numerador num = xA*(yD-yC)+xC*(yA-yD)+xD*(yC-yA); //un extremo de un segmento puede estar encima del otro segmento, pero los //segmentos no son colineales if((num==0.0)||(num==den)) { //asignamos la variable de salida cod = GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN; } //calculamos el parámetro s s = num/den; //calculamos de nuevo el numerador num = -(xA*(yC-yB)+xB*(yA-yC)+xC*(yB-yA)); //un extremo de un segmento puede estar encima del otro segmento, pero los //segmentos no son colineales if((num==0.0)||(num==den)) { //asignamos la variable de salida cod = GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN; } //calculamos el parámetro t t = num/den; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si estamos ante una intersección pura y dura o los segmentos //no se cortan if((s>0.0)&&(s<1.0)&&(t>0.0)&&(t<1.0)) { //asignamos la variable de salida cod = GEOC_SEG_INTERSEC; } else if((s<0.0)||(s>1.0)||(t<0.0)||(t>1.0)) { //asignamos la variable de salida cod = GEOC_SEG_NO_INTERSEC; } //calculamos las coordenadas del punto intersección *x = xA+s*(xB-xA); *y = yA+s*(yB-yA); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return cod; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/ptopol.c0000644000175000017500000012112612035672422016162 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file ptopol.c \brief Declaración de funciones para la realización de chequeos de inclusión de puntos en polígonos. En el momento de la compilación ha de seleccionarse el tipo de dato que se utilizará en los cálculos intermedios de las funciones \ref PtoEnPoligonoVerticeBorde y \ref PtoEnPoligonoVerticeBordeDouble. Si los puntos de trabajo están muy alejados de los polígonos pueden darse casos de resultados erróneos. Sería conveniente que los cálculos internedios se hiciesen en variables de 64 bits, pero el tipo long int suele ser de 4 bytes en procesadores de 32 bits. Para seleccionar este tipo como long long int, lo que en procesadores de 32 bits equivale a una variable de 64 bits, es necesario definir la variable para el preprocesador \em PTOPOL_BORDE_LONG_64. En procesadores de 64 bits no es necesario (aunque puede utilizarse), ya que el tipo long int tiene una longitud de 64 bits. Si no se define la variable, se usará un tipo long int para los cálculos intermedios. En \p gcc, las variables para el preprocesador se pasan como \em -DXXX, donde \em XXX es la variable a introducir. El uso del tipo long long int en procesadores de 32 bits puede hacer que las funciones se ejecuten hasta 10 veces más lentamente que si se utiliza el tipo long int. Con cálculos internos de 32 bits las coordenadas de los vértices del polígono no han de estar más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas 3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto podríamos chequear un punto en un polo con respecto a un polígono en el ecuador en coordenadas UTM expresadas en centímetros. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 05 de abril de 2010 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/ptopol.h" /******************************************************************************/ /******************************************************************************/ int GeocParOmpPtopol(char version[]) { //comprobamos si hay paralelización #if defined(_OPENMP) //comprobamos si hay que extraer versión if(version!=NULL) { //calculamos la versión VersionOpenMP(_OPENMP,version); } //salimos de la función return 1; #else if(version!=NULL) { //utilizamos la variable version para que no dé warming al compilar strcpy(version,""); } //salimos de la función return 0; #endif } /******************************************************************************/ /******************************************************************************/ int GeocLongLongIntPtopol(void) { //comprobamos si se ha pasado la variable del preprocesador #if defined(PTOPOL_BORDE_LONG_64) return 1; #else return 0; #endif } /******************************************************************************/ /******************************************************************************/ int PtoEnRectangulo(const double x, const double y, const double xMin, const double xMax, const double yMin, const double yMax) { //posibles posiciones del punto if((xxMax)||(yyMax)) { //punto fuera return GEOC_PTO_FUERA_POLIG; } else if((x>xMin)&&(xyMin)&&(y=xMin2)&&(xMax1<=xMax2)&&(yMin1>=yMin2)&&(yMax1<=yMax2)) { //el rectángulo está contenido sal = 1; } } else { //el borde no se tiene en cuenta if((xMin1>xMin2)&&(xMax1yMin2)&&(yMax1xMax2)||(xMax1yMax2)||(yMax1y)!=(coorY[posJY]>y))&& (x<(coorX[posJX]-coorX[posIX])*(y-coorY[posIY])/ (coorY[posJY]-coorY[posIY])+coorX[posIX])) { c = !c; } } //asignamos el elemento de salida if(c) { //el punto está dentro del polígono c = GEOC_PTO_DENTRO_POLIG; } else { //el punto está fuera del polígono c = GEOC_PTO_FUERA_POLIG; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return c; } /******************************************************************************/ /******************************************************************************/ int PtoEnPoligonoVertice(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY) { //índice para recorrer bucles size_t i=0; //variable de salida, que inicializamos fuera del polígono int pos=GEOC_PTO_FUERA_POLIG; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si el punto es un vértice for(i=0;i0)!=(cy1>0); Lstrad = (cy<0)!=(cy1<0); //straddle computation if(Rstrad||Lstrad) { //compute intersection of e with x axis X = ((double)(cx*cy1-cx1*cy))/((double)(cy1-cy)); //crosses ray if strictly positive intersection if(Rstrad&&(X>0.0)) { Rcross++; } //crosses ray if strictly negative intersection if(Lstrad&&(X<0.0)) { Lcross++; } } } //q on the edge if left and right cross are not the same parity if((Rcross%2)!=(Lcross%2)) { //el punto está en un borde return GEOC_PTO_BORDE_POLIG; } //q inside if an odd number of crossings if((Rcross%2)==1) { //el punto es interior return GEOC_PTO_DENTRO_POLIG; } else { //el punto es exterior return GEOC_PTO_FUERA_POLIG; } } /******************************************************************************/ /******************************************************************************/ int PtoEnPoligonoVerticeBordeDouble(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const double factor, const int redondeo) { //NOTA: SE MANTIENEN LOS COMENTARIOS ORIGINALES DE LA FUNCIÓN PARA VARIABLES //DE TIPO ENTERO //índices de vértices size_t i=0,i1=0; //number of (right,left) edge/ray crossings int Rcross=0,Lcross=0; //flags indicating the edge strads the X axis int Rstrad=0,Lstrad=0; //punto a evaluar pasado a número entero ptopol_long fX=0,fY=0; //coordenadas del polígono referidas al punto de trabajo ptopol_long cx=0,cy=0,cx1=0,cy1=0; //número de elementos de trabajo del polígono size_t n=N; //variable auxiliar double X=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si el primer vértice se repite al final if((coorX[0]==coorX[(N-1)*incX])&&(coorY[0]==coorY[(N-1)*incY])) { //trabajamos con todos los vértices, menos el último n = N-1; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //pasamos a número entero el punto a evaluar if(redondeo) { //redondeo fX = (ptopol_long)(round(factor*x)); fY = (ptopol_long)(round(factor*y)); } else { //truncamiento fX = (ptopol_long)(factor*x); fY = (ptopol_long)(factor*y); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //for each edge e=(i-1,i), see if crosses ray for(i=0;i0)!=(cy1>0); Lstrad = (cy<0)!=(cy1<0); //straddle computation if(Rstrad||Lstrad) { //compute intersection of e with x axis X = ((double)(cx*cy1-cx1*cy))/((double)(cy1-cy)); //crosses ray if strictly positive intersection if(Rstrad&&(X>0.0)) { Rcross++; } //crosses ray if strictly negative intersection if(Lstrad&&(X<0.0)) { Lcross++; } } } //q on the edge if left and right cross are not the same parity if((Rcross%2)!=(Lcross%2)) { //el punto está en un borde return GEOC_PTO_BORDE_POLIG; } //q inside if an odd number of crossings if((Rcross%2)==1) { //el punto es interior return GEOC_PTO_DENTRO_POLIG; } else { //el punto es exterior return GEOC_PTO_FUERA_POLIG; } } /******************************************************************************/ /******************************************************************************/ size_t* BuscaGeocNanEnVectores(const double* x, const double* y, const size_t N, const size_t incX, const size_t incY, size_t* nNan) { //índice para recorrer bucles size_t i=0; //identificadores de NaN int esNanX=0,esNanY=0; //vector de salida size_t* salida=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos a 0 el número de NaN encontrados *nNan = 0; //comprobamos una posible salida rápida if(N==0) { //salimos de la función return salida; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos los elementos de los vectores for(i=0;i fin del #pragma omp parallel for } else { //hacemos una comprobación normal pos = PtoEnPoligono(x,y,coorX,coorY,N,incX,incY); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return pos; } /******************************************************************************/ /******************************************************************************/ int PtoEnPoligonoVerticeInd(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, size_t* poli) { //índice para recorrer bucles size_t i=0; //posiciones de inicio de los vértices X e Y size_t iniX=0,iniY=0; //número de elementos del polígono a chequear size_t nElem=0; //variable auxiliar de situación de punto int posAux=0; //variable indicadora de continuación de chequeos size_t continuar=1; //variable de salida int pos=GEOC_PTO_FUERA_POLIG; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el polígono que contiene al punto *poli = 0; //comprobamos si hay valores NaN if(nNan) { //paralelización con OpenMP //utilizo schedule(dynamic) para que los polígonos vayan siendo //chequeados uno a uno según los hilos de ejecución van quedándose //libres //hago esto porque es muy probable que los polígonos vengan listados de //mayor a menor número de vértices y así se podrá trabajar con varios //polígonos pequeños mientras se testea uno grande #if defined(_OPENMP) #pragma omp parallel for default(none) schedule(dynamic) \ shared(continuar,posNan,coorX,coorY,pos,poli) \ private(i,iniX,iniY,nElem,posAux) #endif //recorremos desde el primer NaN hasta el penúltimo for(i=0;i<(nNan-1);i++) { //hacemos que todos los hilos vean la variable continuar actualizada #if defined(_OPENMP) #pragma omp flush(continuar) #endif //comprobamos si hay que continuar chequeando polígonos if(continuar) { //extraemos los datos de definición del polígono DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY, &nElem); //comprobamos la inclusión para el polígono de trabajo posAux = PtoEnPoligonoVertice(x,y,&coorX[iniX],&coorY[iniY], nElem,incX,incY); //me aseguro de que las variables involucradas sean actualizadas //por un hilo cada vez, sin posibilidad de modificación por //varios al mismo tiempo #if defined(_OPENMP) #pragma omp critical #endif { //si el punto no está fuera, no se han de hacer más operaciones //el continuar==1 asegura que nos quedemos con el primer //polígono en que está incluido el punto, ya que una vez que el //hilo con punto encontrado actualice la variable continuar, el //resto con posibles resultados positivos no pasarán este if() if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG)) { //asignamos la variable de salida pos = posAux; //asignamos el polígono que contiene al punto *poli = i; //indicamos que no hay que continuar haciendo pruebas //esta variable se usa para el caso de ejecución en paralelo continuar = 0; //hacemos que todos los hilos vean la variable continuar //actualizada #if defined(_OPENMP) #pragma omp flush(continuar) #endif } } } } // --> fin del #pragma omp parallel for } else { //hacemos una comprobación normal pos = PtoEnPoligonoVertice(x,y,coorX,coorY,N,incX,incY); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return pos; } /******************************************************************************/ /******************************************************************************/ int PtoEnPoligonoVerticeBordeInd(const long x, const long y, const long* coorX, const long* coorY, const size_t N, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, size_t* poli) { //índice para recorrer bucles size_t i=0; //posiciones de inicio de los vértices X e Y size_t iniX=0,iniY=0; //número de elementos del polígono a chequear size_t nElem=0; //variable auxiliar de situación de punto int posAux=0; //variable indicadora de continuación de chequeos size_t continuar=1; //variable de salida int pos=GEOC_PTO_FUERA_POLIG; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el polígono que contiene al punto *poli = 0; //comprobamos si hay valores NaN if(nNan) { //paralelización con OpenMP //utilizo schedule(dynamic) para que los polígonos vayan siendo //chequeados uno a uno según los hilos de ejecución van quedándose //libres //hago esto porque es muy probable que los polígonos vengan listados de //mayor a menor número de vértices y así se podrá trabajar con varios //polígonos pequeños mientras se testea uno grande #if defined(_OPENMP) #pragma omp parallel for default(none) schedule(dynamic) \ shared(continuar,posNan,coorX,coorY,pos,poli) \ private(i,iniX,iniY,nElem,posAux) #endif //recorremos desde el primer NaN hasta el penúltimo for(i=0;i<(nNan-1);i++) { //hacemos que todos los hilos vean la variable continuar actualizada #if defined(_OPENMP) #pragma omp flush(continuar) #endif //comprobamos si hay que continuar chequeando polígonos if(continuar) { //extraemos los datos de definición del polígono DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY, &nElem); //comprobamos la inclusión para el polígono de trabajo posAux = PtoEnPoligonoVerticeBorde(x,y,&coorX[iniX], &coorY[iniY],nElem,incX, incY); //me aseguro de que las variables involucradas sean actualizadas //por un hilo cada vez, sin posibilidad de modificación por //varios al mismo tiempo #if defined(_OPENMP) #pragma omp critical #endif { //si el punto no está fuera, no se han de hacer más operaciones //el continuar==1 asegura que nos quedemos con el primer //polígono en que está incluido el punto, ya que una vez que el //hilo con punto encontrado actualice la variable continuar, el //resto con posibles resultados positivos no pasarán este if() if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG)) { //asignamos la variable de salida pos = posAux; //asignamos el polígono que contiene al punto *poli = i; //indicamos que no hay que continuar haciendo pruebas //esta variable se usa para el caso de ejecución en paralelo continuar = 0; //hacemos que todos los hilos vean la variable continuar //actualizada #if defined(_OPENMP) #pragma omp flush(continuar) #endif } } } } // --> fin del #pragma omp parallel for } else { //hacemos una comprobación normal pos = PtoEnPoligonoVerticeBorde(x,y,coorX,coorY,N,incX,incY); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return pos; } /******************************************************************************/ /******************************************************************************/ int PtoEnPoligonoVerticeBordeDoubleInd(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const double factor, const int redondeo, const size_t* posNan, const size_t nNan, size_t* poli) { //índice para recorrer bucles size_t i=0; //posiciones de inicio de los vértices X e Y size_t iniX=0,iniY=0; //número de elementos del polígono a chequear size_t nElem=0; //variable auxiliar de situación de punto int posAux=0; //variable indicadora de continuación de chequeos size_t continuar=1; //variable de salida int pos=GEOC_PTO_FUERA_POLIG; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el polígono que contiene al punto *poli = 0; //comprobamos si hay valores NaN if(nNan) { //paralelización con OpenMP //utilizo schedule(dynamic) para que los polígonos vayan siendo //chequeados uno a uno según los hilos de ejecución van quedándose //libres //hago esto porque es muy probable que los polígonos vengan listados de //mayor a menor número de vértices y así se podrá trabajar con varios //polígonos pequeños mientras se testea uno grande #if defined(_OPENMP) #pragma omp parallel for default(none) schedule(dynamic) \ shared(continuar,posNan,coorX,coorY,pos,poli) \ private(i,iniX,iniY,nElem,posAux) #endif //recorremos desde el primer NaN hasta el penúltimo for(i=0;i<(nNan-1);i++) { //hacemos que todos los hilos vean la variable continuar actualizada #if defined(_OPENMP) #pragma omp flush(continuar) #endif //comprobamos si hay que continuar chequeando polígonos if(continuar) { //extraemos los datos de definición del polígono DatosPoliIndividualEnVecInd(posNan,i,incX,incY,&iniX,&iniY, &nElem); //comprobamos la inclusión para el polígono de trabajo posAux = PtoEnPoligonoVerticeBordeDouble(x,y,&coorX[iniX], &coorY[iniY],nElem, incX,incY,factor, redondeo); //me aseguro de que las variables involucradas sean actualizadas //por un hilo cada vez, sin posibilidad de modificación por //varios al mismo tiempo #if defined(_OPENMP) #pragma omp critical #endif { //si el punto no está fuera, no se han de hacer más operaciones //el continuar==1 asegura que nos quedemos con el primer //polígono en que está incluido el punto, ya que una vez que el //hilo con punto encontrado actualice la variable continuar, el //resto con posibles resultados positivos no pasarán este if() if((continuar==1)&&(posAux!=GEOC_PTO_FUERA_POLIG)) { //asignamos la variable de salida pos = posAux; //asignamos el polígono que contiene al punto *poli = i; //indicamos que no hay que continuar haciendo pruebas //esta variable se usa para el caso de ejecución en paralelo continuar = 0; //hacemos que todos los hilos vean la variable continuar //actualizada #if defined(_OPENMP) #pragma omp flush(continuar) #endif } } } } // --> fin del #pragma omp parallel for } else { //hacemos una comprobación normal pos = PtoEnPoligonoVerticeBordeDouble(x,y,coorX,coorY,N,incX,incY, factor,redondeo); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return pos; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/octclip.h0000644000175000017500000000277312035672422016315 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /* Copyright (C) 2011 José Luis García Pallero, * * This file is part of OctCLIP. * * OctCLIP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, see * . */ /******************************************************************************/ /******************************************************************************/ #ifndef _OCTCLIP_H_ #define _OCTCLIP_H_ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/geom.h" /******************************************************************************/ /******************************************************************************/ #endif /******************************************************************************/ /******************************************************************************/ geometry/src/octclip/eucli.c0000644000175000017500000002443312035672422015751 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom interp @{ \file eucli.c \brief Definición de funciones para la realización de cálculos de geometría euclídea. \author José Luis García Pallero, jgpallero@gmail.com \date 27 de octubre de 2009 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/eucli.h" /******************************************************************************/ /******************************************************************************/ double Dist2D(const double x1, const double y1, const double x2, const double y2) { //calculamos y salimos de la función return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } /******************************************************************************/ /******************************************************************************/ void Dist2DVC(const double x1, const double y1, const double x2, const double y2, const double varx1, const double varx1y1, const double vary1, const double varx2, const double varx2y2, const double vary2, double* dist, double* varDist) { //matrices auxiliares double j[4],jvc[4]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos la distancia *dist = Dist2D(x1,y1,x2,y2); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //rellenamos la matriz jacobiana j[0] = -(x2-x1)/(*dist); j[1] = -(y2-y1)/(*dist); j[2] = -j[0]; j[3] = -j[1]; //producto de la matriz jacobiana por la matriz de varianza-covarianza jvc[0] = j[0]*varx1+j[1]*varx1y1; jvc[1] = j[0]*varx1y1+j[1]*vary1; jvc[2] = j[2]*varx2+j[3]*varx2y2; jvc[3] = j[2]*varx2y2+j[3]*vary2; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //realizamos la propagación de errores *varDist = jvc[0]*j[0]+jvc[1]*j[1]+jvc[2]*j[2]+jvc[3]*j[3]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ double Dist3D(const double x1, const double y1, const double z1, const double x2, const double y2, const double z2) { //calculamos y salimos de la función return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)); } /******************************************************************************/ /******************************************************************************/ void Dist3DVC(const double x1, const double y1, const double z1, const double x2, const double y2, const double z2, const double varx1, const double varx1y1, const double varx1z1, const double vary1, const double vary1z1, const double varz1, const double varx2, const double varx2y2, const double varx2z2, const double vary2, const double vary2z2, const double varz2, double* dist, double* varDist) { //matrices auxiliares double j[6],jvc[6]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos la distancia *dist = Dist3D(x1,y1,z1,x2,y2,z2); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //rellenamos la matriz jacobiana j[0] = -(x2-x1)/(*dist); j[1] = -(y2-y1)/(*dist); j[2] = -(z2-z1)/(*dist); j[3] = -j[0]; j[4] = -j[1]; j[5] = -j[2]; //producto de la matriz jacobiana por la matriz de varianza-covarianza jvc[0] = j[0]*varx1+j[1]*varx1y1+j[2]*varx1z1; jvc[1] = j[0]*varx1y1+j[1]*vary1+j[2]*vary1z1; jvc[2] = j[0]*varx1z1+j[1]*vary1z1+j[2]*varz1; jvc[3] = j[3]*varx2+j[4]*varx2y2+j[5]*varx2z2; jvc[4] = j[3]*varx2y2+j[4]*vary2+j[5]*vary2z2; jvc[5] = j[3]*varx2z2+j[4]*vary2z2+j[5]*varz2; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //realizamos la propagación de errores *varDist = jvc[0]*j[0]+jvc[1]*j[1]+jvc[2]*j[2]+jvc[3]*j[3]+jvc[4]*j[4]+ jvc[5]*j[5]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ double AnguloVecPlano(const double x1, const double y1, const double x2, const double y2) { //variables auxiliares double num=0.0,den=0.0; //variable de salida double alfa=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el numerador de la fórmula que da el coseno del ángulo num = x1*x2+y1*y2; //calculamos el denominador de la fórmula que da el coseno del ángulo den = sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2)); //calculamos el coseno del ángulo, teniendo en cuenta casos singulares if(den==0.0) { //si el denominador es 0.0, el ángulo es 0.0 y su coseno 1.0 alfa = 1.0; } else { //no hay singularidad alfa = num/den; } //calculamos el ángulo alfa = acos(alfa); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return alfa; } /******************************************************************************/ /******************************************************************************/ double AlturaTriangulo(const double xVert, const double yVert, const double xBase1, const double yBase1, const double xBase2, const double yBase2) { //ángulo entra la base en el punto 1 y el vértice double alfa=0.0; //longitud del punto 1 de la base al vértice double lon=0.0; //variables auxiliares double dxv=0.0,dyv=0.0,dxb=0.0,dyb=0.0; //variable de salida double h=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos los incrementos de coordenadas auxiliares dxv = xVert-xBase1; dyv = yVert-yBase1; dxb = xBase2-xBase1; dyb = yBase2-yBase1; //calculamos el ángulo entre la base y el segmento que une el punto inicial //de ésta con el vértice alfa = AnguloVecPlano(dxv,dyv,dxb,dyb); //longitud del lado que une la base con el vértice 1 de la base lon = sqrt(dxv*dxv+dyv*dyv); //calculamos la altura h = fabs(lon*sin(alfa)); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return h; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/polil.c0000755000175000017500000016072612035672422016000 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file polil.c \brief Definición de funciones para el trabajo con polilíneas. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 03 de junio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/polil.h" /******************************************************************************/ /******************************************************************************/ int GeocParOmpPolil(char version[]) { //comprobamos si hay paralelización #if defined(_OPENMP) //comprobamos si hay que extraer versión if(version!=NULL) { //calculamos la versión VersionOpenMP(_OPENMP,version); } //salimos de la función return 1; #else if(version!=NULL) { //utilizamos la variable version para que no dé warming al compilar strcpy(version,""); } //salimos de la función return 0; #endif } /******************************************************************************/ /******************************************************************************/ polil* IniciaPolilVacia(void) { //estructura de salida polil* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos memoria para la estructura sal = (polil*)malloc(sizeof(polil)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //inicializamos los campos escalares a 0 sal->nElem = 0; sal->nPolil = 0; sal->hayLim = 0; //inicializamos los campos vectoriales a NULL sal->x = NULL; sal->y = NULL; sal->posIni = NULL; sal->nVert = NULL; sal->xMin = NULL; sal->xMax = NULL; sal->yMin = NULL; sal->yMax = NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ int AuxCreaPolil1(const size_t nElem, const size_t* posNanX, const size_t* posNanY, const size_t nNanX, const size_t nNanY, size_t* nElemMax, size_t* nPolil) { //índice para recorrer bucles size_t i=0; //variable de salida int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay el mismo número de NaN en los dos vectores if(nNanX!=nNanY) { //salimos de la función return GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL; } //comprobamos si hay NaN en las mismas posiciones de los vectores for(i=0;i fin del #pragma omp parallel sections //comprobamos los posibles errores de asignación de memoria if(((posNanX==NULL)&&(nNanX!=0))||((posNanY==NULL)&&(nNanY!=0))) { //liberamos la memoria asignada LibMemPolil(sal); free(posNanX); free(posNanY); //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si los vectores tienen bien colocados los NaN y calculamos //el número máximo de elementos de los vectores de la estructura y el //número de polilíneas *idError = AuxCreaPolil1(nElem,posNanX,posNanY,nNanX,nNanY,&nElemMax, &nPolil); //comprobamos los posibles errores if(*idError!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(sal); free(posNanX); free(posNanY); //escribimos el mensaje de error if(*idError==GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL) { GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo " "número de polilíneas"); } else if(*idError==GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL) { GEOC_ERROR("Error: Los vectores de trabajo no contienen las mismas " "polilíneas"); } //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos el número de polilíneas sal->nPolil = nPolil; //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(sal,nElemMax,nPolil) #endif { //asignamos memoria para los vectores de la estructura #if defined(_OPENMP) #pragma omp section #endif sal->x = (double*)malloc(nElemMax*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif sal->y = (double*)malloc(nElemMax*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif sal->posIni = (size_t*)malloc(nPolil*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif sal->nVert = (size_t*)malloc(nPolil*sizeof(double)); } // --> fin del #pragma omp parallel sections //comprobamos los posibles errores if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL)) { //liberamos la memoria asignada LibMemPolil(sal); free(posNanX); free(posNanY); //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //copiamos las polilíneas a la estructura //como ya sabemos que el número de NaN y sus posiciones son los mismos para //los vectores x e y, trabajamos con los valores para el vector x AuxCreaPolil3(x,y,nElem,incX,incY,posNanX,nNanX,sal->x,sal->y,sal->posIni, sal->nVert,&ptos,&nPolil); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay de verdad alguna polilínea if(nPolil==0) { //liberamos la memoria asignada LibMemPolil(sal); free(posNanX); free(posNanY); //creamos la estructura vacía sal = IniciaPolilVacia(); //comprobamos los posibles errores if(sal==NULL) { //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //salimos de la función return sal; } //asignamos el número de elementos a la estructura sal->nElem = ptos; //comprobamos si hay que reajustar el tamaño de los vectores de coordenadas if(ptos!=nElemMax) { //asignamos el nuevo tamaño de los vectores sal->nElem = ptos; //reajustamos los tamaños sal->x = (double*)realloc(sal->x,ptos*sizeof(double)); sal->y = (double*)realloc(sal->y,ptos*sizeof(double)); } //comprobamos si el número de polilíneas es el estimado if(nPolil!=sal->nPolil) { //asignamos de nuevo la variable de número de polilíneas sal->nPolil = nPolil; //reajustamos los tamaños sal->posIni = (size_t*)realloc(sal->posIni,nPolil*sizeof(size_t)); sal->nVert = (size_t*)realloc(sal->nVert,nPolil*sizeof(size_t)); } //comprobamos los posibles errores if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL)) { //liberamos la memoria asignada LibMemPolil(sal); free(posNanX); free(posNanY); //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria asignada free(posNanX); free(posNanY); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ void EnlazaCamposPolil(polil* poliEnt, polil* poliSal) { //LIBERAMOS LA POSIBLE MEMORIA ASIGNADA A LOS CAMPOS VECTORIALES DE LA //ESTRUCTURA DE SALIDA //comprobamos si hay algún elemento en los vectores de coordenadas if(poliSal->nElem) { free(poliSal->x); free(poliSal->y); } //comprobamos si hay alguna polilínea en los vectores de posiciones if(poliSal->nPolil) { free(poliSal->posIni); free(poliSal->nVert); } //comprobamos si hay límites calculados if(poliSal->hayLim) { free(poliSal->xMin); free(poliSal->xMax); free(poliSal->yMin); free(poliSal->yMax); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //enlazamos todos los campos de la estructura de entrada en la de salida poliSal->nElem = poliEnt->nElem; poliSal->x = poliEnt->x; poliSal->y = poliEnt->y; poliSal->nPolil = poliEnt->nPolil; poliSal->posIni = poliEnt->posIni; poliSal->nVert = poliEnt->nVert; poliSal->hayLim = poliEnt->hayLim; poliSal->xMin = poliEnt->xMin; poliSal->xMax = poliEnt->xMax; poliSal->yMin = poliEnt->yMin; poliSal->yMax = poliEnt->yMax; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ polil* CopiaPolil(const polil* poli, int* idError) { //polilínea de salida polil* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la variable de error *idError = GEOC_ERR_NO_ERROR; //inicializamos la polilínea de salida sal = IniciaPolilVacia(); //comprobamos los posibles errores if(sal==NULL) { //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //sólo continuamos si la polilínea de entrada contiene datos if(poli->nElem) { //copiamos las coordenadas de los vértices *idError = AnyadeDatosPolil(sal,poli->x,poli->y,poli->nElem,1,1); //comprobamos si ha ocurrido algún error if((*idError)!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(sal); //escribimos el mensaje de error if((*idError)==GEOC_ERR_ASIG_MEMORIA) { GEOC_ERROR("Error de asignación de memoria"); } else if((*idError)==GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL) { GEOC_ERROR("Error: Los vectores de coordenadas de la\n" "polilínea de entrada no contienen el mismo número " "de polilíneas"); } else if((*idError)==GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL) { GEOC_ERROR("Error: Los vectores de coordenadas de la\n" "polilínea de entrada no contienen las mismas " "polilíneas"); } //salimos de la función return NULL; } //comprobamos si hay que calcular límites if(poli->hayLim) { //calculamos los límites *idError = CalcLimitesPolil(sal); //comprobamos los posibles errores if((*idError)!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(sal); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ int AnyadePolilPolil(polil* poli, const polil* anyade) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //número total de elementos size_t nElem=0,nPolil=0; //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //si la polilínea a añadir está vacía, salimos de la función if((anyade!=NULL)&&(anyade->nPolil==0)) { //salimos de la función sin hacer nada return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el número total de elementos de la polilínea conjunta nElem = poli->nElem+anyade->nElem; //si la polilínea original contenía datos, al número total de elementos hay //que restarle 1 por el NaN común que sobra al juntar las dos estructuras if(poli->nPolil) { nElem--; } //calculamos el número total de polilíneas nPolil = poli->nPolil+anyade->nPolil; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //reasignamos memoria para cubrir los nuevos datos poli->x = (double*)realloc(poli->x,nElem*sizeof(double)); poli->y = (double*)realloc(poli->y,nElem*sizeof(double)); poli->posIni = (size_t*)realloc(poli->posIni,nPolil*sizeof(size_t)); poli->nVert = (size_t*)realloc(poli->nVert,nPolil*sizeof(size_t)); //reasignamos también para los posibles vectores de límites if(poli->hayLim) { poli->xMin = (double*)realloc(poli->xMin,nPolil*sizeof(double)); poli->xMax = (double*)realloc(poli->xMax,nPolil*sizeof(double)); poli->yMin = (double*)realloc(poli->yMin,nPolil*sizeof(double)); poli->yMax = (double*)realloc(poli->yMax,nPolil*sizeof(double)); } //comprobamos los posibles errores en las asignaciones obligatorias if((poli->x==NULL)||(poli->y==NULL)||(poli->posIni==NULL)|| (poli->nVert==NULL)) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //comprobamos los posibles errores en las asignaciones de límites if(poli->hayLim) { if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)|| (poli->yMax==NULL)) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos la posición de inicio para copiar en la estructura de salida //si la estructura de salida está vacía, se comienza en la primera posición //si tiene datos, se comienza a continuación en la última (dentro del bucle, //la suma de posIni hace que se comience a continuación de la última) pos = (poli->nPolil==0) ? 0 : poli->nElem-1; //recorremos el número de nuevos elementos for(i=0;inElem;i++) { //copiamos las coordenadas poli->x[pos+i] = anyade->x[i]; poli->y[pos+i] = anyade->y[i]; } //calculamos las posiciones a sumar para ajustar las posiciones de inicio de //las polilíneas añadidas //si la estructura de salida está vacía, se copian las posiciones tal cual //si tiene datos, se suman las posiciones ya ocupadas pos = (poli->nPolil==0) ? 0 : poli->nElem-1; //recorremos el número de polilíneas for(i=0;inPolil;i++) { //copiamos las posiciones de inicio actualizadas y el número de vértices poli->posIni[poli->nPolil+i] = anyade->posIni[i]+pos; poli->nVert[poli->nPolil+i] = anyade->nVert[i]; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que calcular límites if(poli->hayLim) { //comprobamos si ya están calculados if(anyade->hayLim) { //recorremos el número de polilíneas y copiamos los límites for(i=0;inPolil;i++) { //copiamos los límites poli->xMin[poli->nPolil+i] = anyade->xMin[i]; poli->xMax[poli->nPolil+i] = anyade->xMax[i]; poli->yMin[poli->nPolil+i] = anyade->yMin[i]; poli->yMax[poli->nPolil+i] = anyade->yMax[i]; } } else { //calculamos los límites y los copiamos LimitesPoligonosPolig(&(anyade->x[1]),&(anyade->y[1]),1,1, anyade->posIni,anyade->nVert,anyade->nPolil, anyade->posIni[0],&(poli->xMin[poli->nPolil]), &(poli->xMax[poli->nPolil]), &(poli->yMin[poli->nPolil]), &(poli->yMax[poli->nPolil])); } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ajustamos los tamaños antes de salir poli->nElem = nElem; poli->nPolil = nPolil; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ int AnyadeDatosPolil(polil* poli, const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY) { //polilínea auxiliar polil* aux=NULL; //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contemplamos una posible salida rápida if(nElem==0) { //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos una nueva polilínea con los datos a añadir aux = CreaPolil(x,y,nElem,incX,incY,&estado); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(aux); //escribimos el mensaje de error if(estado==GEOC_ERR_ASIG_MEMORIA) { GEOC_ERROR("Error de asignación de memoria"); } else if(estado==GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL) { GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo " "número de polilíneas"); } else if(estado==GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL) { GEOC_ERROR("Error: Los vectores de trabajo no contienen las mismas " "polilíneas"); } //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //añadimos la nueva estructura estado = AnyadePolilPolil(poli,aux); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria utilizada LibMemPolil(aux); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ void LibMemPolil(polil* datos) { //comprobamos si hay memoria que liberar if(datos!=NULL) { //liberamos la memoria asignada al vector de coordenadas X if(datos->x!=NULL) { free(datos->x); } //liberamos la memoria asignada al vector de coordenadas Y if(datos->y!=NULL) { free(datos->y); } //liberamos la memoria asignada al vector de posiciones if(datos->posIni!=NULL) { free(datos->posIni); } //liberamos la memoria asignada al vector de número de vértices if(datos->nVert!=NULL) { free(datos->nVert); } //liberamos la memoria asignada a los vector de coordenadas X mínimas if(datos->xMin!=NULL) { free(datos->xMin); } //liberamos la memoria asignada a los vector de coordenadas X máximas if(datos->xMax!=NULL) { free(datos->xMax); } //liberamos la memoria asignada a los vector de coordenadas Y mínimas if(datos->yMin!=NULL) { free(datos->yMin); } //liberamos la memoria asignada a los vector de coordenadas Y máximas if(datos->yMax!=NULL) { free(datos->yMax); } //liberamos la memoria asignada a la estructura free(datos); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int CalcLimitesPolil(polil* poli) { //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos salida rápida if((poli->nPolil==0)||(poli->hayLim)) { //salimos de la función si la estructura no contiene polilíneas o si //éstas ya tienen calculados sus límites return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli) #endif { //asignamos memoria para los vectores de límites #if defined(_OPENMP) #pragma omp section #endif poli->xMin = (double*)malloc((poli->nPolil)*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif poli->xMax = (double*)malloc((poli->nPolil)*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif poli->yMin = (double*)malloc((poli->nPolil)*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif poli->yMax = (double*)malloc((poli->nPolil)*sizeof(double)); } // --> fin del #pragma omp parallel sections //comprobamos los posibles errores if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)|| (poli->yMax==NULL)) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //indicamos que sí hay límites poli->hayLim = 1; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos los límites de todas las polilíneas LimitesPoligonosPolig(poli->x,poli->y,1,1,poli->posIni,poli->nVert, poli->nPolil,0,poli->xMin,poli->xMax,poli->yMin, poli->yMax); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ void EscalaYTrasladaPolil(polil* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim) { //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli) #endif { #if defined(_OPENMP) #pragma omp section #endif //aplicamos los factores de escala y las traslaciones a las coordenadas X EscalaYTrasladaVector(poli->x,poli->nElem,1,escalaX,trasladaX); #if defined(_OPENMP) #pragma omp section #endif //aplicamos los factores de escala y las traslaciones a las coordenadas Y EscalaYTrasladaVector(poli->y,poli->nElem,1,escalaY,trasladaY); } // --> fin del #pragma omp parallel sections //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO //TOTAL DE VÉRTICES //comprobamos si hay que aplicar el factor a los límites if(aplicaLim&&poli->hayLim) { //aplicamos los factores de escala y las traslaciones a los límites EscalaYTrasladaVector(poli->xMin,poli->nPolil,1,escalaX,trasladaX); EscalaYTrasladaVector(poli->xMax,poli->nPolil,1,escalaX,trasladaX); EscalaYTrasladaVector(poli->yMin,poli->nPolil,1,escalaY,trasladaY); EscalaYTrasladaVector(poli->yMax,poli->nPolil,1,escalaY,trasladaY); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void TrasladaYEscalaPolil(polil* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim) { //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli) #endif { #if defined(_OPENMP) #pragma omp section #endif //aplicamos las traslaciones y los factores de escala a las coordenadas X TrasladaYEscalaVector(poli->x,poli->nElem,1,escalaX,trasladaX); #if defined(_OPENMP) #pragma omp section #endif //aplicamos las traslaciones y los factores de escala a las coordenadas Y TrasladaYEscalaVector(poli->y,poli->nElem,1,escalaY,trasladaY); } // --> fin del #pragma omp parallel sections //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO //TOTAL DE VÉRTICES //comprobamos si hay que aplicar el factor a los límites if(aplicaLim&&poli->hayLim) { //aplicamos las traslaciones y los factores de escala a los límites TrasladaYEscalaVector(poli->xMin,poli->nPolil,1,escalaX,trasladaX); TrasladaYEscalaVector(poli->xMax,poli->nPolil,1,escalaX,trasladaX); TrasladaYEscalaVector(poli->yMin,poli->nPolil,1,escalaY,trasladaY); TrasladaYEscalaVector(poli->yMax,poli->nPolil,1,escalaY,trasladaY); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void MuevePolil(polil* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int orden, const int aplicaLim) { //comprobamos el orden de aplicación de los factores if(orden==0) { //primero los factores de escala y luego las traslaciones EscalaYTrasladaPolil(poli,escalaX,escalaY,trasladaX,trasladaY, aplicaLim); } else { //primero las traslaciones y luego los factores de escala TrasladaYEscalaPolil(poli,escalaX,escalaY,trasladaX,trasladaY, aplicaLim); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int AligeraPolil(polil* poli, const double tol, const enum GEOC_DPEUCKER_ROBUSTO robusto, const size_t nPtosRobusto, const size_t nSegRobusto) { //índices para recorrer bucles size_t i=0,j=0; //posición inicial de la polilínea de trabajo y número de puntos aligerados size_t posIni=0,nPtos=0; //polilínea que es un mismo punto int pmp=0; //coordenadas de las polilíneas aligeradas double* x=NULL; double* y=NULL; //estructura auxiliar polil* aux=NULL; //vector de posiciones después del aligerado size_t* pos=NULL; //variable de salida int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos una posible salida rápida if(poli->nPolil==0) { //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar vacía aux = IniciaPolilVacia(); //comprobamos los posibles errores if(aux==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos el número de polilíneas almacenadas for(i=0;inPolil;i++) { //extraemos la posición inicial de la polilínea de trabajo posIni = poli->posIni[i]; //aligeramos la polilínea de trabajo pos = AligeraPolilinea(&(poli->x[posIni]),&(poli->y[posIni]), poli->nVert[i],1,1,tol,robusto,nPtosRobusto, nSegRobusto,&nPtos); //comprobamos posibles errores if(pos==NULL) { //liberamos la memoria asignada LibMemPolil(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //comprobamos si la polilínea se ha quedado en dos puntos if(nPtos==2) { //comprobamos si los tres puntos son colineales pmp = ((poli->x[posIni+pos[0]])==(poli->x[posIni+pos[1]]))&& ((poli->y[posIni+pos[0]])==(poli->y[posIni+pos[1]])); } //comprobamos si después del aligerado todavía queda una polilínea que //no sea un único punto if((nPtos>2)||((nPtos==2)&&(!pmp))) { //asignamos memoria para los vectores de coordenadas de la polilínea //aligerada x = (double*)malloc(nPtos*sizeof(double)); y = (double*)malloc(nPtos*sizeof(double)); //comprobamos posibles errores if((x==NULL)||(y==NULL)) { //liberamos la memoria asignada LibMemPolil(aux); free(pos); free(x); free(y); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //recorremos el número de puntos de la polilínea aligerada for(j=0;jx[posIni+pos[j]]; y[j] = poli->y[posIni+pos[j]]; } //añadimos las coordenadas a la polilínea aligerada estado = AnyadeDatosPolil(aux,x,y,nPtos,1,1); //sólo puede haber ocurrido un error de asignación de memoria, ya //que suponemos que la polilínea de entrada es correcta if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(aux); free(pos); free(x); free(y); //escribimos el mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //liberamos la memoria asignada a los vectores de coordenadas free(x); free(y); } //liberamos la memoria asignada al vector de posiciones del aligerado free(pos); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que calcular límites if(poli->hayLim) { //calculamos los límites estado = CalcLimitesPolil(aux); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolil(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //enlazamos los campos de la estructura auxiliar a los de la estructura de //salida EnlazaCamposPolil(aux,poli); //liberamos la memoria asignada a la estructura auxiliar (pero no a sus //campos) free(aux); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ void ImprimeCabeceraPolilFichero(const polil* poli, const size_t indice, const char iniCab[], const int impLim, const char formCoor[], const double factorX, const double factorY, FILE* idFich) { //número de vértices de la polilínea de trabajo size_t nVert=0; //límites double xMin=0.0,xMax=0.0,yMin=0.0,yMax=0.0,limAux=0.0; //variables de posición size_t pos=0,posXMin=0,posXMax=0,posYMin=0,posYMax=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //número de vértices a imprimir de la polilínea nVert = poli->nVert[indice]; //posición de inicio de la polilínea pos = poli->posIni[indice]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //imprimimos la marca de inicio y el número de vértices fprintf(idFich,"%s %8zu",iniCab,nVert); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que imprimir los límites if(impLim) { //comprobamos si ya están calculados los límites if(poli->hayLim) { //extraemos los límites xMin = poli->xMin[indice]; xMax = poli->xMax[indice]; yMin = poli->yMin[indice]; yMax = poli->yMax[indice]; } else { //buscamos las posiciones de los elementos máximo y mínimo //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli,pos,nVert,posXMin,posXMax,posYMin,posYMax) #endif { //posiciones en el vector X #if defined(_OPENMP) #pragma omp section #endif MinMax(&(poli->x[pos]),nVert,1,&posXMin,&posXMax); //posiciones en el vector Y #if defined(_OPENMP) #pragma omp section #endif MinMax(&(poli->y[pos]),nVert,1,&posYMin,&posYMax); } // --> fin del #pragma omp parallel sections //extraemos los valores extremos xMin = poli->x[pos+posXMin]; xMax = poli->x[pos+posXMax]; yMin = poli->y[pos+posYMin]; yMax = poli->y[pos+posYMax]; } //comprobamos si el factor de escala para X es negativo if(factorX<0.0) { //los límites cambian limAux = xMin; xMin = xMax; xMax = limAux; //aplicamos el factor de escala xMin *= factorX; xMax *= factorX; } //comprobamos si el factor de escala para Y es negativo if(factorY<0.0) { //los límites cambian limAux = yMin; yMin = yMax; yMax = limAux; //aplicamos el factor de escala yMin *= factorY; yMax *= factorY; } //imprimimos los límites fprintf(idFich," "); fprintf(idFich,formCoor,xMin); fprintf(idFich," "); fprintf(idFich,formCoor,xMax); fprintf(idFich," "); fprintf(idFich,formCoor,yMin); fprintf(idFich," "); fprintf(idFich,formCoor,yMax); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salto de línea final fprintf(idFich,"\n"); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void ImprimePolilFichero(const polil* poli, const double factorX, const double factorY, const int iniNan, const int finNan, const char formCoor[], const int impCabecera, const char iniCab[], const int impLim, FILE* idFich) { //índices para recorrer bucles size_t i=0,j=0; //cadena de formato para imprimir los posibles valores NaN char formNan[GEOC_NAN_LON_FORM_NUM_SIMPLE+1]; //variable de posición size_t pos=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si la estructura contiene alguna polilínea if(poli->nPolil==0) { //salimos sin imprimir nada return; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos la cadena de formato para imprimir los polibles NaN FormatoNumFormatoTexto(formCoor,formNan); //comprobamos si hay que imprimir la marca separadora al principio if(iniNan) { //la imprimimos ImprimeGeocNanTexto(idFich,2,formNan,1); } //recorremos el número de polilíneas for(i=0;inPolil;i++) { //comprobamos si hay que imprimir la cabecera if(impCabecera) { //imprimos la cabecera ImprimeCabeceraPolilFichero(poli,i,iniCab,impLim,formCoor,factorX, factorY,idFich); } //posición del punto inicial de la polilínea pos = poli->posIni[i]; //recorremos el número de vértices de la polilínea de trabajo for(j=0;jnVert[i];j++) { //imprimimos las coordenadas, multiplicadas por factor fprintf(idFich,formCoor,factorX*poli->x[pos+j]); fprintf(idFich,formCoor,factorY*poli->y[pos+j]); fprintf(idFich,"\n"); } //imprimimos la marca separadora al final (menos para el último) if(i!=(poli->nPolil-1)) { ImprimeGeocNanTexto(idFich,2,formNan,1); } } //comprobamos si hay que imprimir la marca separadora al final if(finNan) { //la imprimimos ImprimeGeocNanTexto(idFich,2,formNan,1); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/calctopo.c0000644000175000017500000000702712035672422016454 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geodesia geom @{ \file calctopo.c \brief Definición de funciones para cálculos de topografía. \author José Luis García Pallero, jgpallero@gmail.com \date 05 de julio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/calctopo.h" /******************************************************************************/ /******************************************************************************/ double AcimutTopografico(const double x1, const double y1, const double x2, const double y2) { //acimut calculado double acimut=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el acimut en el dominio [-pi pi] acimut = atan2(x2-x1,y2-y1); //comprobamos si ha salido un valor negativo if(acimut<0.0) { //metemos el valor en dominio acimut += 2.0*GEOC_CONST_PI; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return acimut; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/geocnan.c0000755000175000017500000002045212035672422016262 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geocnan geom matriz gshhs @{ \file geocnan.c \brief Definición de funciones para el trabajo con constantes Not-a-Number. \author José Luis García Pallero, jgpallero@gmail.com \date 26 de mayo de 2011 \version 1.0 \section Licencia Licencia Copyright (c) 2010-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/geocnan.h" /******************************************************************************/ /******************************************************************************/ double GeocNan(void) { //devolvemos el valor de NaN //le calculamos el valor absoluto porque, en algunos sistemas, al imprimir //un valor GEOC_NAN normal, éste sale con un signo negativo delante //aclaración a 22 de septiembre de 2011: parecía que con lo del fabs() //estaba solucionado el asunto del signo negativo, pero no es así //la impresión con signo negativo parece que depende de los flags de //optimización al compilar y de los propios compiladores //no obstante, se mantiene el fabs() return fabs(GEOC_NAN); } /******************************************************************************/ /******************************************************************************/ int EsGeocNan(const double valor) { //comparamos y salimos de la función return valor!=valor; } /******************************************************************************/ /******************************************************************************/ size_t* PosGeocNanEnVector(const double* datos, const size_t nDatos, const size_t incDatos, size_t* nNan) { //índice para recorrer bucles size_t i=0; //vector de salida size_t* salida=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos a 0 el número de NaN encontrados *nNan = 0; //comprobamos una posible salida rápida if(nDatos==0) { //salimos de la función return salida; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos los elementos de los vectores for(i=0;i /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_F_1_0 \brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 1.0 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_F_1_0 (199810) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_F_2_0 \brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 2.0 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_F_2_0 (200203) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_F_2_5 \brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 2.5 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_F_2_5 (200505) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_F_3_0 \brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 3.0 de OpenMP. \date 22 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_F_3_0 (200805) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_F_3_1 \brief Valor (fecha YYYYMM) de la macro \p _OPENMP para la versión 3.1 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_F_3_1 (201107) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_V_1_0 \brief Cadena de texto identificadora de la versión 1.0 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_V_1_0 "1.0" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_V_2_0 \brief Cadena de texto identificadora de la versión 2.0 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_V_2_0 "2.0" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_V_2_5 \brief Cadena de texto identificadora de la versión 2.5 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_V_2_5 "2.5" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_V_3_0 \brief Cadena de texto identificadora de la versión 3.0 de OpenMP. \date 22 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_V_3_0 "3.0" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_V_3_1 \brief Cadena de texto identificadora de la versión 3.1 de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_V_3_1 "3.1" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_F_DESC \brief Fecha de versión de OpenMP desconocida. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_F_DESC (0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_V_DESC \brief Versión de OpenMP correspondiente a un valor desconocido de la macro \p _OPENMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_V_DESC "0.0" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_OMP_LON_CAD_VERS \brief Longitud de la cadena de texto que almacena la versión de OpenMP. \date 25 de agosto de 2011: Creación de la constante. */ #define GEOC_OMP_LON_CAD_VERS (10) /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la versión de OpenMP a partir del valor de la macro \p _OPENMP. \param[in] macro_OPENMP Valor de la macro \p _OPENMP. \param[out] version Versión de OpenMP correspondiente al valor de la macro. Si el argumento \em macro_OPENMP almacena un valor desconocido, se devuelve #GEOC_OMP_V_DESC. \note Esta función asume que \em version tiene asignada suficiente memoria: como mínimo, espacio para una cadena de #GEOC_OMP_LON_CAD_VERS carácteres. \date 25 de agosto de 2011: Creación de la función. */ void VersionOpenMP(const int macro_OPENMP, char version[]); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la fecha (el valor de la macro \p _OPENMP) de una versión de OpenMP dada. \param[in] version Cadena de versión de OpenMP, tal como es calculada por la función \ref VersionOpenMP. \return Fecha, en el formato YYYYMM, correspondiente a la versión. Este valor debería coincidir con la macro \p _OPENMP de la implementación de OpenMP usada. \note En caso de pasar una cadena de versión errónea o desconocida, la función devuelve #GEOC_OMP_F_DESC. \date 25 de agosto de 2011: Creación de la función. */ int FechaVersionOpenMP(const char version[]); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/polig.h0000644000175000017500000017030312032305135017360 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file polig.h \brief Definición de estructuras y declaración de funciones para el trabajo con polígonos. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 20 de abril de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _POLIG_H_ #define _POLIG_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include #include"libgeoc/dpeucker.h" #include"libgeoc/errores.h" #include"libgeoc/fgeneral.h" #include"libgeoc/geocnan.h" #include"libgeoc/geocomp.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \struct polig \brief Estructura contenedora de los vértices que definen el contorno de uno o varios polígono. \date 20 de abril de 2011: Creación de la estructura. \date 26 de mayo de 2011: Reorganización total de la estructura. \date 28 de mayo de 2011: Adición de los campos polig::hayArea, polig::area, polig::hayLim, polig::xMin, polig::xMax, polig::yMin e polig::yMax. */ typedef struct { /** \brief Número de elementos de los vectores de coordenadas. */ size_t nElem; /** \brief Vector de polig::nElem elementos, que almacena las coordenadas X de los vértices del polígono (o los polígonos), así como los separadores entre polígonos. La primera coordenada de cada polígono se repite al final. */ double* x; /** \brief Vector de polig::nElem elementos, que almacena las coordenadas Y de los vértices del polígono (o los polígonos), así como los separadores entre polígonos. La primera coordenada de cada polígono se repite al final. */ double* y; /** \brief Número de polígonos almacenados. */ size_t nPolig; /** \brief Vector de polig::nPolig elementos, que almacena las posiciones en los vectores \em x e \em y de inicio de cada polígono almacenado. */ size_t* posIni; /** \brief Vector de polig::nPolig elementos, que almacena el número de vértices de cada polígono almacenado. El último vértice de cada polígono, que es el primero repetido, también entra en la cuenta. */ size_t* nVert; /** \brief Identificador de si la estructura contiene información acerca de los límites del rectángulo que encierra a cada polígono almacenado. Dos posibilidades: - 0: La estructura no contiene información de los límites. - Distinto de 0: La estructura sí contiene información de los límites. */ int hayLim; /** \brief Vector de polig::nPolig elementos, que almacena la coordenada X mínima de cada polígono almacenado. Este campo sólo contiene información si el campo polig::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* xMin; /** \brief Vector de polig::nPolig elementos, que almacena la coordenada X máxima de cada polígono almacenado. Este campo sólo contiene información si el campo polig::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* xMax; /** \brief Vector de polig::nPolig elementos, que almacena la coordenada Y mínima de cada polígono almacenado. Este campo sólo contiene información si el campo polig::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* yMin; /** \brief Vector de polig::nPolig elementos, que almacena la coordenada Y máxima de cada polígono almacenado. Este campo sólo contiene información si el campo polig::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* yMax; /** \brief Identificador de si la estructura contiene información acerca de la superficie de los polígonos almacenados. Dos posibilidades: - 0: La estructura no contiene información de superficie. - Distinto de 0: La estructura sí contiene información de superficie. */ int hayArea; /** \brief Vector de polig::nPolig elementos, que almacena la superficie de cada polígono almacenado. Este campo sólo contiene información si el campo polig::hayArea es distinto de 0; si no, es igual a \p NULL. La superficie almacenada sólo es correcta si el polígono es simple, esto es, si sus lados no se cortan entre ellos mismos. El área de los polígono puede ser negativa o positiva, de tal forma que: - Si es negativa: Los vértices de polígono están ordenados en el sentido de las agujas del reloj. - Si es positiva: Los vértices de polígono están ordenados en sentido contrario al de las agujas del reloj. */ double* area; }polig; /******************************************************************************/ /******************************************************************************/ /** \brief Indica si hay alguna función compilada en paralelo con OpenMP en el fichero \ref polig.c. \param[out] version Cadena identificadora de la versión de OpenMP utilizada. Este argumento sólo se utiliza si su valor de entrada es distinto de \p NULL y si hay alguna función compilada con OpenMP. \return Dos posibles valores: - 0: No hay ninguna función compilada en paralelo con OpenMP. - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP. \note Esta función asume que el argumento \em version tiene suficiente memoria asignada (si es distinto de \p NULL). \date 27 de mayo de 2011: Creación de la función. \date 25 de agosto de 2011: Adición del argumento de entrada \em version. */ int GeocParOmpPolig(char version[]); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una estructura \ref polig vacía. \return Estructura \ref polig vacía. Los campos escalares se inicializan con el valor 0 y los vectoriales con \p NULL. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \date 26 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ polig* IniciaPoligVacio(void); /******************************************************************************/ /******************************************************************************/ /** \brief Función auxiliar para la rutina de creación de una estructura \ref polig a partir de dos vectores que contienen las coordenadas de los vértices. Esta función calcula el número máximo de elementos que almacenarán los vectores de coordenadas de una estructura \ref polig y el número de polígonos almacenados en los vectores de trabajo. \param[in] nElem Número de elementos de los vectores de coordenadas originales. \param[in] posNanX Vector que almacena las posiciones de los elementos #GEOC_NAN en el vector \em x de coordenadas originales. \param[in] posNanY Vector que almacena las posiciones de los elementos #GEOC_NAN en el vector \em y de coordenadas originales. \param[in] nNanX Número de elementos del vector \em posNanX. \param[in] nNanY Número de elementos del vector \em posNanY. \param[out] nElemMax Número máximo de elementos que contendrán los vectores de coordenadas de los elementos de la estructura. \param[out] nPolig Número de polígonos almacenados en los vectores \em x e \em y de coordenadas originales. \return Variable de error. Tres posibilidades: - #GEOC_ERR_NO_ERROR: Si todo ha ido bien. - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Si los vectores \em x e \em y de coordenadas originales almacenan un número distinto de polígonos, es decir, \em nNanX es distinto que \em nNanY. - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Si algunos polígonos almacenados en \em x e \em y son distintos, es decir, las posiciones almacenadas en \em posNanX son distintas de las almacenadas en \em posNanY. \note Esta función no comprueba si el número de elementos de los vectores \em posNanX y \em posNanY es congruente con los valores pasados en \em nNanX y \em nNanY. \date 26 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ int AuxCreaPolig1(const size_t nElem, const size_t* posNanX, const size_t* posNanY, const size_t nNanX, const size_t nNanY, size_t* nElemMax, size_t* nPolig); /******************************************************************************/ /******************************************************************************/ /** \brief Función auxiliar para la rutina de creación de una estructura \ref polig a partir de dos vectores que contienen las coordenadas de los vértices. Esta función copia una serie de datos de dos vectores en otros dos. \param[in] x Vector que contiene las coordenadas X de los vértices a copiar. \param[in] y Vector que contiene las coordenadas Y de los vértices a copiar. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[out] xSal Vector para almacenar los elementos copiados del vector \em x. Ha de tener la suficiente memoria asignada para copiar \em nElem elementos más un posible elemento adicional, que es el primer elemento de \em x, si éste no se repite al final. \param[out] ySal Vector para almacenar los elementos copiados del vector \em y. Ha de tener la suficiente memoria asignada para copiar \em nElem elementos más un posible elemento adicional, que es el primer elemento de \em y, si éste no se repite al final. \param[out] nCopias Número de elementos copiados en los vectores \em xSal e \em ySal, incluido el primer punto repetido al final, si se copia. \note Esta función no comprueba si el número de elementos de los vectores \em x, \em y, \em xSal e \em ySal es congruente con los valores pasados en \em nElem, \em incX e \em incY. \date 26 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ void AuxCreaPolig2(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, double* xSal, double* ySal, size_t* nCopias); /******************************************************************************/ /******************************************************************************/ /** \brief Función auxiliar para las rutinas de creación de estructuras \ref polig a partir de dos vectores que contienen las coordenadas de los vértices. Esta función crea los polígonos en el formato de almacenamiento de \ref polig a partir de los vectores de entrada. \param[in] x Vector que contiene las coordenadas X de los vértices de trabajo. \param[in] y Vector que contiene las coordenadas Y de los vértices de trabajo. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] posNan Vector que almacena las posiciones de los elementos #GEOC_NAN en los vectores \em x e \em y. \param[in] nNan Número de elementos del vector \em posNan. \param[out] xSal Vector para almacenar las coordenadas X de los vértices de los polígonos creados. \param[out] ySal Vector para almacenar las coordenadas Y de los vértices de los polígonos creados. \param[out] posIni Vector para almacenar las posiciones de inicio de los polígonos creados. \param[out] nVert Vector para almacenar el número de vértices de los polígonos creados. \param[out] nPtos Número de posiciones con información almacenada en los vectores \em xSal e \em ySal. \param[out] nPolig Número de posiciones con información almacenada en los vectores \em posIni y \em nVert. \note Esta función no comprueba si el número de elementos de los vectores \em x, \em y y \em posNan es congruente con los valores pasados en \em nElem, \em incX, \em incY y \em nNan. \note Esta función asume que los vectores \em xSal, \em ySal, \em posIni y \em nVert tienen asignada suficiente memoria. \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ void AuxCreaPolig3(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, double* xSal, double* ySal, size_t* posIni, size_t* nVert, size_t* nPtos, size_t* nPolig); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una estructura \ref polig a partir de dos vectores que contienen las coordenadas de los vértices de uno o varios polígonos. \param[in] x Vector que contiene las coordenadas X de los vértices del polígono o polígonos de trabajo. Si hay varios polígonos, han de estar separados por un valor #GEOC_NAN. \param[in] y Vector que contiene las coordenadas Y de los vértices del polígono o polígonos de trabajo. Si hay varios polígonos, han de estar separados por un valor #GEOC_NAN. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[out] idError Identificador de error. Varias posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Los vectores \em x e \em y contienen un número distinto de polígonos. No contienen el mismo número de identificadores #GEOC_NAN. - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Los vectores \em x e \em y contienen distintos polígonos. Los marcadores #GEOC_NAN no están colocados en las mismas posiciones. \return Estructura \ref polig con los polígonos pasados. Si ocurre algún error, se devuelve \p NULL y el motivo del fallo se codifica en la variable \em idError. \note Esta función está paralelizada con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados de \em nElem, \em incX e \em incY. \note Si los vectores \em x e \em y almacenan varios polígonos, éstos se separan mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición y/o la última es opcional. \note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en \em x e \em y. \note Para los polígonos, es opcional repetir las coordenadas del primer vértice al final del listado del resto de vértices. \note Esta función no calcula los límites de los polígonos ni su área, por lo que los campos polig::hayLim y polig::hayArea se inicializan a 0 y los campos polig::xMin, polig::xMax, polig::yMin, polig::yMax y polig::area se inicializan a \p NULL. \date 26 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ polig* CreaPolig(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, int* idError); /******************************************************************************/ /******************************************************************************/ /** \brief Enlaza el contenido de una estructura \ref polig a otra. \param[in] poliEnt Estructura \ref polig de entrada, que almacena los datos a enlazar. \param[out] poliSal Estructura \ref polig, cuyos campos serán enlazados a los de la estructura \em poliEnt. Esta estructura ha de estar, como mínimo, inicializada. Al término de la ejecución de la función, las estructuras \em poliEnt y \em poliSal comparten el mismo espacio de memoria en sus argumentos vectoriales. \note Esta función asume que la estructura de entrada \em poligEnt tiene memoria asignada. \note Esta función asume que la estructura de salida \em poligSal está, como mínimo, inicializada. \note Esta función libera la posible memoria asignada a los campos de \em poliSal antes de realizar el enlace. \date 19 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void EnlazaCamposPolig(polig* poliEnt, polig* poliSal); /******************************************************************************/ /******************************************************************************/ /** \brief Copia el contenido de una estructura \ref polig en otra. \param[in] poli Estructura \ref polig de entrada, que almacena los datos a copiar. \param[out] idError Identificador de error. Varias posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Los campos polig::x e polig::y del polígono de entrada contienen un número distinto de polígonos. No contienen el mismo número de identificadores #GEOC_NAN. - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Los campos polig::x e polig::y del polígono de entrada contienen distintos polígonos. Los marcadores #GEOC_NAN no están colocados en las mismas posiciones. \return Polígono con los datos contenidos en \em poli copiados. Si ocurre algún error se devuelve \p NULL y la causa se almacena en el argumento \em idError. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \date 09 de julio de 2011: Creación de la función. \note Esta función todavía no está probada. */ polig* CopiaPolig(const polig* poli, int* idError); /******************************************************************************/ /******************************************************************************/ /** \brief Añade el contenido de una estructura \ref polig a otra. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se han añadido los polígonos de la estructura \em anyade. \param[in] anyade Estructura cuyo contenido será añadido a \em poli. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función asume que la estructura de entrada \ref polig tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de las estructuras de entrada no se libera. \note Si la estructura \em poli guarda información de superficie y límites de los polígonos almacenados, esta información se calcula también para los nuevos datos (en realidad, si la estructura \em anyade ya los tiene calculados, simplemente se copian). \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ int AnyadePoligPolig(polig* poli, const polig* anyade); /******************************************************************************/ /******************************************************************************/ /** \brief Añade al contenido de una estructura \ref polig un conjunto de polígonos definidos a partir de un listado con las coordenadas de sus vértices, de la misma forma que el utilizado en la función \ref CreaPolig. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se han añadido los polígonos pasados en \em x e \em y. \param[in] x Vector que contiene las coordenadas X de los vértices del polígono o polígonos a añadir. Si hay varios polígonos, han de estar separados por un valor #GEOC_NAN. \param[in] y Vector que contiene las coordenadas Y de los vértices del polígono o polígonos a añadir. Si hay varios polígonos, han de estar separados por un valor #GEOC_NAN. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. - #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG: Los vectores \em x e \em y contienen un número distinto de polígonos. No contienen el mismo número de identificadores #GEOC_NAN. - #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG: Los vectores \em x e \em y contienen distintos polígonos. Los marcadores #GEOC_NAN no están colocados en las mismas posiciones. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de la estructura y los vectores de entrada no se libera. \note Si la estructura \em poli guarda información de superficie y límites de los polígonos almacenados, esta información se calcula también para los nuevos datos. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados de \em nElem, \em incX e \em incY. \note Si los vectores \em x e \em y almacenan varios polígonos, éstos se separan mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición y/o la última es opcional. \note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en \em x e \em y. \note Para los polígonos, es opcional repetir las coordenadas del primer vértice al final del listado del resto de vértices. \note Esta función crea internamente una estructura \ref polig para luego añadirla a \em poli con la función \ref AnyadePoligPolig. \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ int AnyadeDatosPolig(polig* poli, const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY); /******************************************************************************/ /******************************************************************************/ /** \brief Libera la memoria asignada a una estructura \ref polig. \param[in] datos Estructura \ref polig. \date 20 de abril de 2011: Creación de la estructura. \date 26 de mayo de 2011: Reescritura de la función para el trabajo con la nueva versión de la estructura. \note Esta función todavía no está probada. */ void LibMemPolig(polig* datos); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula los límites de todos los polígonos almacenados en una estructura \ref polig. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se han añadido los límites de los polígonos almacenados. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función está paralelizada con OpenMP. \note Esta función asume que la estructura de entrada \ref polig tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de la estructura de entrada no se libera. \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ int CalcLimitesPolig(polig* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula los límites de un polígono a partir de las coordenadas de sus vértices. \param[in] x Vector que contiene las coordenadas X de los vértices del polígono de trabajo. \param[in] y Vector que contiene las coordenadas Y de los vértices del polígono de trabajo. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[out] xMin Coordenada X mímina del polígono. \param[out] xMax Coordenada X máxima del polígono. \param[out] yMin Coordenada Y mímina del polígono. \param[out] yMax Coordenada Y máxima del polígono. \note Esta función está paralelizada con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados de \em nElem, \em incX e \em incY. \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ void LimitesPoligono(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, double* xMin, double* xMax, double* yMin, double* yMax); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula los límites de una serie de polígonos a partir de las coordenadas de sus vértices, almacenadas en vectores en el formato de la estructura \ref polig. \param[in] x Vector que contiene las coordenadas X de los vértices del polígono de trabajo, tal y como se almacenan en una estructura \ref polig. \param[in] y Vector que contiene las coordenadas Y de los vértices del polígono de trabajo, tal y como se almacenan en una estructura \ref polig. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] posIni Vector de \em nPolig elementos, que almacena las posiciones de inicio de los polígonos de trabajo. \param[in] nVert Vector de \em nPolig elementos, que almacena el número de vértices de los polígonos de trabajo. \param[in] nPolig Número de polígonos de trabajo. \param[in] restaPosIni Número de posiciones a restar a los valores almacenados en \em posIni, de tal forma que los índices de los vértices se refieran al inicio pasado mediante los punteros \em x e \em y. \param[out] xMin Vector de \em nPolig elementos para almacenar las coordenadas X mínimas calculadas de los polígonos. \param[out] xMax Vector de \em nPolig elementos para almacenar las coordenadas X máximas calculadas de los polígonos. \param[out] yMin Vector de \em nPolig elementos para almacenar las coordenadas Y mínimas calculadas de los polígonos. \param[out] yMax Vector de \em nPolig elementos para almacenar las coordenadas Y máximas calculadas de los polígonos. \note Esta función está paralelizada con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em x, \em y, \em posIni, \em nVert, \em xMin, \em xMax, \em yMin e \em yMax es congruente con los valores pasados de \em incX, \em incY, \em nPolig y \em restaPoliIni. \note Esta función no comprueba si las coordenadas almacenadas en los vectores \em x e \em y están en el formato de la estructura \ref polig. \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ void LimitesPoligonosPolig(const double* x, const double* y, const size_t incX, const size_t incY, const size_t* posIni, const size_t* nVert, const size_t nPolig, const size_t restaPosIni, double* xMin, double* xMax, double* yMin, double* yMax); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el área de todos los polígonos almacenados en una estructura \ref polig. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se han añadido las superficies de los polígonos almacenados. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función asume que la estructura de entrada \ref polig tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de la estructura de entrada no se libera. \date 29 de mayo de 2011: Creación de la función. \date 01 de agosto de 2011: Corregido error que hacía que se calculasen mal las superficies debido a un incorrecto uso del argumento \em restaPosIni de la función \ref AreaPoligonosSimplesPolig. \note Esta función todavía no está probada. */ int CalcAreaPolig(polig* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el área de un polígono simple (sin intersecciones consigo mismo) a partir de las coordenadas de sus vértices. \param[in] x Vector que contiene las coordenadas X de los vértices del polígono de trabajo. Las coordenadas del primer punto pueden repetirse o no al final, indistintamente. \param[in] y Vector que contiene las coordenadas Y de los vértices del polígono de trabajo. Las coordenadas del primer punto pueden repetirse o no al final, indistintamente. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \return Superficie del polígono de trabajo. Dos posibilidades: - Número negativo: Los vértices del polígono están ordenados en el sentido de las agujas del reloj. - Número positivo: Los vértices del polígono están ordenados en el sentido contrario al de las agujas del reloj. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados de \em nElem, \em incX e \em incY. \note El algoritmo implementado es el correspondiente a la ecuación 21.4.20 del Numerical Recipes, tercera edición, página 1127. Este algoritmo trabaja con vectores de coordenadas en los que el primer punto no se repite al final. Esta función comprueba internamente si el primer punto se repite al final de los vectores pasados y actua en consecuencia para proporcionar un resultado correcto. \date 29 de mayo de 2011: Creación de la función. \date 23 de junio de 2011: Adición de la capacidad de trabajar con vectores de coordenadas en los que se repite el primer punto al final. \note Esta función todavía no está probada. */ double AreaPoligonoSimple(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el área de una serie de polígonos simples (sin intersecciones consigo mismo) a partir de las coordenadas de sus vértices, almacenadas en vectores en el formato de la estructura \ref polig. \param[in] x Vector que contiene las coordenadas X de los vértices del polígono de trabajo, tal y como se almacenan en una estructura \ref polig. \param[in] y Vector que contiene las coordenadas Y de los vértices del polígono de trabajo, tal y como se almacenan en una estructura \ref polig. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] posIni Vector de \em nPolig elementos, que almacena las posiciones de inicio de los polígonos de trabajo. \param[in] nVert Vector de \em nPolig elementos, que almacena el número de vértices de los polígonos de trabajo. \param[in] nPolig Número de polígonos de trabajo. \param[in] restaPosIni Número de posiciones a restar a los valores almacenados en \em posIni, de tal forma que los índices de los vértices se refieran al inicio pasado mediante los punteros \em x e \em y. \param[out] area Vector de \em nPolig elementos para almacenar las superficies calculadas de los polígonos. Los valores pueden ser positivos o negativos: - Número negativo: Los vértices del polígono están ordenados en el sentido de las agujas del reloj. - Número positivo: Los vértices del polígono están ordenados en el sentido contrario al de las agujas del reloj. \note Esta función está paralelizada con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em x, \em y, \em posIni, \em nVert y \em area es congruente con los valores pasados de \em incX, \em incY, \em nPolig y \em restaPoliIni. \note Esta función no comprueba si las coordenadas almacenadas en los vectores \em x e \em y están en el formato de la estructura \ref polig. \date 29 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ void AreaPoligonosSimplesPolig(const double* x, const double* y, const size_t incX, const size_t incY, const size_t* posIni, const size_t* nVert, const size_t nPolig, const size_t restaPosIni, double* area); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica un factor de escala y una traslación (en este orden) a las coordenadas de todos los polígonos almacenados en una estructura \ref polig. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se ha aplicado un factor de escala y una traslación (en este orden) a las coordenadas de todos los polígonos almacenados y, si se indica, a los límites y las superficies. \param[in] escalaX Factor de escala a aplicar a las coordenadas X. \param[in] escalaY Factor de escala a aplicar a las coordenadas Y. \param[in] trasladaX Traslación a aplicar a las coordenadas X. \param[in] trasladaY Traslación a aplicar a las coordenadas Y. \param[in] aplicaLim Identificador para aplicar o no los factores de escala y las traslaciones a los límites de los polígonos (sólo si están previemente calculados). Dos posibilidades: - 0: No se aplican los factores de escala ni las traslaciones a los límites. - Distinto de 0: Sí se aplican los factores de escala y las traslaciones a los límites, si estos están calculados en la estructura de entrada. \param[in] aplicaArea Identificador para aplicar o no los factores de escala (que se aplican como un único factor \em escalaX*escalaY) a las áreas de los polígonos (sólo si están previemente calculadas). Dos posibilidades: - 0: No se aplican los factores a las áreas. - Distinto de 0: Sí se aplican los factores a las áreas, si estas están calculadas en la estructura de entrada. \note Esta función está paralelizada con OpenMP. \note Primero se aplican los factores de escala y luego las traslaciones. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \note A las áreas sólo se aplican los factores de escala, ya que son invariantes ante traslaciones. \note A las áreas, los factores de escala se aplican como uno solo, igual a \em escalaX*escalaY, para que éstas queden correctamente expresadas en las nuevas unidades a las que da lugar el escalado. \date 02 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Distinción entre factores de escala y traslaciones para las coordenadas X e Y. \note Esta función todavía no está probada. */ void EscalaYTrasladaPolig(polig* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim, const int aplicaArea); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica una traslación y un factor de escala (en este orden) a las coordenadas de todos los polígonos almacenados en una estructura \ref polig. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se ha aplicado una traslación y un factor de escala (en este orden) a las coordenadas de todos los polígonos almacenados y, si se indica, a los límites y las superficies. \param[in] escalaX Factor de escala a aplicar a las coordenadas X. \param[in] escalaY Factor de escala a aplicar a las coordenadas Y. \param[in] trasladaX Traslación a aplicar a las coordenadas X. \param[in] trasladaY Traslación a aplicar a las coordenadas Y. \param[in] aplicaLim Identificador para aplicar o no las traslaciones y los factores de escala a los límites de los polígonos (sólo si están previemente calculados). Dos posibilidades: - 0: No se aplican las traslaciones ni los factores de escala a los límites. - Distinto de 0: Sí se aplican las traslaciones y los factores de escala a los límites, si estos están calculados en la estructura de entrada. \param[in] aplicaArea Identificador para aplicar o no los factores de escala (que se aplican como un único factor \em escalaX*escalaY) a las áreas de los polígonos (sólo si están previemente calculadas). Dos posibilidades: - 0: No se aplican los factores a las áreas. - Distinto de 0: Sí se aplican los factores a las áreas, si estas están calculadas en la estructura de entrada. \note Esta función está paralelizada con OpenMP. \note Primero se aplican las traslaciones y luego los factores de escala. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \note A las áreas sólo se aplican los factores de escala, ya que son invariantes ante traslaciones. \note A las áreas, los factores de escala se aplican como uno solo, igual a \em escalaX*escalaY, para que éstas queden correctamente expresadas en las nuevas unidades a las que da lugar el escalado. \date 02 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Distinción entre factores de escala y traslaciones para las coordenadas X e Y. \note Esta función todavía no está probada. */ void TrasladaYEscalaPolig(polig* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim, const int aplicaArea); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica un factor de escala y una traslación (el orden de aplicación se ha de seleccionar) a las coordenadas de todos los polígonos almacenados en una estructura \ref polig. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se ha aplicado un factor de escala y una traslación (orden a seleccionar) a las coordenadas de todos los polígonos almacenados y, si se indica, a los límites y las superficies. \param[in] escalaX Factor de escala a aplicar a las coordenadas X. \param[in] escalaY Factor de escala a aplicar a las coordenadas Y. \param[in] trasladaX Traslación a aplicar a las coordenadas X. \param[in] trasladaY Traslación a aplicar a las coordenadas Y. \param[in] orden Orden de aplicación de los factores de escala y traslación. Dos posibilidades: - 0: Primero se aplican los factores de escala y luego las traslaciones \f$x'=f\cdot x+t\f$. - Distinto de 0: Primero se aplican las traslaciones y luego los factores de escala \f$x'=(x+t)\cdot f\f$. \param[in] aplicaLim Identificador para aplicar o no los factores de escala y las traslaciones a los límites de los polígonos (sólo si están previemente calculados). Dos posibilidades: - 0: No se aplican los factores de escala ni las traslaciones a los límites. - Distinto de 0: Sí se aplican los factores de escala y las traslaciones a los límites, si estos están calculados en la estructura de entrada. \param[in] aplicaArea Identificador para aplicar o no los factores de escala (que se aplican como un único factor \em escalaX*escalaY) a las áreas de los polígonos (sólo si están previemente calculadas). Dos posibilidades: - 0: No se aplican los factores a las áreas. - Distinto de 0: Sí se aplican los factores a las áreas, si estas están calculadas en la estructura de entrada. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \note A las áreas sólo se aplican los factores de escala, ya que son invariantes ante traslaciones. \note A las áreas, los factores de escala se aplican como uno solo, igual a \em escalaX*escalaY, para que éstas queden correctamente expresadas en las nuevas unidades a las que da lugar el escalado. \date 02 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Distinción entre factores de escala y traslaciones para las coordenadas X e Y. \note Esta función todavía no está probada. */ void MuevePolig(polig* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int orden, const int aplicaLim, const int aplicaArea); /******************************************************************************/ /******************************************************************************/ /** \brief Elimina vértices de los polígonos almacenados en una estructura \ref polig mediante un algoritmo inspirado en el de Douglas-Peucker. Se usa internamente la función \ref AligeraPolilinea. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, almacena el resultado de la aplicación a cada polígono del algoritmo de aligerado de vértices implementado en la función \ref AligeraPolilinea. \param[in] tol Tolerancia para eliminar vértices, en las mismas unidades que las coordenadas de los vértices. Ver la ayuda de la función \ref AligeraPolilinea. \param[in] robusto Identificador para realizar o no un aligerado robusto. Ha de ser un elemento del tipo enumerado #GEOC_DPEUCKER_ROBUSTO. Varias posibilidades: - #GeocDPeuckerRobNo: No se aplica el algoritmo robusto. - #GeocDPeuckerRobSi: Se aplica el algoritmo robusto completo, que garantiza la no ocurrencia de auto intersecciones en el polígono resultante. Internamente, primero se aplica el tratamiento robusto de la opción #GeocDPeuckerRobOrig y luego el de la opción #GeocDPeuckerRobAuto. - #GeocDPeuckerRobOrig: Se aplica un algoritmo semi robusto que consiste en garantizar que los segmentos del polígono aligerado que se van creando no intersectarán con ninguno de los segmentos que forman los vértices que quedan por procesar del polígono original. En casos muy especiales, este algoritmo puede seguir dando lugar a auto intersecciones. - #GeocDPeuckerRobAuto: Se aplica un algoritmo semi robusto que consiste en garantizar que los segmentos del polígono aligerado que se van creando no intersectarán con ninguno de los segmentos del polígono aligerado creados con anterioridad. En casos muy especiales, este algoritmo puede seguir dando lugar a auto intersecciones. \param[in] nPtosRobusto Número de puntos del polígono original a utilizar en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o #GeocDPeuckerRobOrig. Si se pasa el valor 0, se utilizan todos los puntos hasta el final del polígono original. \param[in] nSegRobusto Número de segmentos del polígono aligerado a utilizar en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o #GeocDPeuckerRobAuto. Si se pasa el valor 0, se utilizan todos los segmentos hasta el inicio del polígono aligerado. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función asume que \em poli está, como mínimo, inicializado. \note Si \em poli tiene límites y/o áreas calculadas en la entrada, también los tendrá en la salida. \note Un polígono aligerado sólo será válido si después de aplicarle la función \ref AligeraPolilinea mantiene un mínimo de 3 puntos no alineados por lo que, al término de la ejecución de esta función, el resultado puede ser una estructura \ref polig vacía. \date 09 de julio de 2011: Creación de la función. \date 10 de julio de 2011: Cambio del tipo del argumento \em robusto al tipo enumerado #GEOC_DPEUCKER_ROBUSTO. \date 31 de julio de 2011: Corregido error con índices a la hora de guardar los resultados y comprobación de que los polígonos de salida no estén compuestos por tres puntos alineados. \todo Esta función todavía no está probada. */ int AligeraPolig(polig* poli, const double tol, const enum GEOC_DPEUCKER_ROBUSTO robusto, const size_t nPtosRobusto, const size_t nSegRobusto); /******************************************************************************/ /******************************************************************************/ /** \brief Imprime una línea de cabecera para un polígono almacenado en una estructura \ref polig. \param[in] poli Estructura \ref polig. \param[in] indice Índice del polígono de trabajo en la estructura. \param[in] iniCab Cadena de texto con la que comenzará la cabecera. \param[in] impLim Identificador para imprimir o no los límites de coordenadas del polígono de trabajo. Dos posibles valores: - 0: No se imprimen. - Distinto de 0: Sí se imprimen. \param[in] formCoor Cadena de carácteres indicadora del formato para escribir las coordenadas de los límites. Este argumento sólo se usa internamente si se ha indicado la impresión de límites. \param[in] impArea Identificador para imprimir o no la superficie del polígono de trabajo. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] formArea Cadena de carácteres indicadora del formato para escribir el valor de la superficie. Este argumento sólo se usa internamente si se ha indicado la impresión de la superficie del polígono. \param[in] factorX Factor para multiplicar las coordenadas X de los vértices antes de imprimirlas. \param[in] factorY Factor para multiplicar las coordenadas Y de los vértices antes de imprimirlas. \param[in] repitePrimerPunto Identificador para tener o no en cuenta el primer vértice del polígono repetido al final del listado de coordenadas para el cálculo del número de vértices del polígono. Dos posibles valores: - 0: No se repite, luego no se tiene en cuenta. - Distinto de 0: Sí se repite, luego sí se tiene en cuenta. \param[in] idFich Identificador de fichero abierto para escribir. \note Esta función está paralelizada con OpenMP. \note La cabecera completa tiene el siguiente formato: iniCab númVert área xMín xMáx yMín yMáx. \note Si la estructura no tiene información de límites y/o áreas y se indica que se impriman, los valores se calculan internamente. \note Esta función asume que \em poli es una estructura \ref polig correctamente almacenada. \note Esta función no comprueba si la estructura pasada tiene memoria asignada. \note Esta función no comprueba internamente la validez de los argumentos de formato. \note Esta función no comprueba internamente si el identificador pasado corresponde a un fichero abierto para escribir. \date 18 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void ImprimeCabeceraPoligFichero(const polig* poli, const size_t indice, const char iniCab[], const int impLim, const char formCoor[], const int impArea, const char formArea[], const double factorX, const double factorY, const int repitePrimerPunto, FILE* idFich); /******************************************************************************/ /******************************************************************************/ /** \brief Imprime una estructura \ref polig en un fichero. \param[in] poli Estructura \ref polig. \param[in] factorX Factor para multiplicar las coordenadas X de los vértices antes de imprimirlas. \param[in] factorY Factor para multiplicar las coordenadas Y de los vértices antes de imprimirlas. \param[in] repitePrimerPunto Identificador para repetir o no el primer vértice del polígono al final del listado de coordenadas. Dos posibles valores: - 0: No se repite. - Distinto de 0: Sí se repite. \param[in] iniNan Identificador para imprimir o no la marca de separación de polígonos (\p NaN) delante del primer polígono. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] finNan Identificador para imprimir o no la marca de separación de polígonos (\p NaN) detrás del último polígono. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] formCoor Cadena de carácteres indicadora del formato de cada coordenada a imprimir. \param[in] impCabecera Identificador para imprimir o no una cabecera con información general por cada polígono. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] iniCab Cadena de texto con la que comenzará la cabecera. \param[in] impLim Identificador para imprimir o no en la cabecera los límites de coordenadas de los polígonos de trabajo. Dos posibles valores: - 0: No se imprimen. - Distinto de 0: Sí se imprimen. \param[in] impArea Identificador para imprimir o no en la cabecera la superficie de los polígonos de trabajo. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] formArea Cadena de carácteres indicadora del formato para escribir el valor de la superficie. Este argumento sólo se usa internamente si se ha indicado la impresión de la superficie de los polígonos. \param[in] idFich Identificador de fichero abierto para escribir. \note La cabecera completa tiene el siguiente formato: iniCab númVert área xMín xMáx yMín yMáx. \note Si la estructura no tiene información de límites y/o áreas y se indica que se impriman, los valores se calculan internamente. \note Esta función asume que \em poli es una estructura \ref polig correctamente almacenada. \note Esta función no comprueba si la estructura pasada tiene memoria asignada. \note Esta función no comprueba internamente la validez de los argumentos de formato. \note Esta función no comprueba internamente si el identificador pasado corresponde a un fichero abierto para escribir. \date 26 de mayo de 2011: Creación de la función. \date 30 de mayo de 2011: Adición del argumento de entrada \em factor. \date 18 de junio de 2011: Adición de la capacidad de escritura de una cabecera y del uso de factores de escala independientes para las coordenadas X e Y. \date 22 de septiembre de 2011: Corregido bug que hacía que, dependiendo del compilador y/o los flags de optimización en la compilación, se imprimiesen mal (con un signo menos delante) los valores Not-a-Number. \note Esta función todavía no está probada. */ void ImprimePoligFichero(const polig* poli, const double factorX, const double factorY, const int repitePrimerPunto, const int iniNan, const int finNan, const char formCoor[], const int impCabecera, const char iniCab[], const int impLim, const int impArea, const char formArea[], FILE* idFich); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/dpeucker.h0000644000175000017500000003454612032305135020060 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom @{ \file dpeucker.h \brief Declaración de funciones para el aligerado de polilíneas basadas en el algoritmo de Douglas-Peucker. \author José Luis García Pallero, jgpallero@gmail.com \date 04 de julio de 2011 \section Licencia Licencia Copyright (c) 2009-2010, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _DPEUCKER_H_ #define _DPEUCKER_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include"libgeoc/calctopo.h" #include"libgeoc/constantes.h" #include"libgeoc/eucli.h" #include"libgeoc/fgeneral.h" #include"libgeoc/segmento.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_DPEUCKER_BUFFER_PTOS \brief Número de puntos para ir asignando memoria en bloques para el vector de salida en la funcion \ref AligeraPolilinea. \date 06 de julio de 2011: Creación de la constante. */ #define GEOC_DPEUCKER_BUFFER_PTOS 100 /******************************************************************************/ /******************************************************************************/ /** \enum GEOC_DPEUCKER_ROBUSTO \brief Aplicación o no del algoritmo robusto de aligerado de polilíneas. \date 10 de julio de 2011: Creación del tipo. */ enum GEOC_DPEUCKER_ROBUSTO { /** \brief \b *NO* se realiza aligerado robusto. */ GeocDPeuckerRobNo=111, /** \brief \b *SÍ* se realiza aligerado robusto. */ GeocDPeuckerRobSi=112, /** \brief Aligerado semi robusto con \ref AligPolilRobIntersecOrig. */ GeocDPeuckerRobOrig=113, /** \brief Aligerado semi robusto con \ref AligPolilRobAutoIntersec. */ GeocDPeuckerRobAuto=114 }; /******************************************************************************/ /******************************************************************************/ /** \brief Elimina vértices de una polilínea mediante un algoritmo inspirado en el de Douglas-Peucker. Este algoritmo, comenzando por el primer punto de la polilínea, va uniendo puntos en segmentos de tal forma que se eliminan todos aquellos puntos que queden a una distancia perpendicular menor o igual a \em tol del segmento de trabajo. Así aplicado, pueden ocurrir casos singulares en los que la polilínea aligerada tenga casos de auto intersección entre sus lados resultantes. Para evitar esto, se puede aplicar la versión robusta del algoritmo. \param[in] x Vector que contiene las coordenadas X de los vértices de la polilínea de trabajo. \param[in] y Vector que contiene las coordenadas Y de los vértices de la polilínea de trabajo. \param[in] nPtos Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] tol Tolerancia para eliminar vértices, en las mismas unidades que las coordenadas de los vértices. \param[in] robusto Identificador para realizar o no un aligerado robusto. Ha de ser un elemento del tipo enumerado #GEOC_DPEUCKER_ROBUSTO. Varias posibilidades: - #GeocDPeuckerRobNo: No se aplica el algoritmo robusto. - #GeocDPeuckerRobSi: Se aplica el algoritmo robusto completo, que garantiza la no ocurrencia de auto intersecciones en la polilínea resultante. Internamente, primero se aplica el tratamiento robusto de la opción #GeocDPeuckerRobOrig y luego el de la opción #GeocDPeuckerRobAuto. - #GeocDPeuckerRobOrig: Se aplica un algoritmo semi robusto que consiste en garantizar que los segmentos de la polilínea aligerada que se van creando no intersectarán con ninguno de los segmentos que forman los vértices que quedan por procesar de la polilínea original. En casos muy especiales, este algoritmo puede seguir dando lugar a auto intersecciones. - #GeocDPeuckerRobAuto: Se aplica un algoritmo semi robusto que consiste en garantizar que los segmentos de la polilínea aligerada que se van creando no intersectarán con ninguno de los segmentos de la polilínea aligerada creados con anterioridad. En casos muy especiales, este algoritmo puede seguir dando lugar a auto intersecciones. \param[in] nPtosRobusto Número de puntos de la polilínea original a utilizar en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o #GeocDPeuckerRobOrig. Si se pasa el valor 0, se utilizan todos los puntos hasta el final de la polilínea original. \param[in] nSegRobusto Número de segmentos de la polilínea aligerada a utilizar en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o #GeocDPeuckerRobAuto. Si se pasa el valor 0, se utilizan todos los segmentos hasta el inicio de la polilínea aligerada. \param[out] nPtosSal Número de puntos de la polilínea aligerada. \return Vector de \em nPtosSal elementos que contiene los índices en los vectores \em x e \em y de los vértices que formarán la polilínea aligerada. Si ocurre algún error de asignación de memoria se devuelve el valor \p NULL. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con el valor pasado en \em nPtos. \note Esta función asume que \em nPtos es mayor que 0. En caso contrario, devuelve \p NULL. \date 07 de julio de 2011: Creación de la función. \date 10 de julio de 2011: Cambio del tipo del argumento \em robusto al tipo enumerado #GEOC_DPEUCKER_ROBUSTO. \todo Esta función todavía no está probada. */ size_t* AligeraPolilinea(const double* x, const double* y, const size_t nPtos, const size_t incX, const size_t incY, const double tol, const enum GEOC_DPEUCKER_ROBUSTO robusto, const size_t nPtosRobusto, const size_t nSegRobusto, size_t* nPtosSal); /******************************************************************************/ /******************************************************************************/ /** \brief Aproximación robusta al aligerado de líneas consistente en evitar que los segmentos creados intersecten con los de la polilínea original a partir del punto de trabajo actual. \param[in] x Vector que contiene las coordenadas X de los vértices de la polilínea de trabajo. \param[in] y Vector que contiene las coordenadas Y de los vértices de la polilínea de trabajo. \param[in] nPtos Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] ptosAUsar Número de puntos a utilizar de la polilínea original. Si se pasa el valor 0 se utilizan todos los puntos que quedan desde el punto de trabajo hasta el final. \param[in] posIni Posición inicial del segmento a chequear. \param[in,out] posFin Posición final del segmento a chequear. Al término de la ejecución de la función almacena la posición del punto que hace que el segmento de la polilínea aligerada no intersecte con ninguno de los que quedan de la polilínea original. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con el valor pasado en \em nPtos. \note Esta función no comprueba si los índices pasados en los argumentos \em posIni y \em posFin son congruentes con el tamaño de los vectores pasado en \em nPtos. \note Esta función no comprueba internamente si la variable \em ptosAUsar es congruente con el valor pasado en \em nPtos. \date 07 de julio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void AligPolilRobIntersecOrig(const double* x, const double* y, const size_t nPtos, const size_t incX, const size_t incY, const size_t ptosAUsar, const size_t posIni, size_t* posFin); /******************************************************************************/ /******************************************************************************/ /** \brief Aproximación robusta al aligerado de líneas consistente en evitar que los segmentos creados intersecten con los anteriores de la polilínea aligerada. \param[in] x Vector que contiene las coordenadas X de los vértices de la polilínea de trabajo. \param[in] y Vector que contiene las coordenadas Y de los vértices de la polilínea de trabajo. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] posAlig Vector de posiciones de \em x e \em y utilizadas en la polilínea aligerada. \param[in] nPosAlig Número de elementos de \em posAlig menos el último punto añadido. Esto se hace así para evitar chequear el segmento inmediatamente anterior, que siempre tiene un punto en común (su extremo final) con el de trabajo. \param[in] segAUsar Número de segmentos a utilizar de la polilínea aligerada. Si se pasa el valor 0 se utilizan todos los segmentos anteriores. \param[in] posIni Posición inicial del segmento a chequear. \param[in,out] posFin Posición final del segmento a chequear. Al término de la ejecución de la función almacena la posición del punto que hace que el segmento de la polilínea aligerada no intersecte con ninguno de los anteriormente calculados. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con el valor pasado en \em nPtos. \note Esta función no comprueba si los índices pasados en los argumentos \em posIni y \em posFin son congruentes con el tamaño de los vectores pasado en \em nPtos. \note Esta función trabaja internamente con el valor absoluto del argumento \em tamRect. \date 05 de julio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void AligPolilRobAutoIntersec(const double* x, const double* y, const size_t incX, const size_t incY, const size_t* posAlig, const size_t nPosAlig, const size_t segAUsar, const size_t posIni, size_t* posFin); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/segmento.h0000644000175000017500000003555612032305135020101 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom @{ \file segmento.h \brief Declaración de funciones para la realización de cálculos con segmentos. \author José Luis García Pallero, jgpallero@gmail.com \date 22 de abril de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _SEGMENTO_H_ #define _SEGMENTO_H_ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/fgeneral.h" #include"libgeoc/ptopol.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SEG_NO_INTERSEC \brief Identificador de que dos segmentos no se cortan. \date 14 de mayo de 2011: Creación de la constante. */ #define GEOC_SEG_NO_INTERSEC 0 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SEG_INTERSEC \brief Identificador de que dos segmentos se cortan en un punto, pero no son colineales. \date 14 de mayo de 2011: Creación de la constante. */ #define GEOC_SEG_INTERSEC 1 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN \brief Identificador de que dos segmentos se cortan en un punto, el cual es un extremo que está encima del otro segmento, pero no son colineales. \date 14 de mayo de 2011: Creación de la constante. */ #define GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN 2 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SEG_INTERSEC_EXTREMO_COLIN \brief Identificador de que dos segmentos tienen un punto común y son colineales. \date 14 de mayo de 2011: Creación de la constante. */ #define GEOC_SEG_INTERSEC_EXTREMO_COLIN 3 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SEG_INTERSEC_MISMO_SEG \brief Identificador de que dos segmentos tienen todos sus puntos extremos en común. \date 21 de mayo de 2011: Creación de la constante. */ #define GEOC_SEG_INTERSEC_MISMO_SEG 4 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SEG_INTERSEC_COLIN \brief Identificador de que dos segmentos tienen más de un punto en común. \date 14 de mayo de 2011: Creación de la constante. */ #define GEOC_SEG_INTERSEC_COLIN 5 /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la posición relativa de un punto con respecto a una recta en el plano. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] xIni Coordenada X del punto inicial del segmento que define la recta. \param[in] yIni Coordenada Y del punto inicial del segmento que define la recta. \param[in] xFin Coordenada X del punto final del segmento que define la recta. \param[in] yFin Coordenada Y del punto final del segmento que define la recta. \return Varias posibilidades: - Menor que 0: El punto está a la derecha de la recta. - 0: El punto pertenece a la recta. - Mayor que 0: El punto está a la izquierda de la recta. \note Para la definición de derecha e izquierda, se considera que el sentido de la recta es aquél que se define del punto de inicio al punto final del segmento de trabajo. \note El resultado de esta función no es robusto, es decir, puede dar resultados incorrectos debido a errores de redondeo (salvo que todas las coordenadas pasadas sean números enteros). \note El código de esta función ha sido tomado de la función orient2dfast(), de http://www.cs.cmu.edu/afs/cs/project/quake/public/code/predicates.c \date 20 de abril de 2010: Creación de la función. \date 14 de mayo de 2011: Cambio de nombre a la función. */ double PosPtoRecta2D(const double x, const double y, const double xIni, const double yIni, const double xFin, const double yFin); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si tres puntos (A, B, C) del plano son colineales. \param[in] xA Coordenada X del punto A. \param[in] yA Coordenada Y del punto A. \param[in] xB Coordenada X del punto B. \param[in] yB Coordenada Y del punto B. \param[in] xC Coordenada X del punto C. \param[in] yC Coordenada Y del punto C. \return Dos posibilidades: - 0: Los puntos no son colineales. - Distinto de 0: Los puntos son colineales. \note Esta función utiliza internamente la función \ref PtoComunSegmParalelos2D, que no es robusta. En consecuencia, los resultados de esta función tampoco lo son. \note Estafunción sirve de apoyo para \ref PtoComunSegmParalelos2D. \date 14 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ int TresPuntosColineales2D(const double xA, const double yA, const double xB, const double yB, const double xC, const double yC); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está situado entre dos puntos (pero no es igual a ninguno de ellos) en el plano. Se asume que los tres puntos con colineales. \param[in] x Coordenada X del punto a comprobar. \param[in] y Coordenada Y del punto a comprobar. \param[in] xA Coordenada X del primer punto del segmento. \param[in] yA Coordenada Y del primer punto del segmento. \param[in] xB Coordenada X del segundo punto del segmento. \param[in] yB Coordenada Y del segundo punto del segmento. \return Dos posibilidades: - 0: El punto de trabajo no está situado entre los dos puntos dato o es igual a alguno de ellos. - Distinto de 0: El punto de trabajo sí está situado entre los dos puntos dato. \note Esta función sirve de apoyo para \ref PtoComunSegmParalelos2D. \date 14 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ int PuntoEntreDosPuntos2DColin(const double x, const double y, const double xA, const double yA, const double xB, const double yB); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula un punto común entre dos segmentos paralelos AB y CD. \param[in] xA Coordenada X del punto A. \param[in] yA Coordenada Y del punto A. \param[in] xB Coordenada X del punto B. \param[in] yB Coordenada Y del punto B. \param[in] xC Coordenada X del punto C. \param[in] yC Coordenada Y del punto C. \param[in] xD Coordenada X del punto D. \param[in] yD Coordenada Y del punto D. \param[out] x Coordenada X del punto común. \param[out] y Coordenada Y del punto común. \return Dos posibilidades: - #GEOC_SEG_NO_INTERSEC: Los segmentos no tienen ningún punto en común. - #GEOC_SEG_INTERSEC_EXTREMO_COLIN: Los segmentos tienen un extremo común y son colineales. - #GEOC_SEG_INTERSEC_MISMO_SEG: Los dos segmentos son idénticos. - #GEOC_SEG_INTERSEC_COLIN: Los segmentos tienen más de un punto en común. \note Esta función sirve de apoyo para \ref IntersecSegmentos2D. \note Esta función utiliza internamente la función \ref TresPuntosColineales2D, que no es robusta. En consecuencia, los resultados de esta función tampoco lo son. \note Si los segmentos se tocan en los dos extremos (son el mismo segmento), las coordenadas devueltas son siempre las del vértice A. \note Si los segmentos tienen más de un punto en común, pero no son el mismo segmento, las coordenadas de salida siempre son las de un punto extremo de un segmento. Este punto extremo se intentará que sea uno de los puntos iniciales de algún segmento, anque si no lo es, será uno de los finales. El orden de preferencia de las coordenadas de salida es: A, C, B, D. \date 14 de mayo de 2011: Creación de la función. \date 21 de mayo de 2011: Adición de nuevos valores de salida: #GEOC_SEG_INTERSEC_EXTREMO_COLIN y #GEOC_SEG_INTERSEC_MISMO_SEG. \todo Esta función no está probada. */ int PtoComunSegmParalelos2D(const double xA, const double yA, const double xB, const double yB, const double xC, const double yC, const double xD, const double yD, double* x, double* y); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la intersección de dos segmentos AB y CD en el plano. \param[in] xA Coordenada X del punto A. \param[in] yA Coordenada Y del punto A. \param[in] xB Coordenada X del punto B. \param[in] yB Coordenada Y del punto B. \param[in] xC Coordenada X del punto C. \param[in] yC Coordenada Y del punto C. \param[in] xD Coordenada X del punto D. \param[in] yD Coordenada Y del punto D. \param[out] x Coordenada X del punto común. \param[out] y Coordenada Y del punto común. \return Cinco posibilidades: - #GEOC_SEG_NO_INTERSEC: Los segmentos no tienen ningún punto en común. - #GEOC_SEG_INTERSEC: Los segmentos se cortan en un punto. - #GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN: El extremo de un segmento toca al otro segmento, pero los segmentos no son colineales. - #GEOC_SEG_INTERSEC_EXTREMO_COLIN: Los segmentos tienen un extremo común y son colineales. - #GEOC_SEG_INTERSEC_MISMO_SEG: Los dos segmentos son idénticos. - #GEOC_SEG_INTERSEC_COLIN: Los segmentos tienen más de un punto en común. \note Esta función utiliza internamente la función \ref PtoComunSegmParalelos2D, que no es robusta. En consecuencia, los resultados de esta función tampoco lo son. \note Si los segmentos se tocan en los dos extremos (son el mismo segmento), las coordenadas devueltas son siempre las del vértice A. \note Si los segmentos tienen más de un punto en común, pero no son el mismo segmento, las coordenadas de salida siempre son las de un punto extremo de un segmento. Este punto extremo se intentará que sea uno de los puntos iniciales de algún segmento, anque si no lo es, será uno de los finales. El orden de preferencia de las coordenadas de salida es: A, C, B, D. \date 14 de mayo de 2011: Creación de la función. \date 21 de mayo de 2011: Adición de un nuevo valor de salida: #GEOC_SEG_INTERSEC_MISMO_SEG. \date 06 de julio de 2011: Adición de chequeo rápido al principio de la función para descartar que los segmentos no tienen ningún punto en común. */ int IntersecSegmentos2D(const double xA, const double yA, const double xB, const double yB, const double xC, const double yC, const double xD, const double yD, double* x, double* y); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/ptopol.h0000644000175000017500000015505612032305135017573 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file ptopol.h \brief Declaración de funciones para la realización de chequeos de inclusión de puntos en polígonos. En el momento de la compilación ha de seleccionarse el tipo de dato que se utilizará en los cálculos intermedios de las funciones \ref PtoEnPoligonoVerticeBorde y \ref PtoEnPoligonoVerticeBordeDouble. Si los puntos de trabajo están muy alejados de los polígonos pueden darse casos de resultados erróneos. Sería conveniente que los cálculos internedios se hiciesen en variables de 64 bits, pero el tipo long int suele ser de 4 bytes en procesadores de 32 bits. Para seleccionar este tipo como long long int, lo que en procesadores de 32 bits equivale a una variable de 64 bits, es necesario definir la variable para el preprocesador \em PTOPOL_BORDE_LONG_64. En procesadores de 64 bits no es necesario (aunque puede utilizarse), ya que el tipo long int tiene una longitud de 64 bits. Si no se define la variable, se usará un tipo long int para los cálculos intermedios. En \p gcc, las variables para el preprocesador se pasan como \em -DXXX, donde \em XXX es la variable a introducir. El uso del tipo long long int en procesadores de 32 bits puede hacer que las funciones se ejecuten hasta 10 veces más lentamente que si se utiliza el tipo long int. Con cálculos internos de 32 bits las coordenadas de los vértices del polígono no han de estar más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas 3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto podríamos chequear un punto en un polo con respecto a un polígono en el ecuador en coordenadas UTM expresadas en centímetros. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 05 de abril de 2010 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _PTOPOL_H_ #define _PTOPOL_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include"libgeoc/errores.h" #include"libgeoc/geocnan.h" #include"libgeoc/geocomp.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_PTO_FUERA_POLIG \brief Identificador de punto fuera de un polígono. \date 12 de abril de 2011: Creación de la constante. */ #define GEOC_PTO_FUERA_POLIG 0 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_PTO_DENTRO_POLIG \brief Identificador de punto dentro de un polígono. \date 12 de abril de 2011: Creación de la constante. */ #define GEOC_PTO_DENTRO_POLIG 1 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_PTO_VERTICE_POLIG \brief Identificador de punto que es un vértice de un polígono. \date 12 de abril de 2011: Creación de la constante. */ #define GEOC_PTO_VERTICE_POLIG 2 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_PTO_BORDE_POLIG \brief Identificador de punto que está en el borde de un polígono. \date 12 de abril de 2011: Creación de la constante. */ #define GEOC_PTO_BORDE_POLIG 3 /******************************************************************************/ /******************************************************************************/ /** \typedef ptopol_long \brief Nombre del tipo long int o long long int para utilizar en los cálculos intermedios de las funciones \ref PtoEnPoligonoVerticeBorde y \ref PtoEnPoligonoVerticeBordeDouble. Si los puntos de trabajo están muy alejados de los polígonos pueden darse casos de resultados erróneos. Sería conveniente que los cálculos internedios se hiciesen en variables de 64 bits, pero el tipo long int suele ser de 4 bytes en procesadores de 32 bits. Mediante la variable del preprocesador PTOPOL_BORDE_LONG_64 indicamos que este tipo sea long long int, lo que en procesadores de 32 bits equivale a una variable de 64 bits. \note Este tipo de dato sólo es para uso interno en el fichero \ref ptopol.c. No se recomienda su uso fuera de él, ya que habría que tener el cuenta la variable del preprocesador cada vez que se incluyera este fichero (\ref ptopol.h) en un programa u otro fichero. \date 19 de abril de 2011: Creación del tipo. */ #if defined(PTOPOL_BORDE_LONG_64) typedef long long int ptopol_long; #else typedef long int ptopol_long; #endif /******************************************************************************/ /******************************************************************************/ /** \brief Indica si hay alguna función compilada en paralelo con OpenMP en el fichero \ref ptopol.c. \return Dos posibles valores: - 0: No hay ninguna función compilada en paralelo con OpenMP. - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP. \note Esta función asume que el argumento \em version tiene suficiente memoria asignada (si es distinto de \p NULL). \date 13 de abril de 2011: Creación de la función. \date 25 de agosto de 2011: Adición del argumento de entrada \em version. */ int GeocParOmpPtopol(char version[]); /******************************************************************************/ /******************************************************************************/ /** \brief Indica si se está utilizando el tipo log long int para la realización de cálculos intermedios en las funciones de chequeo de puntos en polígonos que son capaces de detectar si un punto está en el borde. \return Dos posibles valores: - 0: No se está utilizando log long int. - Distinto de 0: Sí se está utilizando log long int. \date 19 de abril de 2011: Creación de la función. */ int GeocLongLongIntPtopol(void); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en un rectángulo. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] xMin Coordenada X mínima del rectángulo. \param[in] xMax Coordenada X máxima del rectángulo. \param[in] yMin Coordenada Y mínima del rectángulo. \param[in] yMax Coordenada Y máxima del rectángulo. \return Varias posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera del rectángulo. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del rectángulo. - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del rectángulo. - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera del rectángulo, pero no es un vértice. \note Esta función asume que \em xMinEsta función puede dar resultados incorrectos para puntos muy alejados de los polígonos de trabajo. Para intentar mitigar este efecto, puede seleccionarse mediante una variable del preprocesador la precisión de algunas variables intermedias. Para más información se recomienda leer el encabezado de este fichero. \note Con cálculos internos de 32 bits las coordenadas de los vértices del polígono no han de estar más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas 3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto podríamos chequear un punto en un polo con respecto a un polígono en el ecuador en coordenadas UTM expresadas en centímetros. \date 06 de abril de 2010: Creación de la función. \date 10 de abril de 2011: Adición de los argumentos de entrada \em incX e \em incY. \date 12 de abril de 2011: Las variables de salida son ahora constantes simbólicas. \date 18 de abril de 2011: Reescritura de la función, siguiendo la página 244 del libro de O'Rourke. La versión anterior la había adaptado del código de la web de O'Rourke, y lo había hecho mal. \todo Esta función no está probada. */ int PtoEnPoligonoVerticeBorde(const long x, const long y, const long* coorX, const long* coorY, const size_t N, const size_t incX, const size_t incY); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en un polígono de un número arbitrario de lados. Esta función trata correctamente los puntos situados en los bordes y/o los vértices del polígono. Trabaja con datos de tipo real, que convierte a enteros (por redondeo o truncamiento) intermamente, mediante la aplicación de un factor de escala. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] coorX Vector que contiene las coordenadas X de los vértices del polígono. Sólo puede contener un polígono. \param[in] coorY Vector que contiene las coordenadas Y de los vértices del polígono. Sólo puede contener un polígono. \param[in] N Número de elementos que contienen los vectores \em coorX y \em coorY. \param[in] incX Posiciones de separación entre los elementos del vector \em coorX. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em coorY. Este argumento siempre ha de ser un número positivo. \param[in] factor Factor de multiplicación para aplicar a las coordenadas del punto de trabajo y de los vértices del polígono, con el fin de aumentar su resolución antes de convertirlas en valores de tipo entero (\p long \p int). El uso de factores muy grandes puede provocar resultados erróneos. Ver la nota al final de la documentación de esta función. \param[in] redondeo Identificador de redondeo o truncamiento en la conversión interna de variables de tipo \p double en variables de tipo \p long \p int. Dos posibilidades: - 0: La conversión se hace por truncamiento. - Distinto de 0: La conversión se hace por redondeo. \return Varias posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono. - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del polígono. - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera del polígono, pero no es un vértice. \note Esta función no comprueba si el número de elementos de los vectores \em coorX y \em coorY es congruente con los valores pasados en \em N, \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual a 3, que es el número mínimo de vértices que ha de tener un polígono. \note El polígono ha de ser único, sin huecos. Es opcional repetir las coordenadas del primer punto al final del listado. \note Los vértices del polígono pueden listarse en sentido dextrógiro o levógiro. \note El código de esta función es el mismo que el de la función \ref PtoEnPoligonoVerticeBorde, salvo que convierte internamente varias variables intermedias de tipo \p double a tipo \p long \p int, que es el tipo de datos necesario para detectar correctamente si un punto pertenece al borde de un polígono. \note Las variables se redondean internamente con la orden (long)(round(factor*variable)), y se truncan con la orden (long)(factor*variable). \note Esta función puede dar resultados incorrectos para puntos muy alejados de los polígonos de trabajo. Para intentar mitigar este efecto, puede seleccionarse mediante una variable del preprocesador la precisión de algunas variables intermedias. Para más información se recomienda leer el encabezado de este fichero. \note Con cálculos internos de 32 bits las coordenadas de los vértices del polígono no han de estar más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas 3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto podríamos chequear un punto en un polo con respecto a un polígono en el ecuador en coordenadas UTM expresadas en centímetros. En este caso nos referimos a las coordenadas una vez aplicado el factor de escala \em factor. \date 10 de abril de 2011: Creación de la función. \date 11 de abril de 2011: Adición del argumento de entrada \em redondeo. \date 12 de abril de 2011: Las variables de salida son ahora constantes simbólicas. \date 18 de abril de 2011: Reescritura de la función, siguiendo la página 244 del libro de O'Rourke. La versión anterior la había adaptado del código de la web de O'Rourke, y lo había hecho mal. \todo Esta función no está probada. */ int PtoEnPoligonoVerticeBordeDouble(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const double factor, const int redondeo); /******************************************************************************/ /******************************************************************************/ /** \brief Busca valores #GEOC_NAN es uno o dos vectores de datos. Esta función está pensada para el chequeo en paralelo de la inclusión de puntos en polígonos. \param[in] x Vector que contiene las coordenadas X de los vértices de una serie de polígonos, tal y como entraría en la definición de múltiples elementos (pero sin huecos) para la función \ref PtoEnPoligono. La marca de separación entre polígonos ha de ser #GEOC_NAN. \param[in] y Vector que contiene las coordenadas Y de los vértices de una serie de polígonos, tal y como entraría en la definición de múltiples elementos (pero sin huecos) para la función \ref PtoEnPoligono. La marca de separación entre polígonos ha de ser #GEOC_NAN. Este argumento puede valer NULL, en cuyo caso sólo se trabajará con el vector \em x. \param[in] N Número de elementos que contienen los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[out] nNan Número de valores #GEOC_NAN encontrados, que es el número de elementos del vector de salida. \return Varias posibilidades: - Si todo ha ido bien, vector que contiene las posiciones en el vector o vectores originales donde se almacena el valor #GEOC_NAN. Si se trabaja con los vectores \em x e \em y, la posición sólo se extrae si ambos vectores contienen #GEOC_NAN para una misma posición. - NULL: Pueden haber ocurrido dos cosas: - Si \em nNan vale 0, en los datos de entrada no hay ningún valor #GEOC_NAN. - Si \em nNan es mayor que 0, ha ocurrido un error interno de asignación de memoria. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados en \em N, \em incX e \em incY. \note Las posiciones de los elementos #GEOC_NAN encontradas se refieren al número de elementos \em N de los vectores de trabajo. Para encontrar la posición real en memoria es necesario tener en cuenta las variables \em incX e \em incY. \date 13 de abril de 2011: Creación de la función. \todo Esta función no está probada. */ size_t* BuscaGeocNanEnVectores(const double* x, const double* y, const size_t N, const size_t incX, const size_t incY, size_t* nNan); /******************************************************************************/ /******************************************************************************/ /** \brief Extrae los parámetros de inicio y número de elementos de un polígono en una lista de polígonos separados por un indicador. Esta función está pensada para el chequeo en paralelo de la inclusión de puntos en polígonos. \param[in] posInd Vector que contiene las posiciones de los indicadores en el vector original. Este argumento es el vector que devuelve la función \ref BuscaGeocNanEnVectores. \param[in] indPosInd Índice en el vector de posiciones de indicadores del indicador que da comienzo al polígono de trabajo. \param[in] incX Posiciones de separación entre los elementos del vector original que almacena las coordenadas X del listado de polígonos. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector original que almacena las coordenadas Y del listado de polígonos. Este argumento siempre ha de ser un número positivo. \param[out] iniX Posición de inicio de la coordenada X del polígono de trabajo en el vector original que almacena las coordenadas X del listado de polígonos. Para encontrar la posición real en memoria es necesario tener en cuenta la variable \em incX. \param[out] iniY Posición de inicio de la coordenada Y del polígono de trabajo en el vector original que almacena las coordenadas Y del listado de polígonos. Para encontrar la posición real en memoria es necesario tener en cuenta la variable \em incY. \param[out] nElem Número de elementos que conforman el polígono de trabajo. \note Esta función no comprueba si el vector \em posInd contiene datos. \note Esta función asume que el vector \em posInd contiene un número \b *PAR* de datos. \note Esta función asume que el argumento \em indPosInd no es la última posición del vector \em posInd. \date 13 de abril de 2011: Creación de la función. \todo Esta función no está probada. */ void DatosPoliIndividualEnVecInd(const size_t* posInd, const size_t indPosInd, const size_t incX, const size_t incY, size_t* iniX, size_t* iniY, size_t* nElem); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en una serie de polígonos individuales de un número arbitrario de lados. Esta función puede no dar resultados correctos para puntos en los bordes y/o los vértices del polígono. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] coorX Vector que contiene las coordenadas X de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] coorY Vector que contiene las coordenadas Y de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] N Número de elementos que contienen los vectores \em coorX y \em coorY. \param[in] incX Posiciones de separación entre los elementos del vector \em coorX. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em coorY. Este argumento siempre ha de ser un número positivo. \param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y \em coorY de los elementos #GEOC_NAN, que separan los polígonos individuales. Este vector es la salida de la función \ref BuscaGeocNanEnVectores. \param[in] nNan Número de elementos del vector \em posNan. \param[out] poli Número del polígono en que está incluido el punto de trabajo. Si hay varios polígonos que contienen al punto de trabajo no se puede asegurar cuál de ellos será el indicado en este argumento. Este argumento sólo tiene sentido si el valor retornado por la función es distinto de #GEOC_PTO_FUERA_POLIG. \return Dos posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos listados. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono de entre los listados. \note Esta función se puede ejecutar en paralelo con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em coorX y \em coorY es congruente con los valores pasados en \em N, \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual a 3, que es el número mínimo de vértices que ha de tener un polígono. \note Esta función no comprueba si el número de elementos del vector \em posNan es congruente con el valor pasado en \em nNan. \note Esta función no detecta el caso de que el punto de trabajo esté en el borde o en un vértice del polígono. En este caso, el test puede dar el punto dentro o fuera, indistintamente (el chequeo del mismo punto con el mismo polígono siempre dará el mismo resultado). \note La estructura de los vectores de coordenadas es la misma que la de la función \ref PtoEnPoligono. Las marcas de comienzo y final de los listados, así como las de separación entre polígonos han de ser valores #GEOC_NAN. \note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los elementos primero y último han de ser #GEOC_NAN. \note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados como polígonos individuales. \date 14 de abril de 2011: Creación de la función. \todo Esta función no está probada. */ int PtoEnPoligonoInd(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, size_t* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en una serie de polígonos individuales de un número arbitrario de lados. Esta función puede no dar resultados correctos para puntos en los bordes del polígono. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] coorX Vector que contiene las coordenadas X de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] coorY Vector que contiene las coordenadas Y de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] N Número de elementos que contienen los vectores \em coorX y \em coorY. \param[in] incX Posiciones de separación entre los elementos del vector \em coorX. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em coorY. Este argumento siempre ha de ser un número positivo. \param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y \em coorY de los elementos #GEOC_NAN, que separan los polígonos individuales. Este vector es la salida de la función \ref BuscaGeocNanEnVectores. \param[in] nNan Número de elementos del vector \em posNan. \param[out] poli Número del polígono en que está incluido el punto de trabajo. Si hay varios polígonos que contienen al punto de trabajo no se puede asegurar cuál de ellos será el indicado en este argumento. Este argumento sólo tiene sentido si el valor retornado por la función es distinto de #GEOC_PTO_FUERA_POLIG. \return Dos posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos listados. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono de entre los listados. - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice de, al menos, un polígono de entre los listados. \note Esta función se puede ejecutar en paralelo con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em coorX y \em coorY es congruente con los valores pasados en \em N, \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual a 3, que es el número mínimo de vértices que ha de tener un polígono. \note Esta función no comprueba si el número de elementos del vector \em posNan es congruente con el valor pasado en \em nNan. \note Esta función no detecta el caso de que el punto de trabajo esté en el borde del polígono. En este caso, el test puede dar el punto dentro o fuera, indistintamente (el chequeo del mismo punto con el mismo polígono siempre dará el mismo resultado). \note La estructura de los vectores de coordenadas es la misma que la de la función \ref PtoEnPoligono. Las marcas de comienzo y final de los listados, así como las de separación entre polígonos han de ser valores #GEOC_NAN. \note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los elementos primero y último han de ser #GEOC_NAN. \note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados como polígonos individuales. \date 14 de abril de 2011: Creación de la función. \todo Esta función no está probada. */ int PtoEnPoligonoVerticeInd(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, size_t* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en una serie de polígonos individuales de un número arbitrario de lados. Esta función trata correctamente los puntos situados en los bordes y/o los vértices del polígono, pero sólo trabaja con datos de tipo entero. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] coorX Vector que contiene las coordenadas X de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] coorY Vector que contiene las coordenadas Y de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] N Número de elementos que contienen los vectores \em coorX y \em coorY. \param[in] incX Posiciones de separación entre los elementos del vector \em coorX. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em coorY. Este argumento siempre ha de ser un número positivo. \param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y \em coorY de los elementos #GEOC_NAN, que separan los polígonos individuales. Este vector es la salida de la función \ref BuscaGeocNanEnVectores. \param[in] nNan Número de elementos del vector \em posNan. \param[out] poli Número del polígono en que está incluido el punto de trabajo. Si hay varios polígonos que contienen al punto de trabajo no se puede asegurar cuál de ellos será el indicado en este argumento. Este argumento sólo tiene sentido si el valor retornado por la función es distinto de #GEOC_PTO_FUERA_POLIG. \return Dos posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos listados. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono de entre los listados. - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice de, al menos, un polígono de entre los listados. - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera de, al menos, un polígono de entre los listados, pero no es un vértice. \note Esta función se puede ejecutar en paralelo con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em coorX y \em coorY es congruente con los valores pasados en \em N, \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual a 3, que es el número mínimo de vértices que ha de tener un polígono. \note Esta función no comprueba si el número de elementos del vector \em posNan es congruente con el valor pasado en \em nNan. \note La estructura de los vectores de coordenadas es la misma que la de la función \ref PtoEnPoligono. Las marcas de comienzo y final de los listados, así como las de separación entre polígonos han de ser valores #GEOC_NAN. \note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los elementos primero y último han de ser #GEOC_NAN. \note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados como polígonos individuales. \note Esta función puede dar resultados incorrectos para puntos muy alejados de los polígonos de trabajo. Para intentar mitigar este efecto, puede seleccionarse mediante una variable del preprocesador la precisión de algunas variables intermedias. Para más información se recomienda leer el encabezado de este fichero. \note Con cálculos internos de 32 bits las coordenadas de los vértices del polígono no han de estar más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas 3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto podríamos chequear un punto en un polo con respecto a un polígono en el ecuador en coordenadas UTM expresadas en centímetros. \date 14 de abril de 2011: Creación de la función. \todo Esta función no está probada. */ int PtoEnPoligonoVerticeBordeInd(const long x, const long y, const long* coorX, const long* coorY, const size_t N, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, size_t* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en una serie de polígonos individuales de un número arbitrario de lados. Esta función trata correctamente los puntos situados en los bordes y/o los vértices del polígono. Trabaja con datos de tipo real, que convierte a enteros (por redondeo o truncamiento) intermamente, mediante a aplicación de un factor de escala. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] coorX Vector que contiene las coordenadas X de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] coorY Vector que contiene las coordenadas Y de los vértices de los elementos. Puede contener varios polígonos, pero no huecos (si los hay, serán tratados como otros polígonos). \param[in] N Número de elementos que contienen los vectores \em coorX y \em coorY. \param[in] incX Posiciones de separación entre los elementos del vector \em coorX. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em coorY. Este argumento siempre ha de ser un número positivo. \param[in] factor Factor de multiplicación para aplicar a las coordenadas del punto de trabajo y de los vértices de los polígonos, con el fin de aumentar su resolución antes de convertirlas en valores de tipo entero (\p long \p int). El uso de factores muy grandes puede provocar resultados erróneos. Ver la nota al final de la documentación de esta función. \param[in] redondeo Identificador de redondeo o truncamiento en la conversión interna de variables de tipo \p double en variables de tipo \p long \p int. Dos posibilidades: - 0: La conversión se hace por truncamiento. - Distinto de 0: La conversión se hace por redondeo. \param[in] posNan Vector que almacena las posiciones en los vectores \em coorX y \em coorY de los elementos #GEOC_NAN, que separan los polígonos individuales. Este vector es la salida de la función \ref BuscaGeocNanEnVectores. \param[in] nNan Número de elementos del vector \em posNan. \param[out] poli Número del polígono en que está incluido el punto de trabajo. Si hay varios polígonos que contienen al punto de trabajo no se puede asegurar cuál de ellos será el indicado en este argumento. Este argumento sólo tiene sentido si el valor retornado por la función es distinto de #GEOC_PTO_FUERA_POLIG. \return Dos posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera de todos los polígonos listados. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro de, al menos, un polígono de entre los listados. - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice de, al menos, un polígono de entre los listados. - #GEOC_PTO_BORDE_POLIG: El punto pertenece a la frontera de, al menos, un polígono de entre los listados, pero no es un vértice. \note Esta función se puede ejecutar en paralelo con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em coorX y \em coorY es congruente con los valores pasados en \em N, \em incX e \em incY. Tampoco comprueba si \em N es un valor mayor o igual a 3, que es el número mínimo de vértices que ha de tener un polígono. \note Esta función no comprueba si el número de elementos del vector \em posNan es congruente con el valor pasado en \em nNan. \note Las variables se redondean internamente con la orden (long)(round(factor*variable)), y se truncan con la orden (long)(factor*variable). \note La estructura de los vectores de coordenadas es la misma que la de la función \ref PtoEnPoligono. Las marcas de comienzo y final de los listados, así como las de separación entre polígonos han de ser valores #GEOC_NAN. \note Aunque los vectores \em coorX y \em coorY sólo contengan un polígono, los elementos primero y último han de ser #GEOC_NAN. \note Los huecos en los polígonos no serán tenidos en cuenta, serán tratados como polígonos individuales. \note Esta función puede dar resultados incorrectos para puntos muy alejados de los polígonos de trabajo. Para intentar mitigar este efecto, puede seleccionarse mediante una variable del preprocesador la precisión de algunas variables intermedias. Para más información se recomienda leer el encabezado de este fichero. \note Con cálculos internos de 32 bits las coordenadas de los vértices del polígono no han de estar más lejos de las de los puntos de trabajo de unas 40000 unidades. Con cálculos de 64 bits, los polígonos pueden estar alejados de los puntos de trabajo unas 3000000000 unidades, lo que corresponde a coordenadas Y UTM ajustadas al centímetro. Con esto podríamos chequear un punto en un polo con respecto a un polígono en el ecuador en coordenadas UTM expresadas en centímetros. En este caso nos referimos a las coordenadas una vez aplicado el factor de escala \em factor. \date 14 de abril de 2011: Creación de la función. \todo Esta función no está probada. */ int PtoEnPoligonoVerticeBordeDoubleInd(const double x, const double y, const double* coorX, const double* coorY, const size_t N, const size_t incX, const size_t incY, const double factor, const int redondeo, const size_t* posNan, const size_t nNan, size_t* poli); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/compilador.h0000644000175000017500000001226112032305135020375 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup general geopot @{ \file compilador.h \brief Declaración de funciones para la detección de compiladores. \author José Luis García Pallero, jgpallero@gmail.com \date 28 de abril de 2011 \version 1.0 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _COMPILADOR_H_ #define _COMPILADOR_H_ /******************************************************************************/ /******************************************************************************/ #include /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si el compilador utilizado para compilar este fichero es de la familia GCC. \param[out] noGnu Identificador de que estamos ante un compilador que no es de la familia GCC, diga lo que diga la variable devuelta por la función (ver nota al final de la documentación). Este argumento sólo es utilizado si en la entrada su valor es distinto de \p NULL. Dos posibles valores de salida: - 0: El compilador \b *ES* de la familia GCC. - Distinto de 0: El compilador \b *NO* \b *ES* de la familia GCC. \return Dos posibilidades: - 0: El compilador no pertenece a la familia GCC. - Distinto de 0: El compilador sí pertenece a la familia GCC (para una validez total de este valor hay que tener en cuenta el argumento \em noGnu). \note Esta función realiza la comprobación mediante el chequeo de la existencia de la constante simbólica \p __GNUC__. Este hecho hace que la detección del compilador se lleve a cabo durante la compilación del fichero que contiene a esta función, por lo que hay que tener en cuenta si ésta es llamada desde una función contenida en otro fichero que no fue compilado con un compilador de la familia GCC. \note Algunos compiladores, como el Intel C/C++ Compiler (\p icc), definen por defecto la macro \p __GNUC__, por lo que la detección puede ser errónea. Para estos casos ha de tenerse en cuenta el argumento \em noGnu. \note En las versiones más recientes de \p icc, el argumento \p -no-gcc suprime la definición de \p __GNUC__. \date 11 de octubre de 2009: Creación de la función. */ int EsCompiladorGNU(int* noGnu); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/geom.h0000644000175000017500000000640512032305135017176 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \defgroup geom Módulo GEOMETRIA \brief En este módulo se reúnen las funciones necesarias para el tratamiento de problemas de geometría. @{ \file geom.h \brief Inclusión de ficheros de cabecera para el trabajo con la biblioteca GEOMETRIA. \author José Luis García Pallero, jgpallero@gmail.com \date 26 de diciembre de 2009 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _GEOM_H_ #define _GEOM_H_ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/dpeucker.h" #include"libgeoc/eucli.h" #include"libgeoc/greiner.h" #include"libgeoc/polig.h" #include"libgeoc/polil.h" #include"libgeoc/ptopol.h" #include"libgeoc/recpolil.h" #include"libgeoc/segmento.h" /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/geocnan.h0000755000175000017500000002746412032305135017674 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \defgroup geocnan Módulo GEOCNAN \ingroup geom matriz gshhs \brief En este módulo se reúnen constantes y funciones para el trabajo con valores Not-a-Number. @{ \file geocnan.h \brief Declaración de constantes y funciones para el trabajo con valores Not-a-Number. \author José Luis García Pallero, jgpallero@gmail.com \date 26 de mayo de 2011 \version 1.0 \section Licencia Licencia Copyright (c) 2010-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _GEOCNAN_H_ #define _GEOCNAN_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include #include #include"libgeoc/errores.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_NAN \brief Constante \em Not-a-Number (\em NaN). Se define como \em 0.0/0.0. \date 21 de diciembre de 2010: Creación de la constante. */ #define GEOC_NAN (0.0/0.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_NAN_TXT \brief Constante \em Not-a-Number (\em NaN), como cadena de texto. \date 22 de septiembre de 2011: Creación de la constante. */ #define GEOC_NAN_TXT "NaN" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_NAN_LON_FORM_NUM_SIMPLE \brief Longitud de una cadena de texto auxiliar para el cálculo de la longitud de una cadena de formato numérico simple. \date 22 de septiembre de 2011: Creación de la constante. */ #define GEOC_NAN_LON_FORM_NUM_SIMPLE 100 /******************************************************************************/ /******************************************************************************/ /** \brief Devuelve el número que representa el valor \em Not-a-Number (\em NaN), que se define como el resultado de la evaluación de la operación \em 0.0/0.0. \return Valor NaN. \note Esta función devuelve el valor almacenado en la constante #GEOC_NAN. \date 21 de diciembre de 2010: Creación de la función. \date 24 de mayo de 2011: Ahora la función devuelve el valor absoluto de #GEOC_NAN, calculado con la función fabs() de C estándar. Se ha hecho así porque, a veces, al imprimir un valor normal de #GEOC_NAN, éste aparecía con un signo negativo delante. \date 22 de septiembre de 2011: Lo del fabs() no funciona. Parece que los problemas en la impresión dependen del compilador y los flags de optimización utilizados. No obstante, se mantiene el uso de la función fabs() en el código. \todo Esta función todavía no está probada. */ double GeocNan(void); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un número es \em Not-a-Number (\em NaN). \param[in] valor Un número. \return Dos posibilidades: - 0: El número pasado no es NaN. - Distinto de 0: El número pasado sí es NaN. \note Esta función ha sido adaptada de LAPACK 3.2.1, disnan.f, (http://www.netlib.org/lapack). \date 21 de diciembre de 2010: Creación de la función. \todo Esta función todavía no está probada. */ int EsGeocNan(const double valor); /******************************************************************************/ /******************************************************************************/ /** \brief Busca valores #GEOC_NAN es un vector de datos. \param[in] datos Vector de trabajo. \param[in] nDatos Número de elementos que contiene el vector \em datos. \param[in] incDatos Posiciones de separación entre los elementos del vector \em datos. Este argumento siempre ha de ser un número positivo. \param[out] nNan Número de valores #GEOC_NAN encontrados, que es el número de elementos del vector de salida. \return Varias posibilidades: - Si todo ha ido bien, vector que contiene las posiciones en el vector original donde se almacena el valor #GEOC_NAN. - NULL: Pueden haber ocurrido dos cosas: - Si \em nNan vale 0, en los datos de entrada no hay ningún valor #GEOC_NAN. - Si \em nNan es mayor que 0, ha ocurrido un error interno de asignación de memoria. \note Esta función no comprueba si el número de elementos del vector \em datos es congruente con los valores pasados en \em nDatos e \em incDatos. \note Las posiciones de los elementos #GEOC_NAN encontradas se refieren al número de elementos \em nDatos del vector de trabajo. Para encontrar la posición real en memoria es necesario tener en cuenta la variable \em incDatos. \date 26 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ size_t* PosGeocNanEnVector(const double* datos, const size_t nDatos, const size_t incDatos, size_t* nNan); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el número de carácteres que ocupa un valor numérico imprimido con determinado formato. \param[in] formato Cadena de formato para imprimir \b *UN \b ÚNICO* valor numérico (de cualquier tipo). \return Número de carácteres que ocupa un valor numérico imprimido según el formato pasado. \note Esta función no comprueba internamente si la cadena de formato es correcta. \note \em formato no puede dar lugar a un texto impreso de más de #GEOC_NAN_LON_FORM_NUM_SIMPLE carácteres. \date 22 de septiembre de 2011: Creación de la función. \todo Esta función todavía no está probada. */ size_t LonFormatoNumSimple(const char formato[]); /******************************************************************************/ /******************************************************************************/ /** \brief Convierte una cadena de formato para imprimir un \b *ÚNICO* número en una cadena para imprimir texto con el mismo ancho que el que tendría de haber sido imprimida como número. \param[in] formatoNum Cadena de formato para imprimir \b *UN \b ÚNICO* valor numérico (de cualquier tipo). \param[out] formatoTexto Cadena de texto que almacenará la cadena de formato para la impresión en modo texto. \note Esta función no comprueba internamente si la cadena de formato numérico es correcta. \note \em formatoNum no puede dar lugar a un texto impreso de más de #GEOC_NAN_LON_FORM_NUM_SIMPLE carácteres. \note Esta función asume que \em formatoTexto tiene espacio suficiente para almacenar la cadena de salida. \note Si \em formatoNum contiene al final carácteres de retorno de carro y salto de línea, estos no son tenidos en cuenta en la creación de la cadena de salida (no son tenidos en cuenta en el sentido de que no se añaden al formato de salida, pero el espacio que ocupan sí se computa). \date 22 de septiembre de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void FormatoNumFormatoTexto(const char formatoNum[], char formatoTexto[]); /******************************************************************************/ /******************************************************************************/ /** \brief Imprime valores Not-a-Number en modo texto (#GEOC_NAN_TXT) es un fichero. \param[in] idFich Identificador del fichero de trabajo, abierto para escribir. \param[in] nNan Número de veces que se ha de imprimir el valor #GEOC_NAN_TXT, una a continuación de otra. \param[in] formato Cadena de formato para la impresión de cada valor #GEOC_NAN_TXT. \param[in] retCarro Identificador para añadir un retorno de carro y cambio de línea al final de la impresión de datos, independientemente del valor pasado en el argumento \em formato. Dos posibilidades: - 0: No se imprime retorno de carro y cambio de línea al final. - Distinto de 0: Sí se imprime retorno de carro y cambio de línea al final. \note Esta función no comprueba internamente si el fichero de entrada está abierto correctamente. \note Esta función no comprueba internamente si la cadena de formato es correcta. \note Si se ha indicado que se imprima salto de línea y retorno de carro al final, este se imprime aunque \em nNan valga 0. \date 22 de septiembre de 2011: Creación de la función. \todo Esta función no está probada. */ void ImprimeGeocNanTexto(FILE* idFich, const size_t nNan, const char formato[], const int retCarro); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/fgeneral.h0000644000175000017500000010330512032305135020027 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup eop general geom geopot matriz @{ \file fgeneral.h \brief Declaración de macros y funciones de utilidad general. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 25 de septiembre de 2009 \version 1.0 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _FGENERAL_H_ #define _FGENERAL_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include #include #include"libgeoc/constantes.h" #include"libgeoc/errores.h" #include"libgeoc/geocomp.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_SIGNO \brief Macro para determinar el signo de un escalar. \param[in] a Un número. \return Signo del dato de entrada. Dos posibilidades: - -1.0: El dato pasado es negativo. - 1.0: El dato pasado es positivo o 0.0. \date 10 de junio de 2011: Creación de la macro. */ #define GEOC_SIGNO(a) ((a)>=0.0 ? 1.0 : -1.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_MAX \brief Macro para seleccionar el valor máximo entre dos escalares. \param[in] a Un número. \param[in] b Otro número. \return El mayor de los dos argumentos de entrada. \date 25 de septiembre de 2009: Creación de la macro. */ #define GEOC_MAX(a,b) ((a)>(b) ? (a) : (b)) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_MIN \brief Macro para seleccionar el valor mínimo entre dos escalares. \param[in] a Un número. \param[in] b Otro número. \return El menor de los dos argumentos de entrada. \date 25 de septiembre de 2009: Creación de la macro. */ #define GEOC_MIN(a,b) ((a)<(b) ? (a) : (b)) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_PARI \brief Macro para comprobar si un número de tipo entero es par. \param[in] a Un número. \return Dos posibilidades: - 0: El número es impar. - 1: El número es par. \note Esta macro usa el operador \b % de C para calcular el resto de la división del número pasado entre 2, por lo que el argumento de entrada ha de ser de tipo entero: \p char, \p short, \p int, \p long o \p long \p long (con los identificadores \p signed o \p undigned). \date 15 de marzo de 2011: Creación de la macro. */ #define GEOC_PARI(a) ((a)%2 ? 0 : 1) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ES_CERO \brief Macro para comprobar si un número puede considerarse cero con una cierta tolerancia. \param[in] num Número a comprobar. \param[in] tol Tolerancia. Ha de ser un número \b POSITIVO. \return Dos posibilidades: - 0: \em num es distinto de 0, tal que \f$num<=-tol\f$ o \f$num>=tol\f$. - 1: \em num es 0, tal que \f$ -tol < num < tol\f$. \note Para que esta macro funcione correctamente, \em tol ha de ser un número \b POSITIVO. \date 13 de marzo de 2010: Creación de la macro. \todo Esta macro todavía no está probada. */ #define GEOC_ES_CERO(num,tol) (((num)>(-(tol)))&&((num)<(tol)) ? 1 : 0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_DBL \brief Macro para realizar una conversión explícita a tipo de dato \p double. \param[in] a Un número. \return Órdenes para la conversión explícita del dato pasado a \p double. \date 19 de junio de 2011: Creación de la macro. */ #define GEOC_DBL(a) ((double)(a)) /******************************************************************************/ /******************************************************************************/ /** \brief Indica si hay alguna función compilada en paralelo con OpenMP en el fichero \ref fgeneral.c. \param[out] version Cadena identificadora de la versión de OpenMP utilizada. Este argumento sólo se utiliza si su valor de entrada es distinto de \p NULL y si hay alguna función compilada con OpenMP. \return Dos posibles valores: - 0: No hay ninguna función compilada en paralelo con OpenMP. - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP. \note Esta función asume que el argumento \em version tiene suficiente memoria asignada (si es distinto de \p NULL). \date 22 de agosto de 2011: Creación de la función. \date 25 de agosto de 2011: Adición del argumento de entrada \em version. */ int GeocParOmpFgeneral(char version[]); /******************************************************************************/ /******************************************************************************/ /** \brief Mete un ángulo en el dominio \f$]-2*\pi,2*\pi[\f$. \param[in] angulo Valor angular, en radianes. \return Valor angular de entrada, en el dominio \f$]-2*\pi,2*\pi[\f$, en radianes. \note Esta función elimina todas las vueltas completas a la circunferencia que hacen que el posible valor de entrada esté fuera de los límites del dominio de salida. \date 10 de junio de 2011: Creación de la función. */ double PonAnguloDominio(const double angulo); /******************************************************************************/ /******************************************************************************/ /** \brief Busca en una lista de coordenadas de una polilínea en una dimensión las posiciones de inicio y fin del segmento que encierra a un punto dado. \param[in] valor Coordenada del punto de trabajo, contenido en el segmento a buscar. \param[in] lista Lista con las coordenadas de la polilínea. \param[in] nDatos Número de elementos de la lista de coordenadas pasadas. \param[in] incDatos Posiciones de separación entre cada elemento de \em lista. Ha de ser un número positivo. \param[out] posInicio Posición en \em lista de la coordenada inicial del segmento buscado. \param[out] posFin Posición en \em lista de la coordenada final del segmento buscado. \note Para convertir las posiciones devueltas por la función en las posiciones reales del array en memoria, han de ser multiplicadas por el valor \em incDatos. \note En las siguientes notas, cuando se habla de la longitud o el número de elementos de \em lista quiere decir el número de datos de trabajo, no todas las posiciones almacenadas en memoria. \note Esta función no comprueba internamente si la longitud de \em lista es congruente con el valor \em nDatos. \note Esta función supone que \em lista contiene un número de elementos >= 2. \note Esta función supone que los elementos almacenados en \em lista están ordenados de menor a mayor. \note Esta función supone que \em lista[0] <= \em valor >= \em lista[nDatos-1]. \note Si algún elemento de \em lista es igual a \em valor, su posición será el punto de inicio del segmento calculado, excepto si el elemento de \em lista es el último, en cuyo caso será el punto final. \date 06 de diciembre de 2010: Creación de la función. */ void BuscaSegmento1DInc(const double valor, const double* lista, const size_t nDatos, const size_t incDatos, size_t* posInicio, size_t* posFin); /******************************************************************************/ /******************************************************************************/ /** \brief Busca en una lista de coordenadas de una polilínea en una dimensión las posiciones de inicio y fin del segmento que encierra a un punto dado. \param[in] valor Coordenada del punto de trabajo, contenido en el segmento a buscar. \param[in] lista Lista con las coordenadas de la polilínea. \param[in] nDatos Número de elementos de la lista de coordenadas pasadas. \param[out] posInicio Posición en \em lista de la coordenada inicial del segmento buscado. \param[out] posFin Posición en \em lista de la coordenada final del segmento buscado. \note Esta función no comprueba internamente si la longitud de \em lista es congruente con el valor \em nDatos. \note Esta función supone que \em lista contiene un número de elementos >= 2. \note Esta función supone que los elementos almacenados en \em lista están ordenados de menor a mayor. \note Esta función supone que \em lista[0] <= \em valor >= \em lista[nDatos-1]. \note Si algún elemento de \em lista es igual a \em valor, su posición será el punto de inicio del segmento calculado, excepto si el elemento de \em lista es el último, en cuyo caso será el punto final. \date 11 de octubre de 2009: Creación de la función. */ void BuscaSegmento1D(const double valor, const double* lista, const size_t nDatos, size_t* posInicio, size_t* posFin); /******************************************************************************/ /******************************************************************************/ /** \brief Busca las posiciones fila y columna del elemento de una matriz correspondiente a la esquina NW del cuadrado que encierra a un punto dado. \param[in] xPto Coordenada X del punto de trabajo. \param[in] yPto Coordenada Y del punto de trabajo. \param[in] xMin Coordenada X mínima (esquina W) de los puntos almacenados en la matriz. \param[in] xMax Coordenada X máxima (esquina E) de los puntos almacenados en la matriz. \param[in] yMin Coordenada Y mínima (esquina S) de los puntos almacenados en la matriz. \param[in] yMax Coordenada Y máxima (esquina N) de los puntos almacenados en la matriz. \param[in] pasoX Paso de malla (valor absoluto) en la dirección X. \param[in] pasoY Paso de malla (valor absoluto) en la dirección Y. \param[out] fil Fila del elemento NW del cuadrado que encierra al punto de trabajo. \param[out] col Columna del elemento NW del cuadrado que encierra al punto de trabajo. \note Esta función no comprueba internamente si las coordenadas del punto de trabajo son congruentes con los límites de la matriz. \note Esta función asume que los pasos de malla son congruentes con los límites de la malla (supone que el cálculo del número de nodos es un número entero o del tipo X.9... o X.0...). \note Esta función asume que \em xMin < \em xMax y que \em yMin < \em yMax. \note Esta función asume que \em pasoX y \em pasoY han sido introducidos en valor absoluto. \date 15 de mayo de 2010: Creación de la función. \date 25 de septiembre de 2011: Corrección de error que hacía que se calculase una fila de más en determinados casos. \todo Esta función no está probada. */ void BuscaPosNWEnMalla(const double xPto, const double yPto, const double xMin, const double xMax, const double yMin, const double yMax, const double pasoX, const double pasoY, size_t* fil, size_t* col); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el elemento de mínimo valor en una lista de tipo \p double. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \return Elemento de mínimo valor. \note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o superior (se detecta automáticamente en la compilación). \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \date 22 de agosto de 2011: Creación de la función. \todo Esta función todavía no está probada con OpenMP. */ double Minimo(const double* lista, const size_t nDatos, const size_t incDatos); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el elemento de máximo valor en una lista de tipo \p double. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \return Elemento de máximo valor. \note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o superior (se detecta automáticamente en la compilación). \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \date 22 de agosto de 2011: Creación de la función. \todo Esta función todavía no está probada con OpenMP. */ double Maximo(const double* lista, const size_t nDatos, const size_t incDatos); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el elemento de mínimo valor absoluto en una lista de tipo \p double. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \return Elemento de mínimo valor absoluto. \note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o superior (se detecta automáticamente en la compilación). \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \date 22 de agosto de 2011: Creación de la función. \todo Esta función todavía no está probada con OpenMP. */ double MinimoAbs(const double* lista, const size_t nDatos, const size_t incDatos); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el elemento de máximo valor absoluto en una lista de tipo \p double. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \return Elemento de máximo valor absoluto. \note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o superior (se detecta automáticamente en la compilación). \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \date 22 de agosto de 2011: Creación de la función. \todo Esta función todavía no está probada con OpenMP. */ double MaximoAbs(const double* lista, const size_t nDatos, const size_t incDatos); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el elemento de mínimo valor en una lista de tipo \p size_t. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \return Elemento de mínimo valor. \note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o superior (se detecta automáticamente en la compilación). \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \date 24 de agosto de 2011: Creación de la función. \todo Esta función todavía no está probada con OpenMP. */ size_t MinimoSizeT(const size_t* lista, const size_t nDatos, const size_t incDatos); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el elemento de máximo valor en una lista de tipo \p size_t. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \return Elemento de máximo valor. \note Esta función se puede ejecutar en paralelo con OpenMP, versión 3.1 o superior (se detecta automáticamente en la compilación). \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \date 24 de agosto de 2011: Creación de la función. \todo Esta función todavía no está probada con OpenMP. */ size_t MaximoSizeT(const size_t* lista, const size_t nDatos, const size_t incDatos); /******************************************************************************/ /******************************************************************************/ /** \brief Busca las posiciones que ocupan en una lista de tipo \p double los elementos de menor y mayor valor. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \param[out] posMin Posición en \em lista del elemento de menor valor. \param[out] posMax Posición en \em lista del elemento de mayor valor. \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \note Si hay varios elementos en la lista que se corresponden con el valor menor o mayor, la posición devuelta es la correspondiente al primer elemento a partir del inicio. \note Las posiciones devueltas lo son atendiendo al parámetro \em nDatos, por lo que para obtener las posiciones reales del elemento en memoria han de ser multiplicadas por el valor \em incDatos. \date 27 de octubre de 2009: Creación de la función. \date 29 de mayo de 2011: Adición del argumento de entrada \em incDatos. */ void MinMax(const double* lista, const size_t nDatos, const size_t incDatos, size_t* posMin, size_t* posMax); /******************************************************************************/ /******************************************************************************/ /** \brief Busca las posiciones que ocupan en una lista los elementos de menor y mayor valor absoluto. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \param[out] posMin Posición en \em lista del elemento de menor valor absoluto. \param[out] posMax Posición en \em lista del elemento de mayor valor absoluto. \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \note Si hay varios elementos en la lista que se corresponden con el valor menor o mayor, la posición devuelta es la correspondiente al primer elemento a partir del inicio. \note Las posiciones devueltas lo son atendiendo al parámetro \em nDatos, por lo que para obtener las posiciones reales del elemento en memoria han de ser multiplicadas por el valor \em incDatos. \date 27 de octubre de 2009: Creación de la función. \date 29 de mayo de 2011: Adición del argumento de entrada \em incDatos. */ void MinMaxAbs(const double* lista, const size_t nDatos, const size_t incDatos, size_t* posMin, size_t* posMax); /******************************************************************************/ /******************************************************************************/ /** \brief Busca las posiciones que ocupan en una lista de tipo \p size_t los elementos de menor y mayor valor. \param[in] lista Lista de valores. \param[in] nDatos Número de elementos de la lista de valores. \param[in] incDatos Posiciones de separación entre los elementos del vector \em lista. Este argumento siempre ha de ser un número positivo. \param[out] posMin Posición en \em lista del elemento de menor valor. \param[out] posMax Posición en \em lista del elemento de mayor valor. \note Esta función no comprueba internamente si la longitud de \em lista es congruente con los valores de \em nDatos e \em incDatos. \note Esta función supone que \em lista contiene un número de elementos >= 1. \note Si hay varios elementos en la lista que se corresponden con el valor menor o mayor, la posición devuelta es la correspondiente al primer elemento a partir del inicio. \note Las posiciones devueltas lo son atendiendo al parámetro \em nDatos, por lo que para obtener las posiciones reales del elemento en memoria han de ser multiplicadas por el valor \em incDatos. \date 08 de enero de 2010: Creación de la función. \date 29 de mayo de 2011: Adición del argumento de entrada \em incDatos. */ void MinMaxSizeT(const size_t* lista, const size_t nDatos, const size_t incDatos, size_t* posMin, size_t* posMax); /******************************************************************************/ /******************************************************************************/ /** \brief Asigna memoria para una matriz bidimensional en estilo C. \param[in] fil Número de filas de la matriz. \param[in] col Número de columnas de la matriz. \return Puntero a la matriz creada. Si ocurre algún error de asignación de memoria, se devuelve NULL. \note La memoria asignada no se inicializa a ningún valor. \note Los datos se almacenan en ROW MAJOR ORDER de forma contigua en memoria. \note Esta función no controla si alguna de las dimensiones pasadas es 0. \date 14 de enero de 2010: Creación de la función. \date 02 de diciembre de 2010: Reprogramación de la función para que los datos se almacenen en memoria de forma contigua. */ double** AsigMemMatrizC(const size_t fil, const size_t col); /******************************************************************************/ /******************************************************************************/ /** \brief Libera memoria de una matriz bidimensional en estilo C. \param[in] matriz Puntero al espacio de memoria a liberar. \date 14 de enero de 2010: Creación de la función. \date 27 de febrero de 2010: Corregido bug que hacía que la función diese error si se le pasaba un puntero a NULL. */ void LibMemMatrizC(double** matriz); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula las posiciones de comienzo de elementos repetidos en un vector. - Para un vector de datos [1,2,2,3,4,4] se devuelve el vector de posiciones [0,1,3,4]. - Para un vector de datos [1,2,2,3,4] se devuelve el vector de posiciones [0,1,3,4]. - Para un vector de datos [1,1,1,1,1] se devuelve el vector de posiciones [0]. - Para un vector de datos [1] se devuelve el vector de posiciones [0]. \param[in] datos Vector de datos. \param[in] nDatos Número de elementos de \em datos. No puede ser 0. \param[in] incDatos Posiciones de separación entre los elementos del vector \em datos. Este argumento siempre ha de ser un número positivo. \param[out] nRepe Número de elementos del vector de posiciones de comienzo de elementos repetidos devuelto por la función. \return Vector, de \em nRepe elementos, que almacena las posiciones de comienzo de elementos repetidos en el vector \em datos. Las posiciones devueltas no tienen en cuenta el argumento \em incDatos, luego no son posiciones en el array realmente almacenado en memoria. Los índices comienzan en 0. Si ocurre un error de asignación de memoria se devuelve \p NULL. \note Esta función no comprueba internamente el vector pasado contiene suficiente memoria. \note Esta función no comprueba internamente si las dimensiones del vector pasado son congruentes con el espacio almacenado en memoria. \note Esta función no comprueba internamente si el argumento \em nDatos es igual a 0. \note Para calcular con los valores de salida las posiciones reales en el vector \em datos es necesario tener en cuenta el argumento \em incDatos. \date 02 de febrero de 2011: Creación de la función. */ size_t* PosRepeEnVector(const double* datos, const size_t nDatos, const size_t incDatos, size_t* nRepe); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el número de elementos repetidos en un vector a partir de la salida de la función \ref PosRepeEnVector. - Para un vector de datos [1,2,2,3,4,4], donde la función \ref PosRepeEnVector devuelve el vector de posiciones [0,1,3,4], esta función devuelve el vector [1,2,1,2]. - Para un vector de datos [1,2,2,3,4], donde la función \ref PosRepeEnVector devuelve el vector de posiciones [0,1,3,4], esta función devuelve el vector [1,2,1,1]. - Para un vector de datos [1,1,1,1,1], donde la función \ref PosRepeEnVector devuelve el vector de posiciones [0], esta función devuelve el vector [5]. - Para un vector de datos [1], donde la función \ref PosRepeEnVector devuelve el vector de posiciones [0], esta función devuelve el vector [1]. \param[in] pos Vector de posiciones devuelto por la función \ref PosRepeEnVector. \param[in] nPos Número de elementos de \em pos. No puede ser 0. \param[in] nElemVecOrig Número de elementos del vector de datos original. \return Vector, de \em nPos elementos, que almacena el número de elementos repetidos a partir de cada posición (incluida ésta) almacenada en el vector \em pos. Si ocurre un error de asignación de memoria se devuelve \p NULL. \note Esta función no comprueba internamente el vector pasado contiene suficiente memoria. \note Esta función no comprueba internamente si las dimensiones del vector pasado son congruentes con el espacio almacenado en memoria. \note Esta función no comprueba internamente si el argumento \em nPos es igual a 0. \date 02 de febrero de 2011: Creación de la función. */ size_t* NumElemRepeEnVector(const size_t* pos, const size_t nPos, const size_t nElemVecOrig); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica un factor de escala y una traslación (en este orden) a los elementos de un vector. \param[in,out] vector Vector de datos. Al término de la ejecución de la función, se ha aplicado un factor de escala y una traslación (en este orden) a los elementos del vector. \param[in] nElem Número de elementos de \em vector. \param[in] inc Posiciones de separación entre los elementos del vector \em vector. Este argumento siempre ha de ser un número positivo. \param[in] escala Factor de escala a aplicar. \param[in] traslada Traslación a aplicar. \note Primero se aplica el factor de escala y luego la traslación. \note Esta función asume que el vector de entrada \em vector tiene memoria asignada. \date 18 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void EscalaYTrasladaVector(double* vector, const size_t nElem, const size_t inc, const double escala, const double traslada); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica una traslación y un factor de escala (en este orden) a los elementos de un vector. \param[in,out] vector Vector de datos. Al término de la ejecución de la función, se ha aplicado una traslación y un factor de escala (en este orden) a los elementos del vector. \param[in] nElem Número de elementos de \em vector. \param[in] inc Posiciones de separación entre los elementos del vector \em vector. Este argumento siempre ha de ser un número positivo. \param[in] escala Factor de escala a aplicar. \param[in] traslada Traslación a aplicar. \note Primero se aplica la traslación y luego el factor de escala. \note Esta función asume que el vector de entrada \em vector tiene memoria asignada. \date 18 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void TrasladaYEscalaVector(double* vector, const size_t nElem, const size_t inc, const double escala, const double traslada); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/polil.h0000755000175000017500000012532212032305135017371 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file polil.h \brief Definición de estructuras y declaración de funciones para el trabajo con polilíneas. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 03 de junio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _POLIL_H_ #define _POLIL_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include"libgeoc/dpeucker.h" #include"libgeoc/errores.h" #include"libgeoc/fgeneral.h" #include"libgeoc/geocnan.h" #include"libgeoc/geocomp.h" #include"libgeoc/polig.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \struct polil \brief Estructura contenedora de los vértices que definen el contorno de una o varias polilíneas. \date 03 de junio de 2011: Creación de la estructura. */ typedef struct { /** \brief Número de elementos de los vectores de coordenadas. */ size_t nElem; /** \brief Vector de polil::nElem elementos, que almacena las coordenadas X de los vértices de la polilínea (o las polilíneas), así como los separadores entre polilíneas. La primera coordenada de cada polilínea se repite al final. */ double* x; /** \brief Vector de polil::nElem elementos, que almacena las coordenadas Y de los vértices de la polilínea (o las polilíneas), así como los separadores entre polilíneas. La primera coordenada de cada polilínea se repite al final. */ double* y; /** \brief Número de polilíneas almacenadas. */ size_t nPolil; /** \brief Vector de polil::nPolig elementos, que almacena las posiciones en los vectores \em x e \em y de inicio de cada polilínea almacenada. */ size_t* posIni; /** \brief Vector de polil::nPolig elementos, que almacena el número de vértices de cada polilínea almacenada. */ size_t* nVert; /** \brief Identificador de si la estructura contiene información acerca de los límites del rectángulo que encierra a cada polilínea almacenada. Dos posibilidades: - 0: La estructura no contiene información de los límites. - Distinto de 0: La estructura sí contiene información de los límites. */ int hayLim; /** \brief Vector de polil::nPolig elementos, que almacena la coordenada X mínima de cada polilínea almacenada. Este campo sólo contiene información si el campo polil::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* xMin; /** \brief Vector de polil::nPolig elementos, que almacena la coordenada X máxima de cada polilínea almacenada. Este campo sólo contiene información si el campo polil::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* xMax; /** \brief Vector de polil::nPolig elementos, que almacena la coordenada Y mínima de cada polilínea almacenada. Este campo sólo contiene información si el campo polil::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* yMin; /** \brief Vector de polil::nPolig elementos, que almacena la coordenada Y máxima de cada polilínea almacenada. Este campo sólo contiene información si el campo polil::hayLim es distinto de 0; si no, es igual a \p NULL. */ double* yMax; }polil; /******************************************************************************/ /******************************************************************************/ /** \brief Indica si hay alguna función compilada en paralelo con OpenMP en el fichero \ref polil.c. \param[out] version Cadena identificadora de la versión de OpenMP utilizada. Este argumento sólo se utiliza si su valor de entrada es distinto de \p NULL y si hay alguna función compilada con OpenMP. \return Dos posibles valores: - 0: No hay ninguna función compilada en paralelo con OpenMP. - Distinto de 0: Sí hay alguna función compilada en paralelo con OpenMP. \note Esta función asume que el argumento \em version tiene suficiente memoria asignada (si es distinto de \p NULL). \date 03 de junio de 2011: Creación de la función. \date 25 de agosto de 2011: Adición del argumento de entrada \em version. */ int GeocParOmpPolil(char version[]); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una estructura \ref polil vacía. \return Estructura \ref polil vacía. Los campos escalares se inicializan con el valor 0 y los vectoriales con \p NULL. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \date 26 de mayo de 2011: Creación de la función. \note Esta función todavía no está probada. */ polil* IniciaPolilVacia(void); /******************************************************************************/ /******************************************************************************/ /** \brief Función auxiliar para la rutina de creación de una estructura \ref polil a partir de dos vectores que contienen las coordenadas de los vértices. Esta función calcula el número máximo de elementos que almacenarán los vectores de coordenadas de una estructura \ref polil y el número de polilíneas almacenadas en los vectores de trabajo. \param[in] nElem Número de elementos de los vectores de coordenadas originales. \param[in] posNanX Vector que almacena las posiciones de los elementos #GEOC_NAN en el vector \em x de coordenadas originales. \param[in] posNanY Vector que almacena las posiciones de los elementos #GEOC_NAN en el vector \em y de coordenadas originales. \param[in] nNanX Número de elementos del vector \em posNanX. \param[in] nNanY Número de elementos del vector \em posNanY. \param[out] nElemMax Número máximo de elementos que contendrán los vectores de coordenadas de los elementos de la estructura. \param[out] nPolil Número de polilíneas almacenadas en los vectores \em x e \em y de coordenadas originales. \return Variable de error. Tres posibilidades: - #GEOC_ERR_NO_ERROR: Si todo ha ido bien. - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Si los vectores \em x e \em y de coordenadas originales almacenan un número distinto de polilíneas, es decir, \em nNanX es distinto que \em nNanY. - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Si algunas polilíneas almacenadas en \em x e \em y son distintas, es decir, las posiciones almacenadas en \em posNanX son distintas de las almacenadas en \em posNanY. \note Esta función no comprueba si el número de elementos de los vectores \em posNanX y \em posNanY es congruente con los valores pasados en \em nNanX y \em nNanY. \date 03 de junio de 2011: Creación de la función. \date 13 de junio de 2011: Corrección de error que hacía que el argumento \em nElemMax que calculase mal si los argumentos \em nNanX y/o \em nNanY valían 0. \note Esta función todavía no está probada. */ int AuxCreaPolil1(const size_t nElem, const size_t* posNanX, const size_t* posNanY, const size_t nNanX, const size_t nNanY, size_t* nElemMax, size_t* nPolil); /******************************************************************************/ /******************************************************************************/ /** \brief Función auxiliar para la rutina de creación de una estructura \ref polil a partir de dos vectores que contienen las coordenadas de los vértices. Esta función copia una serie de datos de dos vectores en otros dos. \param[in] x Vector que contiene las coordenadas X de los vértices a copiar. \param[in] y Vector que contiene las coordenadas Y de los vértices a copiar. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[out] xSal Vector de \em nElem elementos para almacenar los elementos copiados del vector \em x. \param[out] ySal Vector de \em nElem elementos para almacenar los elementos copiados del vector \em y. \note Esta función no comprueba si el número de elementos de los vectores \em x, \em y, \em xSal e \em ySal es congruente con los valores pasados en \em nElem, \em incX e \em incY. \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void AuxCreaPolil2(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, double* xSal, double* ySal); /******************************************************************************/ /******************************************************************************/ /** \brief Función auxiliar para las rutinas de creación de estructuras \ref polil a partir de dos vectores que contienen las coordenadas de los vértices. Esta función crea las polilíneas en el formato de almacenamiento de \ref polil a partir de los vectores de entrada. \param[in] x Vector que contiene las coordenadas X de los vértices de trabajo. \param[in] y Vector que contiene las coordenadas Y de los vértices de trabajo. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[in] posNan Vector que almacena las posiciones de los elementos #GEOC_NAN en los vectores \em x e \em y. \param[in] nNan Número de elementos del vector \em posNan. \param[out] xSal Vector para almacenar las coordenadas X de los vértices de las polilíneas creadas. \param[out] ySal Vector para almacenar las coordenadas Y de los vértices de las polilíneas creadas. \param[out] posIni Vector para almacenar las posiciones de inicio de las polilíneas creadas. \param[out] nVert Vector para almacenar el número de vértices de las polilíneas creadas. \param[out] nPtos Número de posiciones con información almacenada en los vectores \em xSal e \em ySal. \param[out] nPolil Número de posiciones con información almacenada en los vectores \em posIni y \em nVert. \note Esta función no comprueba si el número de elementos de los vectores \em x, \em y y \em posNan es congruente con los valores pasados en \em nElem, \em incX, \em incY y \em nNan. \note Esta función asume que los vectores \em xSal, \em ySal, \em posIni y \em nVert tienen asignada suficiente memoria. \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void AuxCreaPolil3(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, const size_t* posNan, const size_t nNan, double* xSal, double* ySal, size_t* posIni, size_t* nVert, size_t* nPtos, size_t* nPolil); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una estructura \ref polil a partir de dos vectores que contienen las coordenadas de los vértices de una o varias polilíneas. \param[in] x Vector que contiene las coordenadas X de los vértices de la polilínea o polilíneas de trabajo. Si hay varias polilíneas, han de estar separados por un valor #GEOC_NAN. \param[in] y Vector que contiene las coordenadas Y de los vértices de la polilínea o polilíneas de trabajo. Si hay varias polilíneas, han de estar separados por un valor #GEOC_NAN. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \param[out] idError Identificador de error. Varias posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Los vectores \em x e \em y contienen un número distinto de polilíneas. No contienen el mismo número de identificadores #GEOC_NAN. - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Los vectores \em x e \em y contienen distintas polilíneas. Los marcadores #GEOC_NAN no están colocados en las mismas posiciones. \return Estructura \ref polil con las polilíneas pasadas. Si ocurre algún error, se devuelve \p NULL y el motivo del fallo se codifica en la variable \em idError. \note Esta función está paralelizada con OpenMP. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados de \em nElem, \em incX e \em incY. \note Si los vectores \em x e \em y almacenan varias polilíneas, éstas se separan mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición y/o la última es opcional. \note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en \em x e \em y. \note Esta función no calcula los límites de las polilíneas, por lo que el campo polil::hayLim se inicializa a 0 y los campos polil::xMin, polil::xMax, polil::yMin y polil::yMax se inicializan a \p NULL. \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ polil* CreaPolil(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, int* idError); /******************************************************************************/ /******************************************************************************/ /** \brief Enlaza el contenido de una estructura \ref polil a otra. \param[in] poliEnt Estructura \ref polil de entrada, que almacena los datos a enlazar. \param[out] poliSal Estructura \ref polil, cuyos campos serán enlazados a los de la estructura \em poliEnt. Esta estructura ha de estar, como mínimo, inicializada. Al término de la ejecución de la función, las estructuras \em poliEnt y \em poliSal comparten el mismo espacio de memoria en sus argumentos vectoriales. \note Esta función asume que la estructura de entrada \em poligEnt tiene memoria asignada. \note Esta función asume que la estructura de salida \em poligSal está, como mínimo, inicializada. \note Esta función libera la posible memoria asignada a los campos de \em poliSal antes de realizar el enlace. \date 19 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void EnlazaCamposPolil(polil* poliEnt, polil* poliSal); /******************************************************************************/ /******************************************************************************/ /** \brief Copia el contenido de una estructura \ref polil en otra. \param[in] poli Estructura \ref polil de entrada, que almacena los datos a copiar. \param[out] idError Identificador de error. Varias posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Los campos polil::x e polil::y de la polilínea de entrada contienenun número distinto de polilíneas. No contienen el mismo número de identificadores #GEOC_NAN. - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Los campos polig::x e polig::y de la polilínea de entrada contienen distintas polilíneas. Los marcadores #GEOC_NAN no están colocados en las mismas posiciones. \return Polilínea con los datos contenidos en \em poli copiados. Si ocurre algún error se devuelve \p NULL y la causa se almacena en el argumento \em idError. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \date 09 de julio de 2011: Creación de la función. \note Esta función todavía no está probada. */ polil* CopiaPolil(const polil* poli, int* idError); /******************************************************************************/ /******************************************************************************/ /** \brief Añade el contenido de una estructura \ref polil a otra. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, se han añadido las polilíneas de la estructura \em anyade. \param[in] anyade Estructura cuyo contenido será añadido a \em poli. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función asume que la estructura de entrada \ref polil tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de las estructuras de entrada no se libera. \note Si la estructura \em poli guarda información de límites de las polilíneas almacenadas, esta información se calcula también para los nuevos datos (en realidad, si la estructura \em anyade ya los tiene calculados, simplemente se copian). \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ int AnyadePolilPolil(polil* poli, const polil* anyade); /******************************************************************************/ /******************************************************************************/ /** \brief Añade al contenido de una estructura \ref polil un conjunto de polilíneas definidas a partir de un listado con las coordenadas de sus vértices, de la misma forma que el utilizado en la función \ref CreaPolil. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, se han añadido las polilíneas pasados en \em x e \em y. \param[in] x Vector que contiene las coordenadas X de los vértices de la polilínea o polilíneas a añadir. Si hay varias polilíneas, han de estar separadas por un valor #GEOC_NAN. \param[in] y Vector que contiene las coordenadas Y de los vértices de la polilínea o polilíneas a añadir. Si hay varias polilíneas, han de estar separadas por un valor #GEOC_NAN. \param[in] nElem Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. - #GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL: Los vectores \em x e \em y contienen un número distinto de polilíneas. No contienen el mismo número de identificadores #GEOC_NAN. - #GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL: Los vectores \em x e \em y contienen distintas polilíneas. Los marcadores #GEOC_NAN no están colocados en las mismas posiciones. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de la estructura y los vectores de entrada no se libera. \note Si la estructura \em poli guarda información de límites de las polilíneas almacenadas, esta información se calcula también para los nuevos datos. \note Esta función no comprueba si el número de elementos de los vectores \em x e \em y es congruente con los valores pasados de \em nElem, \em incX e \em incY. \note Si los vectores \em x e \em y almacenan varias polilíneas, éstas se separan mediante valores #GEOC_NAN. Poner #GEOC_NAN en la primera posición y/o la última es opcional. \note Los posibles valores #GEOC_NAN han de estar en las mismas posiciones en \em x e \em y. \note Esta función crea internamente una estructura \ref polil para luego añadirla a \em poli con la función \ref AnyadePolilPolil. \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ int AnyadeDatosPolil(polil* poli, const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY); /******************************************************************************/ /******************************************************************************/ /** \brief Libera la memoria asignada a una estructura \ref polil. \param[in] datos Estructura \ref polil. \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void LibMemPolil(polil* datos); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula los límites de todas las polilíneas almacenados en una estructura \ref polil. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, se han añadido los límites de las polilíneas almacenadas. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función está paralelizada con OpenMP. \note Esta función asume que la estructura de entrada \ref polil tiene memoria asignada. \note En caso de error de asignación de memoria, la memoria de la estructura de entrada no se libera. \date 03 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ int CalcLimitesPolil(polil* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica un factor de escala y una traslación (en este orden) a las coordenadas de todas las polilíneas almacenadas en una estructura \ref polil. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, se ha aplicado un factor de escala y una traslación (en este orden) a las coordenadas de todas las polilíneas almacenadas y, si se indica, a los límites. \param[in] escalaX Factor de escala a aplicar a las coordenadas X. \param[in] escalaY Factor de escala a aplicar a las coordenadas Y. \param[in] trasladaX Traslación a aplicar a las coordenadas X. \param[in] trasladaY Traslación a aplicar a las coordenadas Y. \param[in] aplicaLim Identificador para aplicar o no los factores de escala y las traslaciones a los límites de las polilíneas (sólo si están previemente calculados). Dos posibilidades: - 0: No se aplican los factores de escala ni las traslaciones a los límites. - Distinto de 0: Sí se aplican los factores de escala y las traslaciones a los límites, si estos están calculados en la estructura de entrada. \note Esta función está paralelizada con OpenMP. \note Primero se aplican los factores de escala y luego las traslaciones. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \date 03 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Distinción entre factores de escala y traslaciones para las coordenadas X e Y. \note Esta función todavía no está probada. */ void EscalaYTrasladaPolil(polil* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica una traslación y un factor de escala (en este orden) a las coordenadas de todas las polilíneas almacenadss en una estructura \ref polil. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, se ha aplicado una traslación y un factor de escala (en este orden) a las coordenadas de todas las polilíneas almacenadas y, si se indica, a los límites. \param[in] escalaX Factor de escala a aplicar a las coordenadas X. \param[in] escalaY Factor de escala a aplicar a las coordenadas Y. \param[in] trasladaX Traslación a aplicar a las coordenadas X. \param[in] trasladaY Traslación a aplicar a las coordenadas Y. \param[in] aplicaLim Identificador para aplicar o no las traslaciones y los factores de escala a los límites de las polilíneas (sólo si están previemente calculados). Dos posibilidades: - 0: No se aplican las traslaciones ni los factores de escala a los límites. - Distinto de 0: Sí se aplican las traslaciones y los factores de escala a los límites, si estos están calculados en la estructura de entrada. \note Esta función está paralelizada con OpenMP. \note Primero se aplican las traslaciones y luego los factores de escala. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \date 03 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Distinción entre factores de escala y traslaciones para las coordenadas X e Y. \note Esta función todavía no está probada. */ void TrasladaYEscalaPolil(polil* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim); /******************************************************************************/ /******************************************************************************/ /** \brief Aplica un factor de escala y una traslación (el orden de aplicación se ha de seleccionar) a las coordenadas de todas las polilíneas almacenadas en una estructura \ref polil. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, se ha aplicado un factor de escala y una traslación (orden a seleccionar) a las coordenadas de todas las polilíneas almacenadas y, si se indica, a los límites. \param[in] escalaX Factor de escala a aplicar a las coordenadas X. \param[in] escalaY Factor de escala a aplicar a las coordenadas Y. \param[in] trasladaX Traslación a aplicar a las coordenadas X. \param[in] trasladaY Traslación a aplicar a las coordenadas Y. \param[in] orden Orden de aplicación de los factores de escala y traslación. Dos posibilidades: - 0: Primero se aplican los factores de escala y luego las traslaciones \f$x'=f\cdot x+t\f$. - Distinto de 0: Primero se aplican las traslaciones y luego los factores de escala \f$x'=(x+t)\cdot f\f$. \param[in] aplicaLim Identificador para aplicar o no los factores de escala y las traslaciones a los límites de las polilíneas (sólo si están previemente calculados). Dos posibilidades: - 0: No se aplican los factores de escala ni las traslaciones a los límites. - Distinto de 0: Sí se aplican los factores de escala y las traslaciones a los límites, si estos están calculados en la estructura de entrada. \note Esta función asume que la estructura de entrada \em poli tiene memoria asignada. \date 03 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Distinción entre factores de escala y traslaciones para las coordenadas X e Y. \note Esta función todavía no está probada. */ void MuevePolil(polil* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int orden, const int aplicaLim); /******************************************************************************/ /******************************************************************************/ /** \brief Elimina vértices de las polilíneas almacenadas en una estructura \ref polil mediante un algoritmo inspirado en el de Douglas-Peucker. Se usa internamente la función \ref AligeraPolilinea. \param[in,out] poli Estructura \ref polil, que almacena una serie de polilíneas. Al término de la ejecución de la función, almacena el resultado de la aplicación a cada polilínea del algoritmo de aligerado de vértices implementado en la función \ref AligeraPolilinea. \param[in] tol Tolerancia para eliminar vértices, en las mismas unidades que las coordenadas de los vértices. Ver la ayuda de la función \ref AligeraPolilinea. \param[in] robusto Identificador para realizar o no un aligerado robusto. Ha de ser un elemento del tipo enumerado #GEOC_DPEUCKER_ROBUSTO. Varias posibilidades: - #GeocDPeuckerRobNo: No se aplica el algoritmo robusto. - #GeocDPeuckerRobSi: Se aplica el algoritmo robusto completo, que garantiza la no ocurrencia de auto intersecciones en la polilínea resultante. Internamente, primero se aplica el tratamiento robusto de la opción #GeocDPeuckerRobOrig y luego el de la opción #GeocDPeuckerRobAuto. - #GeocDPeuckerRobOrig: Se aplica un algoritmo semi robusto que consiste en garantizar que los segmentos de la polilínea aligerada que se van creando no intersectarán con ninguno de los segmentos que forman los vértices que quedan por procesar de la polilínea original. En casos muy especiales, este algoritmo puede seguir dando lugar a auto intersecciones. - #GeocDPeuckerRobAuto: Se aplica un algoritmo semi robusto que consiste en garantizar que los segmentos de la polilínea aligerada que se van creando no intersectarán con ninguno de los segmentos de la polilínea aligerada creados con anterioridad. En casos muy especiales, este algoritmo puede seguir dando lugar a auto intersecciones. \param[in] nPtosRobusto Número de puntos de la polilínea original a utilizar en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o #GeocDPeuckerRobOrig. Si se pasa el valor 0, se utilizan todos los puntos hasta el final de la polilínea original. \param[in] nSegRobusto Número de segmentos de la polilínea aligerada a utilizar en el caso de tratamiento robusto con las opciones #GeocDPeuckerRobSi o #GeocDPeuckerRobAuto. Si se pasa el valor 0, se utilizan todos los segmentos hasta el inicio de la polilínea aligerada. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función asume que \em poli está, como mínimo, inicializada. \note Si \em poli tiene límites calculados en la entrada, también los tendrá en la salida. \note Una polilínea aligerada sólo será válida si después de aplicarle la función \ref AligeraPolilinea mantiene un mínimo de 2 puntos que no sean el mismo (esto sólo puede ocurrir si se pasa un polígono -los vértices de inicio y final coinciden- y sólo quedan al final los extremos). Al término de la ejecución de esta función, el resultado puede ser una estructura \ref polil vacía. \date 09 de julio de 2011: Creación de la función. \date 10 de julio de 2011: Cambio del tipo del argumento \em robusto al tipo enumerado #GEOC_DPEUCKER_ROBUSTO. \date 31 de julio de 2011: Corregido error con índices a la hora de guardar los resultados y modificación para no tomar como válidas las polilíneas que se quedan en sólo dos vértices que sean el mismo. \todo Esta función todavía no está probada. */ int AligeraPolil(polil* poli, const double tol, const enum GEOC_DPEUCKER_ROBUSTO robusto, const size_t nPtosRobusto, const size_t nSegRobusto); /******************************************************************************/ /******************************************************************************/ /** \brief Imprime una línea de cabecera para una polilínea almacenada en una estructura \ref polil. \param[in] poli Estructura \ref polil. \param[in] indice Índice de la polilínea de trabajo en la estructura. \param[in] iniCab Cadena de texto con la que comenzará la cabecera. \param[in] impLim Identificador para imprimir o no los límites de coordenadas de la polilínea de trabajo. Dos posibles valores: - 0: No se imprimen. - Distinto de 0: Sí se imprimen. \param[in] formCoor Cadena de carácteres indicadora del formato para escribir las coordenadas de los límites. Este argumento sólo se usa internamente si se ha indicado la impresión de límites. \param[in] factorX Factor para multiplicar las coordenadas X de los vértices antes de imprimirlas. \param[in] factorY Factor para multiplicar las coordenadas Y de los vértices antes de imprimirlas. \param[in] idFich Identificador de fichero abierto para escribir. \note Esta función está paralelizada con OpenMP. \note La cabecera completa tiene el siguiente formato: iniCab númVert xMín xMáx yMín yMáx. \note Si la estructura no tiene información de límites y se indica que se impriman, los valores se calculan internamente. \note Esta función asume que \em poli es una estructura \ref polil correctamente almacenada. \note Esta función no comprueba si la estructura pasada tiene memoria asignada. \note Esta función no comprueba internamente la validez de los argumentos de formato. \note Esta función no comprueba internamente si el identificador pasado corresponde a un fichero abierto para escribir. \date 18 de junio de 2011: Creación de la función. \note Esta función todavía no está probada. */ void ImprimeCabeceraPolilFichero(const polil* poli, const size_t indice, const char iniCab[], const int impLim, const char formCoor[], const double factorX, const double factorY, FILE* idFich); /******************************************************************************/ /******************************************************************************/ /** \brief Imprime una estructura \ref polil en un fichero. \param[in] poli Estructura \ref polil. \param[in] factorX Factor para multiplicar las coordenadas X de los vértices antes de imprimirlas. \param[in] factorY Factor para multiplicar las coordenadas Y de los vértices antes de imprimirlas. \param[in] iniNan Identificador para imprimir o no la marca de separación de polilíneas (\p NaN) delante de la primera polilínea. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] finNan Identificador para imprimir o no la marca de separación de polilíneas (\p NaN) delante de la última polilínea. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] formCoor Cadena de carácteres indicadora del formato de cada coordenada a imprimir. \param[in] impCabecera Identificador para imprimir o no una cabecera con información general por cada polilínea. Dos posibles valores: - 0: No se imprime. - Distinto de 0: Sí se imprime. \param[in] iniCab Cadena de texto con la que comenzará la cabecera. \param[in] impLim Identificador para imprimir o no en la cabecera los límites de coordenadas de las polilíneas de trabajo. Dos posibles valores: - 0: No se imprimen. - Distinto de 0: Sí se imprimen. \param[in] idFich Identificador de fichero abierto para escribir. \note La cabecera completa tiene el siguiente formato: iniCab númVert xMín xMáx yMín yMáx. \note Si la estructura no tiene información de límites y se indica que se impriman, los valores se calculan internamente. \note Esta función asume que \em poli es una estructura \ref polil correctamente almacenada. \note Esta función no comprueba si la estructura pasada tiene memoria asignada. \note Esta función no comprueba internamente la validez de los argumentos de formato. \note Esta función no comprueba internamente si el identificador pasado corresponde a un fichero abierto para escribir. \date 03 de junio de 2011: Creación de la función. \date 18 de junio de 2011: Adición de la capacidad de escritura de una cabecera y del uso de factores de escala independientes para las coordenadas X e Y. \date 22 de septiembre de 2011: Corregido bug que hacía que, dependiendo del compilador y/o los flags de optimización en la compilación, se imprimiesen mal (con un signo menos delante) los valores Not-a-Number. \note Esta función todavía no está probada. */ void ImprimePolilFichero(const polil* poli, const double factorX, const double factorY, const int iniNan, const int finNan, const char formCoor[], const int impCabecera, const char iniCab[], const int impLim, FILE* idFich); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/ventorno.h0000644000175000017500000001174612032305135020125 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup anespec general @{ \file ventorno.h \brief Definición de variables de entorno y declaración de funciones para su control. \author José Luis García Pallero, jgpallero@gmail.com \date 31 de marzo de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _VENTORNO_H_ #define _VENTORNO_H_ /******************************************************************************/ /******************************************************************************/ #include #include /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ENV_NOM_VAR_PILOMBS \brief Nombre de la variable de entorno para imprimir o no pasos intermedios en la ejecución de la función \ref AnalisisLombSig. \date 31 de marzo de 2011: Creación de la constante. */ #define GEOC_ENV_NOM_VAR_PILOMBS "GEOC_ENV_PILOMBS" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ENV_VAL_REF_PILOMBS \brief Valor de referencia de la variable de entorno #GEOC_ENV_NOM_VAR_PILOMBS. \date 31 de marzo de 2011: Creación de la constante. */ #define GEOC_ENV_VAL_REF_PILOMBS "0" /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si una variable de entorno está definida y es igual a un valor. \param[in] var Nombre de la variable de entorno a comprobar. \param[in] valRef Valor de referencia de la variable de entorno. \return Tres posibilidades: - Menor que 0: La variable de entorno no está definida. - 0: La variable de entorno existe, pero tiene un valor distinto a \em valRef. - Mayor que 0: La variable de entorno existe y tiene el mismo valor que \em valRef. \date 31 de marzo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ int VarEnvValRef(const char* var, const char* valRef); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/greiner.h0000644000175000017500000013012412032305135017676 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file greiner.h \brief Definición de estructuras y declaración de funciones para el recorte de polígonos mediante el algoritmo de Greiner-Hormann (http://davis.wpi.edu/~matt/courses/clipping/). \author José Luis García Pallero, jgpallero@gmail.com \date 14 de mayo de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _GREINER_H_ #define _GREINER_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include #include #include"libgeoc/errores.h" #include"libgeoc/eucli.h" #include"libgeoc/geocnan.h" #include"libgeoc/polig.h" #include"libgeoc/ptopol.h" #include"libgeoc/segmento.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_GREINER_FAC_EPS_PERTURB \brief Factor de escala para el cálculo de la cantidad mínima de perturbación para un valor. Esta variable se usa en la función \ref CantPerturbMin. A base de hacer pruebas he visto que es desaconsejable un valor por debajo de 10.0. \date 22 de mayo de 2011: Creación de la constante. */ #define GEOC_GREINER_FAC_EPS_PERTURB 10.0 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_GREINER_BUFFER_PTOS \brief Número de puntos para ir asignando memoria en bloques para los polígonos de salida en la funcion \ref Paso3Greiner. Ha de ser un número mayor o igual a 2. \date 23 de mayo de 2011: Creación de la constante. */ #define GEOC_GREINER_BUFFER_PTOS 100 /******************************************************************************/ /******************************************************************************/ /** \enum GEOC_OP_BOOL_POLIG \brief Operación booleana entre polígonos. \date 21 de mayo de 2011: Creación del tipo. */ enum GEOC_OP_BOOL_POLIG { /** \brief Intersección entre polígonos. */ GeocOpBoolInter=111, /** \brief Unión de polígonos. */ GeocOpBoolUnion=112, /** \brief Unión exclusiva de polígonos. */ GeocOpBoolXor=113, /** \brief Operación A-B. */ GeocOpBoolAB=114, /** \brief Operación B-A. */ GeocOpBoolBA=115 }; /******************************************************************************/ /******************************************************************************/ /** \struct _vertPoliClip \brief Estructura de definición de un vértice de un polígono usado en operaciones de recorte. El polígono se almacena en memoria como una lista doblemente enlazada de vértices. \date 14 de mayo de 2011: Creación de la estructura. */ typedef struct _vertPoliClip { /** \brief Coordenada X del vértice. */ double x; /** \brief Coordenada Y del vértice. */ double y; /** \brief Coordenada X perturbada del vértice. */ double xP; /** \brief Coordenada Y perturbada del vértice. */ double yP; /** \brief Vértice anterior. */ struct _vertPoliClip* anterior; /** \brief Vértice siguiente. */ struct _vertPoliClip* siguiente; /** \brief Enlace al mismo nodo, perteneciente a otro polígono. Los puntos de intersección pertenecen tanto al polígono de recorte como al recortado. */ struct _vertPoliClip* vecino; /** \brief Indicador de primer punto de polígono. Dos posibilidades: - 0: No es el primer punto del polígono. - Distinto de 0: Sí es el primer punto del polígono. */ char ini; /** \brief Indicador de punto de intersección. Dos posibilidades: - 0: No es un punto de intersección. - Distinto de 0: Sí es un punto de intersección. */ char interseccion; /** \brief Indicador de punto de entrada al interior del otro polígono. Dos posibilidades: - 0: No es un punto de entrada, es de salida. - Distinto de 0: Sí es un punto de entrada. */ char entrada; /** \brief Indicador de punto visitado. Dos posibilidades: - 0: No ha sido visitado. - Distinto de 0: Sí ha sido visitado. */ char visitado; /** \brief Distancia, en tanto por uno, de un nodo de intersección con respecto al primer vértice del segmento que lo contiene. */ double alfa; }vertPoliClip; /******************************************************************************/ /******************************************************************************/ /** \brief Crea un vértice de tipo \ref _vertPoliClip y lo inserta entre otros dos. \param[in] x Coordenada X del vértice. \param[in] y Coordenada Y del vértice. \param[in] anterior Vértice anterior (puede ser \p NULL). \param[in] siguiente Vértice siguiente (puede ser \p NULL). \param[in] vecino Campo _vertPoliClip::vecino (puede ser \p NULL). \param[in] ini Campo _vertPoliClip::ini. \param[in] interseccion Campo _vertPoliClip::interseccion. \param[in] entrada Campo _vertPoliClip::entrada. \param[in] visitado Campo _vertPoliClip::visitado. \param[in] alfa Campo _vertPoliClip::alfa. \return Puntero al nuevo vértice creado. Si se devuelve \p NULL, ha ocurrido un error de asignación de memoria. \date 18 de mayo de 2011: Creación de la función. \date 21 de mayo de 2011: Eliminación del algumento \em siguientePoli y adición del argumento \em ini. \todo Esta función todavía no está probada. */ vertPoliClip* CreaVertPoliClip(const double x, const double y, vertPoliClip* anterior, vertPoliClip* siguiente, vertPoliClip* vecino, const char ini, const char interseccion, const char entrada, const char visitado, const double alfa); /******************************************************************************/ /******************************************************************************/ /** \brief Crea un polígono, como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] x Vector de coordenadas X de los nodos del polígono. \param[in] y Vector de coordenadas Y de los nodos del polígono. \param[in] nCoor Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \return Puntero al primer vértice de la lista. Si se devuelve \p NULL, ha ocurrido un error de asignación de memoria. \note Esta función asume que el argumento \em nCoor es mayor que 0. \note En la lista de salida que representa al polígono, el primer vértice siempre se repite al final. Si en los vectores \em x e \em y el último elemento no es igual que el primero, igualmente se crea en la lista de salida. \note Si en los vectores de coordenadas \em x e \em y hay valores #GEOC_NAN, éstos no se tienen en cuenta a la hora de la creación de la estructura de salida. \note Que los vectores de coordenadas \em x e \em y admitan vértices con coordenadas (#GEOC_NAN,#GEOC_NAN) no quiere decir que éstos sean separadores de múltiples polígonos. \em x e \em y \b *SÓLO* deben almacenar un único polígono. \date 18 de mayo de 2011: Creación de la función. \date 24 de mayo de 2011: Adición del soporte de coordenadas (#GEOC_NAN,#GEOC_NAN) en los vectores de entrada. \todo Esta función todavía no está probada. */ vertPoliClip* CreaPoliClip(const double* x, const double* y, const size_t nCoor, const size_t incX, const size_t incY); /******************************************************************************/ /******************************************************************************/ /** \brief Libera la memoria asignada a un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] poli Puntero al primer elemento del polígono. \note Esta función no comprueba si hay vértices del polígono anteriores al vértice de entrada, por lo que si se quiere liberar toda la memoria asignada a un polígono, el vértice pasado ha de ser el primero de la lista. \note Esta función \b *NO* trabaja con listas circulares. \date 18 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void LibMemPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Elimina los vértices no originales de un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] poli Puntero al primer elemento del polígono. \return Puntero al primer elemento del polígono original. Si se devuelve \p NULL, ninguno de los vértices pertenecía al polígono original. \note Esta función asume que el primero y el último vértices originales del polígono pasado tienen las mismas coordenadas. \note Los vértices eliminados por esta función son todos aquéllos cuyo campo _vertPoliClip::interseccion sea distinto de 0. \note Aunque se supone que el primer vértice de un polígono siempre es un vértice original, si no lo es, la variable de entrada queda modificada. Por tanto, siempre es recomendable capturar la variable de salida, que garantiza la posición del primer elemento. \note Las coordenadas de todos los vértices originales vuelven a ser la de inicio, es decir, los campos _vertPoliClip::xP e _vertPoliClip::yP se sobreescriben con los valores almacenados en _vertPoliClip::x e _vertPoliClip::y. \note Esta función \b *NO* trabaja con listas circulares. \date 18 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPoliClip* ReiniciaPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Reinicia los vértices de un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip para poder volver a calcular otra operación booleana sin tener que recalcular las intersecciones. Esta función devuelve todos los campos _vertPoliClip::visitado a 0 y los campos _vertPoliClip::entrada a 0. \param[in] poli Puntero al primer elemento del polígono. \return Puntero al primer elemento del polígono original. Si se devuelve \p NULL, quiere decir qie el argumento de entrada valía \p NULL. \note Esta función \b *NO* trabaja con listas circulares. \date 30 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPoliClip* ReiniciaVerticesPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el siguiente vértice original en un polígono. \param[in] vert Puntero al vértice a partir del cual se ha de buscar. \return Puntero al siguiente vértice original en el polígono. Si se devuelve \p NULL, se ha llegado al final. \note Esta función asume que el primero y el último vértices originales del polígono pasado tienen las mismas coordenadas. \note Los vértices no originales son todos aquéllos cuyo campo _vertPoliClip::interseccion es distinto de 0. \note Esta función \b *NO* trabaja con listas circulares. \date 19 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPoliClip* SiguienteVertOrigPoliClip(vertPoliClip* vert); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el siguiente vértice que sea una intersección no visitada en un polígono. \param[in] vert Puntero al vértice a partir del cual se ha de buscar. \return Puntero al siguiente vértice que sea una intersección no visitada en el polígono. Si se devuelve \p NULL, se ha llegado al final. \note Esta función asume que el primero y el último vértices originales del polígono pasado tienen las mismas coordenadas. \note Los vértices intersección no visitados son todos aquéllos cuyo campo _vertPoliClip::visitado es 0. \note Esta función asume que el vértice inicial del polígono, aquél cuyo campo _vertPoliClip::ini vale 1, es un vértice original. \note Esta función puede trabajar con listas circulares y no circulares. \date 21 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPoliClip* SiguienteIntersecNoVisitadaPoliClip(vertPoliClip* vert); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el último vértice de un polígono almacenado como una lista doblemente enlazada de vértives \ref _vertPoliClip. \param[in] poli Puntero al primer elemento del polígono. \return Puntero al último vértice del polígono, que es aquél cuyo campo _vertPoliClip::siguiente apunta a \p NULL. Si se devuelve \p NULL, significa que el argumento pasado en \em poli vale \p NULL. \note Esta función \b *NO* trabaja con listas circulares. \date 21 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPoliClip* UltimoVertPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Inserta un vértice de tipo \ref _vertPoliClip entre otros dos, atendiendo al campo _vertPoliClip::alfa. \param[in] ins Vértice a insertar. \param[in] extremoIni Extremo inicial del segmento donde se insertará \em ins. \param[in] extremoFin Extremo final del segmento donde se insertará \em ins. \note Esta función asume que todos los elementos pasados tienen memoria asignada. \note Si entre \em extremoIni y \em extremoFin hay más vértices, \em ins se insertará de tal modo que los campos _vertPoliClip::alfa queden ordenados de menor a mayor. \note Si el campo _vertPoliClip::alfa de \em ins tiene el mismo valor que el de \em extremoIni, \em ins se insertará justo a continuación de \em extremoIni. \note Si el campo _vertPoliClip::alfa de \em ins tiene el mismo valor que el de \em extremoFin, \em ins se insertará justo antes de \em extremoIni. \note Esta función \b *NO* trabaja con listas circulares. \date 19 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void InsertaVertPoliClip(vertPoliClip* ins, vertPoliClip* extremoIni, vertPoliClip* extremoFin); /******************************************************************************/ /******************************************************************************/ /** \brief Convierte una lista doblemente enlazada de elementos \ref _vertPoliClip en una lista doblemente enlazada circular. \param[in,out] poli Vértice inicial del polígono, almacenado como lista doblemente enlazada, pero no cerrada. Al término de la ejecución de la función la lista se ha cerrado, por medio de un enlace del penúltimo elemento (el último es el primero repetido) con el primero. \return Puntero al último elemento del polígono original que, al ser el primer elemento repetido, queda almacenado en memoria pero no neferenciado por el polígono. Si el valor devuelto es \p NULL quiere decir que el argumento de entrada era \p NULL. \note Esta función \b *NO* trabaja con listas circulares. \date 21 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPoliClip* CierraPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Convierte una lista doblemente enlazada circular de elementos \ref _vertPoliClip en una lista doblemente enlazada simple. \param[in,out] poli Vértice inicial del polígono, almacenado como lista doblemente enlazada circular. Al término de la ejecución de la función la lista ha recuperado su condición de doblemente enlazada sin cerrar. \param[in] ultimo Puntero al último elemento de la lista doblemente enlazada original. Este argumento ha de ser el valor devuelto por la función \ref CierraPoliClip. \note Esta función asume que los elementos pasados tienen memoria asignada. \note Esta función sólo trabaja con listas circulares. \date 21 de mayo de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void AbrePoliClip(vertPoliClip* poli, vertPoliClip* ultimo); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en un polígono de un número arbitrario de lados. Esta función puede no dar resultados correctos para puntos en los bordes y/o los vértices del polígono. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] poli Polígono, almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Sólo se tienen en cuenta los vértices originales del polígono, que son todos aquéllos cuyo campo _vertPoliClip::interseccion es distinto de 0. \return Dos posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono. \note El código de esta función ha sido adaptado de la función \ref PtoEnPoligono. \note Esta función no comprueba si la variable \em poli es un polígono correctamente almacenado. \note Esta función no detecta el caso de que el punto de trabajo esté en el borde o en un vértice del polígono. En este caso, el test puede dar el punto dentro o fuera, indistintamente (el chequeo del mismo punto con el mismo polígono siempre dará el mismo resultado). \note Esta función \b *NO* trabaja con listas circulares. \date 19 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ int PtoEnPoliClip(const double x, const double y, vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Comprueba si un punto está contenido en un polígono de un número arbitrario de lados. Esta función puede no dar resultados correctos para puntos en los bordes del polígono. \param[in] x Coordenada X del punto de trabajo. \param[in] y Coordenada Y del punto de trabajo. \param[in] poli Polígono, almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Sólo se tienen en cuenta los vértices originales del polígono, que son todos aquéllos cuyo campo _vertPoliClip::interseccion es distinto de 0. \return Dos posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono. - #GEOC_PTO_VERTICE_POLIG: El punto es un vértice del polígono. \note El código de esta función ha sido adaptado de la función \ref PtoEnPoligonoVertice. \note Esta función no comprueba si la variable \em poli es un polígono correctamente almacenado. \note Esta función utiliza en uno de sus pasos la función \ref PtoEnPoliClip y se comporta igual que ella en el caso de puntos en el borde. \note Esta función \b *NO* trabaja con listas circulares. \date 19 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ int PtoEnPoliClipVertice(const double x, const double y, vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Cuenta el número de vértices originales que hay en un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] poli Polígono, almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Sólo se tienen en cuenta los vértices originales del polígono, que son todos aquéllos cuyo campo _vertPoliClip::interseccion es distinto de 0. \return Número de vértices originales almacenados. El último vértice, que es igual al primero, también se cuenta. \note Esta función no comprueba si la variable \em poli es un polígono correctamente almacenado. \note Esta función \b *NO* trabaja con listas circulares. \date 19 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ size_t NumeroVertOrigPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Cuenta el número total de vértices que hay en un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] poli Polígono, almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Se tienen en cuenta todos los vértices. \return Número total de vértices almacenados. El último vértice, que debe ser igual al primero, también se cuenta. \note Esta función no comprueba si la variable \em poli es un polígono correctamente almacenado. \note Esta función \b *NO* trabaja con listas circulares. \date 19 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ size_t NumeroVertPoliClip(vertPoliClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la cantidad mínima a añadir a un número para que el valor de la suma sea distinto del número original. \param[in] x Número a perturbar. \param[in] factor Factor para ir multiplicando el valor a añadir a \em x mientras no sea suficiente para producir una perturbación detectable. Un buen valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB. \return Cantidad mínima a añadir a \em x para que el valor de la suma sea distinto de \em x. \note Esta función no comprueba internamente si \em factor es menor o igual que 1, lo que daría lugar a que la función entrase en un bucle infinito. \note Como valor inicial de la cantidad a añadir se toma el producto de \em factor por la constante \p DBL_EPSILON, perteneciente al fichero \p float.h de C estándar. \date 22 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ double CantPerturbMin(const double x, const double factor); /******************************************************************************/ /******************************************************************************/ /** \brief Modifica un número la cantidad mínima para que sea distinto del número original. \param[in] x Número a perturbar. \param[in] factor Factor para el cálculo de la cantidad perturbadora mínima. Ver la documentación de la función \ref CantPerturbMin para obtener más detalles. Un buen valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB. \return Número perturbado. \note La perturbación de \em x se realiza de la siguiente manera: - Se calcula la cantidad mínima perturbadora \p perturb con la función \ref CantPerturbMin. - Se calcula un número seudoaleatorio con la función de C estándar rand() (el generador de números seudoaleatorios se inicializa con la orden srand((unsigned int)time(NULL));). - Se comprueba la paridad del número seudoaleatorio generado para obtener la variable \p signo, de tal forma que: - Si el número seudoaleatorio es par: \p signo vale 1.0. - Si el número seudoaleatorio es impar: \p signo vale -1.0. - Se perturba \em x como xPerturb=x+signo*perturb. \date 22 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ double PerturbaPuntoMin(const double x, const double factor); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza el paso número 1 del algoritmo de Greiner-Hormann, que consiste en el cálculo de los puntos de intersección entre los dos polígonos de trabajo. \param[in,out] poliBas Polígono base, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Al término de la ejecución de la función se le han añadido los puntos de intersección. \param[in,out] poliRec Polígono de recorte, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Al término de la ejecución de la función se le han añadido los puntos de intersección. \param[in] facPer Factor para el posible cálculo de la perturbación de las coordenadas de algunos vértices. Este valor es usado internamente por la función \ref PerturbaPuntoMin (ver su documentación). Un buen valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB. \param[out] nIntersec Número de intersecciones calculadas. \param[out] nPerturb Número de puntos perturbados en el proceso. \return Variable de estado. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si las variables \em poliBas y \em poliRec son polígonos correctamente almacenados. \note En el caso de tener que perturbar algún vértice, sólo se modifican los de \em poliRec, dejando las coordenadas del polígono base inalteradas. \date 22 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ int Paso1Greiner(vertPoliClip* poliBas, vertPoliClip* poliRec, const double facPer, size_t* nIntersec, size_t* nPerturb); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza el paso número 2 del algoritmo de Greiner-Hormann, que consiste en la asignación de los puntos de intersección como entrada o salida. \param[in,out] poliBas Polígono base, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Al término de la ejecución de la función los puntos de intersección han sido marcados como entrada o salida. \param[in,out] poliRec Polígono de recorte, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Al término de la ejecución de la función los puntos de intersección han sido marcados como entrada o salida. \param[in] op Identificador de la operación a realizar. Ha de ser un elemento del tipo enumerado #GEOC_OP_BOOL_POLIG, excepto la unión exclusiva \p xor. En el caso de indicar la operación de unión exclusiva \p xor, se realiza una intersección y \b *NO* se avisa del argumento incorrecto. \note Esta función no comprueba si las variables \em poliBas y \em poliRec son polígonos correctamente almacenados. \date 22 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ void Paso2Greiner(vertPoliClip* poliBas, vertPoliClip* poliRec, const enum GEOC_OP_BOOL_POLIG op); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza el paso número 3 del algoritmo de Greiner-Hormann, que consiste en la generación de los polígonos resultado. \param[in,out] poliBas Polígono base, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip, tal y como sale de la función \ref Paso2Greiner. Al término de la ejecución de la función los puntos visitados han sido marcados en el campo _vertPoliClip::visitado. \param[in,out] poliRec Polígono de recorte, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip, tal y como sale de la función \ref Paso2Greiner. Al término de la ejecución de la función los puntos visitados han sido marcados en el campo _vertPoliClip::visitado. \return Estructura \ref polig con los polígonos resultado de la operación. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si las variables \em poliBas y \em poliRec son polígonos correctamente almacenados. \date 22 de mayo de 2011: Creación de la función. \date 29 de mayo de 2011: Cambio de la variable de salida por la estructura \ref polig. \todo Esta función no está probada. */ polig* Paso3Greiner(vertPoliClip* poliBas, vertPoliClip* poliRec); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza una operación booleana entre dos polígonos mediante el algoritmo de Greiner-Hormann. \param[in,out] poliBas Polígono base, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Al término de la ejecución de la función se han añadido los puntos de intersección con \em poliRec. \param[in,out] poliRec Polígono de recorte, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. Al término de la ejecución de la función se han añadido los puntos de intersección con \em poliRec. \param[in] op Identificador de la operación a realizar. Ha de ser un elemento del tipo enumerado #GEOC_OP_BOOL_POLIG. Varias posibilidades: - #GeocOpBoolInter: Realiza la intersección entre \em poliBas y \em poliRec. - #GeocOpBoolUnion: Realiza la unión entre \em poliBas y \em poliRec. - #GeocOpBoolXor: Realiza la unión exclusiva entre \em poliBas y \em poliRec. - #GeocOpBoolAB: Realiza la sustracción \em poliBas-poliRec. - #GeocOpBoolBA: Realiza la sustracción \em poliRec-poliBas. \param[in] facPer Factor para el posible cálculo de la perturbación de las coordenadas de algunos vértices. Este valor es usado internamente por la función \ref Paso1Greiner (ver su documentación). Un buen valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB. \param[out] nIntersec Número de intersecciones calculadas. \param[out] nPerturb Número de puntos perturbados en el proceso. \return Estructura \ref polig con los polígonos resultado de la operación. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si las variables \em poliBas y \em poliRec son polígonos correctamente almacenados. \note Esta función no comprueba internamente si \em op pertenece al tipo enumerado #GEOC_OP_BOOL_POLIG. Si se introduce un valor no perteneciente al tipo, se realiza la operación #GeocOpBoolInter. \note En el caso de tener que perturbar algún vértice, sólo se modifican los de \em poliRec, dejando las coordenadas de \em poliBase inalteradas. \note Si \em facPer es menor o igual que 1, se sustituye internamente su valor por #GEOC_GREINER_FAC_EPS_PERTURB (ver documentación de la función \ref CantPerturbMin). \note Esta función realiza la unión exclusiva #GeocOpBoolXor mediante la unión de las operaciones individuales #GeocOpBoolAB y #GeocOpBoolBA. Esta última unión simplemente es el almacenamiento en la estructura de salida de los resultados de #GeocOpBoolAB y #GeocOpBoolBA. En ningún momento se realiza la operación booleana #GeocOpBoolUnion entre los resultados de #GeocOpBoolAB y #GeocOpBoolBA. \date 22 de mayo de 2011: Creación de la función. \date 29 de mayo de 2011: Cambio de la variable de salida por la estructura \ref polig. \date 30 de mayo de 2011: Adición de la capacidad de calcular la operación unión exclusiva \p xor. \todo Esta función no está probada. */ polig* PoliBoolGreiner(vertPoliClip* poliBas, vertPoliClip* poliRec, const enum GEOC_OP_BOOL_POLIG op, const double facPer, size_t* nIntersec, size_t* nPerturb); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza una operación booleana entre múltiples polígonos mediante el algoritmo de Greiner-Hormann. \param[in] poliBas Estructura \ref polig que almacena los polígonos base. \param[in] poliRec Estructura \ref polig que almacena los polígonos de recorte. \param[in] op Identificador de la operación a realizar. Ha de ser un elemento del tipo enumerado #GEOC_OP_BOOL_POLIG. Varias posibilidades: - #GeocOpBoolInter: Realiza la intersección entre los polígonos almacenados en \em poliBas y los almacenados en \em poliRec. - #GeocOpBoolUnion: Realiza la unión entre los polígonos almacenados en \em poliBas y los almacenados en \em poliRec. - #GeocOpBoolXor: Realiza la unión exclusiva entre los polígonoa almacenados en \em poliBas y los almacenados en \em poliRec. - #GeocOpBoolAB: Realiza la sustracción entre todos los polígonos \em poliBas-poliRec. - #GeocOpBoolBA: Realiza la sustracción entre todos los polígonos \em poliRec-poliBas. \param[in] facPer Factor para el posible cálculo de la perturbación de las coordenadas de algunos vértices. Este valor es usado internamente por la función \ref Paso1Greiner (ver su documentación). Un buen valor para este argumento es #GEOC_GREINER_FAC_EPS_PERTURB. \param[out] nIntersec Número total de intersecciones calculadas entre todas los polígonos. \param[out] nPerturb Número total de puntos perturbados en el proceso. \return Estructura \ref polig con los polígonos resultado de las operaciones. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función realiza la operación \em op con todas las combinaciones posibles de polígonos. Es decir, se recorren todos los polígonos almacenados en \em poliBas y con cada uno de ellos se realiza la operación \em op con cada polígono almacenado en \em poliRec. \note Esta función no comprueba si las variables \em poliBas y \em poliRec son polígonos correctamente almacenados. \note Esta función no comprueba internamente si \em op pertenece al tipo enumerado #GEOC_OP_BOOL_POLIG. Si se introduce un valor no perteneciente al tipo, se realiza la operación #GeocOpBoolInter. \note En el caso de tener que perturbar algún vértice, sólo se modifican los correspondientes a \em poliRec, dejando las coordenadas de los polígonos de \em poliBase inalteradas. \note Si \em facPer es menor o igual que 1, se sustituye internamente su valor por #GEOC_GREINER_FAC_EPS_PERTURB (ver documentación de la función \ref CantPerturbMin). \note Esta función realiza la unión exclusiva #GeocOpBoolXor mediante la unión de las operaciones individuales #GeocOpBoolAB y #GeocOpBoolBA. Esta última unión simplemente es el almacenamiento en la estructura de salida de los resultados de #GeocOpBoolAB y #GeocOpBoolBA. En ningún momento se realiza la operación booleana #GeocOpBoolUnion entre los resultados de #GeocOpBoolAB y #GeocOpBoolBA. \date 07 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ polig* PoliBoolGreinerMult(const polig* poliBas, const polig* poliRec, const enum GEOC_OP_BOOL_POLIG op, const double facPer, size_t* nIntersec, size_t* nPerturb); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una estructura \ref polig a partir de todos los vértices de un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] poli Polígono de trabajo, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. El puntero pasado ha de apuntar al primer elemento del polígono (no se controla internamente). \param[in] coorOrig Identificador para copiar las coordenadas originales o perturbadas. Dos posibilidades: - 0: Se copiarán las coordenadas perturbadas _vertPoliClip::xP e _vertPoliClip::yP. - Distinto de 0: Se copiarán las coordenadas originales _vertPoliClip::x e _vertPoliClip::y. \return Estructura \ref polig que representa el polígono. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si la variable \em poli es un polígono correctamente almacenado. \note Esta función \b *NO* trabaja con listas circulares. \note Esta función realiza una copia en memoria de las coordenadas de los vértices de la estructura \em poli a la estructura de salida. \date 29 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ polig* CreaPoligPoliClip(vertPoliClip* poli, const int coorOrig); /******************************************************************************/ /******************************************************************************/ /** \brief Añade los vértices de un polígono almacenado como una lista doblemente enlazada de elementos \ref _vertPoliClip a una estructura \ref polig previamente creada. \param[in,out] poli Estructura \ref polig, que almacena una serie de polígonos. Al término de la ejecución de la función, se han añadido los polígonos de la estructura \em anyade. \param[in] anyade Polígono a añadir, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. El puntero pasado ha de apuntar al primer elemento del polígono (no se controla internamente). \param[in] coorOrig Identificador para copiar las coordenadas originales o perturbadas. Dos posibilidades: - 0: Se copiarán las coordenadas perturbadas _vertPoliClip::xP e _vertPoliClip::yP. - Distinto de 0: Se copiarán las coordenadas originales _vertPoliClip::x e _vertPoliClip::y. \return Variable de error. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si la variable \em poli es un polígono correctamente almacenado. \note Esta función no comprueba si la variable \em anyade es un polígono correctamente almacenado. \note Esta función \b *NO* trabaja con listas circulares. \note Esta función realiza una copia en memoria de las coordenadas de los vértices de la estructura \em poli a la estructura de salida. \note Esta función crea internamente una estructura \ref polig para luego añadirla a \em poli con la función \ref AnyadePoligPolig. \date 29 de mayo de 2011: Creación de la función. \todo Esta función no está probada. */ int AnyadePoligClipPolig(polig* poli, vertPoliClip* anyade, const int coorOrig); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/eucli.h0000644000175000017500000002642112032305135017350 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom interp @{ \file eucli.h \brief Declaración de funciones para la realización de cálculos de geometría euclídea. \author José Luis García Pallero, jgpallero@gmail.com \date 27 de octubre de 2009 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _EUCLI_H_ #define _EUCLI_H_ /******************************************************************************/ /******************************************************************************/ #include /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la distancia euclídea entre dos puntos en el plano. \param[in] x1 Coordenada X del punto inicial. \param[in] y1 Coordenada Y del punto inicial. \param[in] x2 Coordenada X del punto final. \param[in] y2 Coordenada Y del punto final. \return Distancia euclídea entre los dos puntos. \note Esta función asume que todas las coordenadas vienen dadas en las mismas unidades. \date 27 de octubre de 2009: Creación de la función. \todo Esta función todavía no está probada. */ double Dist2D(const double x1, const double y1, const double x2, const double y2); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la distancia euclídea entre dos puntos en el plano y realiza la propagación de errores correspondiente. \param[in] x1 Coordenada X del punto inicial. \param[in] y1 Coordenada Y del punto inicial. \param[in] x2 Coordenada X del punto final. \param[in] y2 Coordenada Y del punto final. \param[in] varx1 Varianza de la coordenada X del punto inicial. \param[in] varx1y1 Covarianza entre las coordenadas X e Y del punto inicial. \param[in] vary1 Varianza de la coordenada Y del punto inicial. \param[in] varx2 Varianza de la coordenada X del punto final. \param[in] varx2y2 Covarianza entre las coordenadas X e Y del punto final. \param[in] vary2 Varianza de la coordenada Y del punto final. \param[out] dist Distancia euclídea entre los dos puntos. \param[out] varDist Varianza de la distancia calculada. \note Esta función asume que todas las coordenadas vienen dadas en las mismas unidades. \note Las unidades de las matrices de varianza-covarianza han de ser congruentes con las de las coordenadas pasadas. \date 27 de octubre de 2009: Creación de la función. \todo Esta función todavía no está probada. */ void Dist2DVC(const double x1, const double y1, const double x2, const double y2, const double varx1, const double varx1y1, const double vary1, const double varx2, const double varx2y2, const double vary2, double* dist, double* varDist); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la distancia euclídea entre dos puntos en el espacio. \param[in] x1 Coordenada X del punto inicial. \param[in] y1 Coordenada Y del punto inicial. \param[in] z1 Coordenada Z del punto inicial. \param[in] x2 Coordenada X del punto final. \param[in] y2 Coordenada Y del punto final. \param[in] z2 Coordenada Z del punto final. \return Distancia euclídea entre los dos puntos. \note Esta función asume que todas las coordenadas vienen dadas en las mismas unidades. \date 27 de octubre de 2009: Creación de la función. \todo Esta función todavía no está probada. */ double Dist3D(const double x1, const double y1, const double z1, const double x2, const double y2, const double z2); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la distancia euclídea entre dos puntos en el espacio y realiza la propagación de errores correspondiente. \param[in] x1 Coordenada X del punto inicial. \param[in] y1 Coordenada Y del punto inicial. \param[in] z1 Coordenada Z del punto inicial. \param[in] x2 Coordenada X del punto final. \param[in] y2 Coordenada Y del punto final. \param[in] z2 Coordenada Z del punto final. \param[in] varx1 Varianza de la coordenada X del punto inicial. \param[in] varx1y1 Covarianza entre las coordenadas X e Y del punto inicial. \param[in] varx1z1 Covarianza entre las coordenadas X y Z del punto inicial. \param[in] vary1 Varianza de la coordenada Y del punto inicial. \param[in] vary1z1 Covarianza entre las coordenadas Y y Z del punto inicial. \param[in] varz1 Varianza de la coordenada Z del punto inicial. \param[in] varx2 Varianza de la coordenada X del punto final. \param[in] varx2y2 Covarianza entre las coordenadas X e Y del punto final. \param[in] varx2z2 Covarianza entre las coordenadas X y Z del punto final. \param[in] vary2 Varianza de la coordenada Y del punto final. \param[in] vary2z2 Covarianza entre las coordenadas Y y Z del punto final. \param[in] varz2 Varianza de la coordenada Z del punto final. \param[out] dist Distancia euclídea entre los dos puntos. \param[out] varDist Varianza de la distancia calculada. \note Esta función asume que todas las coordenadas vienen dadas en las mismas unidades. \note Las unidades de las matrices de varianza-covarianza han de ser congruentes con las de las coordenadas pasadas. \date 27 de octubre de 2009: Creación de la función. \todo Esta función todavía no está probada. */ void Dist3DVC(const double x1, const double y1, const double z1, const double x2, const double y2, const double z2, const double varx1, const double varx1y1, const double varx1z1, const double vary1, const double vary1z1, const double varz1, const double varx2, const double varx2y2, const double varx2z2, const double vary2, const double vary2z2, const double varz2, double* dist, double* varDist); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el ángulo formado por dos vectores en el plano. \param[in] x1 Coordenada X del primer vector. \param[in] y1 Coordenada Y del primer vector. \param[in] x2 Coordenada X del segundo vector. \param[in] y2 Coordenada Y del segundo vector. \return Ángulo formado por los dos vectores, en radianes. \note Esta función asume que todas las coordenadas vienen dadas en las mismas unidades. \date 04 de julio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ double AnguloVecPlano(const double x1, const double y1, const double x2, const double y2); /******************************************************************************/ /******************************************************************************/ /** \brief Calcula la altura de un triángulo a partir de las coordenadas de sus vértices. \param[in] xVert Coordenada X del vértice a partir del cual se calculará la altura. \param[in] yVert Coordenada Y del vértice a partir del cual se calculará la altura. \param[in] xBase1 Coordenada X del primer punto de la base del triángulo. \param[in] yBase1 Coordenada Y del primer punto de la base del triángulo. \param[in] xBase2 Coordenada X del segundo punto de la base del triángulo. \param[in] yBase2 Coordenada Y del segundo punto de la base del triángulo. \return Altura del triángulo, dada como la longitud del segmento que, partiendo del vértice pasado, corta en ángulo recto a la base. \note Esta función asume que todas las coordenadas vienen dadas en las mismas unidades. \date 04 de julio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ double AlturaTriangulo(const double xVert, const double yVert, const double xBase1, const double yBase1, const double xBase2, const double yBase2); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/constantes.h0000644000175000017500000002776112032305135020440 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup anespec astro eop general geodesia geom gravim marea @{ \file constantes.h \brief Definición de constantes generales. \author José Luis García Pallero, jgpallero@gmail.com \date 02 de marzo de 2009 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _CONSTANTES_H_ #define _CONSTANTES_H_ /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \typedef geoc_char \brief Nombre del tipo \p char para almacenar números en \p libgeoc. Se declara este tipo para dotar de portabilidad a la biblioteca, debido a que en algunas implementaciones de C la declaración \p char a secas corresponde a un tipo \p unsigned \p char en lugar de a un \p signed \p char, que es el que necesita \p libgeoc cuando almacena un número en un \p char. En la implementación de \p gcc para PowerPC, por ejemplo, el tipo por defecto de un \p char es \p unsigned \p char, lo que hace que se produzcan errores al intentar almacenar números negativos. \date 02 de marzo de 2009: Creación del tipo. */ typedef signed char geoc_char; /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_PI \brief Constante \em PI. Tomada del fichero \p gsl_math.h, de la biblioteca GSL. \date 02 de marzo de 2009: Creación de la constante. */ #define GEOC_CONST_PI (3.14159265358979323846264338328) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_E \brief Constante \em e (base de los logaritmos naturales). Tomada del fichero \p gsl_math.h, de la biblioteca GSL. \date 03 de octubre de 2010: Creación de la constante. */ #define GEOC_CONST_E (2.71828182845904523536028747135) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_GR \brief Paso de grados centesimales a radianes. */ #define GEOC_CONST_GR ((GEOC_CONST_PI)/200.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_RG \brief Paso de radianes a grados centesimales. \date 02 de marzo de 2009: Creación de la constante. */ #define GEOC_CONST_RG (1.0/(GEOC_CONST_GR)) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_DR \brief Paso de grados sexagesimales en formato decimal a radianes. \date 02 de marzo de 2009: Creación de la constante. */ #define GEOC_CONST_DR ((GEOC_CONST_PI)/180.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_RD \brief Paso de radianes a grados sexagesimales en formato decimal. \date 02 de marzo de 2009: Creación de la constante. */ #define GEOC_CONST_RD (1.0/(GEOC_CONST_DR)) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_SIMUGAL \brief Paso de atracción gravitatoria en el SI (m/s^2) a microgales. \date 05 de noviembre de 2009: Creación de la constante. */ #define GEOC_CONST_SIMUGAL (1.0e8) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_MJD \brief Constante a sustraer a una fecha juliana (en días) para convertirla en fecha juliana modificada (MJD). \date 04 de octubre de 2009: Creación de la constante. */ #define GEOC_CONST_MJD (2400000.5) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_J2000 \brief Constante a sustraer a una fecha juliana (en días) para convertirla en fecha juliana referida a J2000. \date 01 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_J2000 (2451545.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_JISGPS \brief Fecha juliana del día de inicio de las semanas GPS: 6 de enero de 1980, 00:00:00 horas. \date 02 de marzo de 2010: Creación de la constante. */ #define GEOC_CONST_JISGPS (2444244.5) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_MIN_HORA \brief Número de minutos que contiene una hora. \date 19 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_MIN_HORA (60.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_SEG_HORA \brief Número de segundos que contiene una hora. \date 01 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_SEG_HORA (3600.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_SEG_MIN \brief Número de segundos que contiene un minuto \date 19 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_SEG_MIN (60.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_SEG_DIA \brief Número de segundos que contiene un día. \date 24 de octubre de 2009: Creación de la constante. */ #define GEOC_CONST_SEG_DIA (86400.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_HORAS_DIA \brief Número de horas que contiene un día. \date 01 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_HORAS_DIA (24.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_DIAS_SIGLO_JUL \brief Número de días que contiene un siglo juliano. \date 01 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_DIAS_SIGLO_JUL (36525.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_DIAS_SEMANA \brief Número de días que contiene una semana. \date 02 de marzo de 2010: Creación de la constante. */ #define GEOC_CONST_DIAS_SEMANA (7.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_DIAS_ANYO_NORM \brief Número de días que contiene un año normal. \date 02 de marzo de 2010: Creación de la constante. */ #define GEOC_CONST_DIAS_ANYO_NORM (365.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_DIAS_ANYO_BIS \brief Número de días que contiene un año bisiesto. \date 02 de marzo de 2010: Creación de la constante. */ #define GEOC_CONST_DIAS_ANYO_BIS ((GEOC_CONST_DIAS_ANYO_NORM)+1.0) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_CPD_RH \brief Paso de ciclos por día a radianes por hora. \date 20 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_CPD_RH (2.0*(GEOC_CONST_PI)/(GEOC_CONST_HORAS_DIA)) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_RH_CPD \brief Paso de radianes por hora a ciclos por día. \date 20 de diciembre de 2009: Creación de la constante. */ #define GEOC_CONST_RH_CPD (1.0/(GEOC_CONST_CPD_RH)) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_G \brief Constante de gravitación universal, en m^3/(kg*s^2). \date 04 de noviembre de 2009: Creación de la constante. */ #define GEOC_CONST_G (6.67428e-11) /******************************************************************************/ /******************************************************************************/ /** \def GEOC_CONST_VRT \brief Velocidad de rotación de la Tierra, en radianes/s. \date 21 de enero de 2011: Creación de la constante. */ #define GEOC_CONST_VRT (7.292115e-5) /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/calctopo.h0000644000175000017500000001005012032305135020042 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geodesia geom @{ \file calctopo.h \brief Declaración de funciones para cálculos de topografía. \author José Luis García Pallero, jgpallero@gmail.com \date 05 de julio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _CALCTOPO_H_ #define _CALCTOPO_H_ /******************************************************************************/ /******************************************************************************/ #include #include"libgeoc/constantes.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \brief Calcula el acimut topográfico entre dos puntos. \param[in] x1 Coordenada X del primer punto. \param[in] y1 Coordenada y del primer punto. \param[in] x2 Coordenada X del segundo punto. \param[in] y2 Coordenada y del segundo punto. \return Acimut del primer al segundo punto, en radianes. \date 05 de julio de 2011: Creación de la función. \todo Esta función todavía no ha sido probada. */ double AcimutTopografico(const double x1, const double y1, const double x2, const double y2); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/general.h0000644000175000017500000000624312032305135017664 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \defgroup general Módulo GENERAL \brief En este módulo se reúnen constantes, macros y funciones de utilidad general. @{ \file general.h \brief Inclusión de archivos de cabecera para la utilización de la biblioteca GENERAL. \author José Luis García Pallero, jgpallero@gmail.com \date 16 de febrero de 2011 \version 1.0 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _GENERAL_H_ #define _GENERAL_H_ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/compilador.h" #include"libgeoc/constantes.h" #include"libgeoc/fgeneral.h" #include"libgeoc/ventorno.h" /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/errores.h0000644000175000017500000013637512032305135017742 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \defgroup errores Módulo ERRORES \ingroup anespec eop fichero geodesia geom general geopot gshhs marea matriz \ingroup mmcc orden snx texto \brief En este módulo se reúnen los ficheros necesarios para realizar el tratamiento de errores que puedan ocurrir en la biblioteca. @{ \file errores.h \brief Declaración de funciones y constantes para el tratamiento de errores. En el momento de la compilación ha de seleccionarse el comportamiento de la función \ref GeocError. Para realizar la selección es necesario definir las variables para el preprocesador \em ESCRIBE_MENSAJE_ERROR si se quiere que la función imprima un mensaje de error y/o \em FIN_PROGRAMA_ERROR si se quiere que la función termine la ejecución del programa en curso. Si no se define ninguna variable, la función no ejecuta ninguna acción. En \p gcc, las variables para el preprocesador se pasan como \em -DXXX, donde \em XXX es la variable a introducir. \author José Luis García Pallero, jgpallero@gmail.com \date 06 de marzo de 2009 \section Licencia Licencia Copyright (c) 2009-2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include #include /******************************************************************************/ /******************************************************************************/ #ifndef _ERRORES_H_ #define _ERRORES_H_ /******************************************************************************/ /******************************************************************************/ //GENERAL #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_PLINEA \brief Palabra \em Línea para ser utilizada en el mensaje que imprime la macro #GEOC_ERROR. Esta constante se define porque el preprocesador del compilador \p pgcc no soporta letras con tilde escritas directamente en las órdenes a ejecutar por las macros. \date 10 de enero de 2011: Creación de la constante. */ #define GEOC_PLINEA "Línea" /******************************************************************************/ /******************************************************************************/ /** \def GEOC_TIPO_ERR_NADA \brief Indicador de que la función \ref GeocError no hace nada. \date 09 de enero de 2011: Creación de la constante. */ #define GEOC_TIPO_ERR_NADA 0 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_TIPO_ERR_MENS_Y_EXIT \brief Indicador de que la función \ref GeocError imprime un mensaje descriptivo en la salida de error \em stderr y termina la ejecución del programa en curso. \date 09 de enero de 2011: Creación de la constante. */ #define GEOC_TIPO_ERR_MENS_Y_EXIT 1 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_TIPO_ERR_MENS \brief Indicador de que la función \ref GeocError imprime un mensaje descriptivo en la salida de error \em stderr y no termina la ejecución del programa en curso. \date 09 de enero de 2011: Creación de la constante. */ #define GEOC_TIPO_ERR_MENS 2 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_TIPO_ERR_EXIT \brief Indicador de que la función \ref GeocError termina la ejecución del programa en curso. \date 09 de enero de 2011: Creación de la constante. */ #define GEOC_TIPO_ERR_EXIT 3 /******************************************************************************/ /******************************************************************************/ /** \brief Indica el tipo de acción que realiza la función \ref GeocError. \return Cuatro posibles valores: - #GEOC_TIPO_ERR_NADA: La función \ref GeocError no hace nada. - #GEOC_TIPO_ERR_MENS_Y_EXIT: La función \ref GeocError imprime un mensaje descriptivo en la salida de error \em stderr y termina la ejecución del programa en curso. - #GEOC_TIPO_ERR_MENS: La función \ref GeocError imprime un mensaje descriptivo en la salida de error \em stderr y no detiene la ejecución del programa en curso. - #GEOC_TIPO_ERR_EXIT: La función \ref GeocError detiene la ejecución del programa en curso. \date 09 de enero de 2011: Creación de la función. */ int GeocTipoError(void); /******************************************************************************/ /******************************************************************************/ /** \brief Imprime un mensaje en la salida de error \em stderr y/o sale del programa en ejecución. \param[in] mensaje Cadena de texto a imprimir. \param[in] funcion Nombre de la función desde donde se ha invocado a esta función. \note Si este fichero se compila con las variables para el preprocesador \em ESCRIBE_MENSAJE_ERROR y \em FIN_PROGRAMA_ERROR, esta función imprime el mensaje de error y termina la ejecución del programa en curso mediante la llamada a la función \em exit(EXIT_FAILURE), de la biblioteca estándar de C. \note Si este fichero se compila con la variable para el preprocesador \em ESCRIBE_MENSAJE_ERROR, esta función imprime el mensaje de error. \note Si este fichero se compila con la variable para el preprocesador \em FIN_PROGRAMA_ERROR, esta función termina la ejecución del programa en curso mediante la llamada a la función \em exit(EXIT_FAILURE), de la biblioteca estándar de C. \note Si este fichero se compila sin variables para el preprocesador, esta función no hace nada. \date 10 de enero de 2011: Creación de la función. */ void GeocError(const char mensaje[], const char funcion[]); /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERROR \brief Macro para imprimir un mensaje en la salida de error \em stderr y/o sale del programa en ejecución. \param[in] mensaje Cadena de texto a imprimir. \note Esta macro llama internamente a la función \ref GeocError. \note Esta macro pasa como argumento \em funcion a \ref GeocError la variable del preprocesador \em __func__, de C99. \date 10 de enero de 2011: Creación de la macro. */ #define GEOC_ERROR(mensaje) \ { \ if(GeocTipoError()!=GEOC_TIPO_ERR_NADA) \ { \ fprintf(stderr,"\n\n"); \ fprintf(stderr,"********************\n********************\n"); \ fprintf(stderr,GEOC_PLINEA" %d del fichero '%s'\n",__LINE__,__FILE__); \ GeocError(mensaje,(const char*)__func__); \ fprintf(stderr,"********************\n********************\n\n"); \ } \ else \ { \ GeocError(mensaje,(const char*)__func__); \ } \ } /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //GENERAL #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_NO_ERROR \brief Indicador de que no ha ocurrido ningun error. \date 06 de marzo de 2009: Creación de la constante. */ #define GEOC_ERR_NO_ERROR 0 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_LECTURA_FICHERO \brief Indicador de que ha ocurrido un error en la lectura de un fichero. \date 06 de marzo de 2009: Creación de la constante. */ #define GEOC_ERR_LECTURA_FICHERO 1001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_ESCRITURA_FICHERO \brief Indicador de que ha ocurrido un error en escritura de un fichero. \date 20 de agosto de 2009: Creación de la constante. */ #define GEOC_ERR_ESCRITURA_FICHERO 1002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_QUEDAN_DATOS_EN_FICHERO \brief Indicador de que quedan datos por leer en un fichero. \date 06 de marzo de 2009: Creación de la constante. */ #define GEOC_ERR_QUEDAN_DATOS_EN_FICHERO 1003 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_NO_QUEDAN_DATOS_EN_FICHERO \brief Indicador de que no quedan datos por leer en un fichero. \date 25 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_NO_QUEDAN_DATOS_EN_FICHERO 1004 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_NO_HAY_DATOS_EN_FICHERO \brief Indicador de que no hay datos a leer en un fichero. \date 02 de diciembre de 2010: Creación de la constante. */ #define GEOC_ERR_NO_HAY_DATOS_EN_FICHERO 1005 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_LINEA_LARGA_EN_FICHERO \brief Indicador de que una línea de un fichero es demasiado larga. \date 23 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_LINEA_LARGA_EN_FICHERO 1006 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_LINEA_CORTA_EN_FICHERO \brief Indicador de que una línea de un fichero es demasiado corta. \date 23 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_LINEA_CORTA_EN_FICHERO 1007 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_ARG_ENTRADA_INCORRECTO \brief Indicador de que un argumento de entrada de una función es incorrecto. \date 06 de marzo de 2009: Creación de la constante. */ #define GEOC_ERR_ARG_ENTRADA_INCORRECTO 1008 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_ASIG_MEMORIA \brief Indicador de que ha ocurrido un error en la asignación de memoria. \date 06 de marzo de 2009: Creación de la constante. */ #define GEOC_ERR_ASIG_MEMORIA 1009 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_FUERA_DOMINIO \brief Indicador de que ha ocurrido un error porque un dato está fuera de dominio. \date 04 de octubre de 2009: Creación de la constante. */ #define GEOC_ERR_FUERA_DOMINIO 1010 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_FUERA_DOMINIO_MAYOR \brief Indicador de que ha ocurrido un error porque un dato está fuera de dominio. En este caso, el dato se sale del dominio por arriba (porque es demasiado grande). \date 26 de octubre de 2009: Creación de la constante. */ #define GEOC_ERR_FUERA_DOMINIO_MAYOR 1011 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_FUERA_DOMINIO_MENOR \brief Indicador de que ha ocurrido un error porque un dato está fuera de dominio. En este caso, el dato se sale del dominio por abajo (porque es demasiado pequeño). \date 26 de octubre de 2009: Creación de la constante. */ #define GEOC_ERR_FUERA_DOMINIO_MENOR 1012 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_INTERP \brief Indicador de que ha ocurrido un error en una interpolación. \date 15 de mayo de 2010: Creación de la constante. */ #define GEOC_ERR_INTERP 1013 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_INTERP_NO_DATO \brief Indicador de que no hay datos para realizar una interpolación. \date 30 de mayo de 2010: Creación de la constante. */ #define GEOC_ERR_INTERP_NO_DATO 1014 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_DIV_ENTRE_CERO \brief Indicador de que se ha realizado una división entre cero. \date 26 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_DIV_ENTRE_CERO 1015 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_DIM_MATRIZ \brief Indicador de dimensiones de una matriz erróneas. \date 02 de diciembre de 2010: Creación de la constante. */ #define GEOC_ERR_DIM_MATRIZ 1016 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_MATRIZ_SINGULAR \brief Indicador de matriz singular. \date 12 de marzo de 2011: Creación de la constante. */ #define GEOC_ERR_MATRIZ_SINGULAR 1017 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //EOP #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_EOP_ERRORES \brief Indicador de que ha ocurrido un error porque una estructura eop no contiene información de errores. \date 04 de octubre de 2009: Creación de la constante. */ #define GEOC_ERR_EOP_ERRORES 2001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_EOP_DOS_PUNTOS \brief Indicador de que ha ocurrido un error porque en una interpolación cuadrática sólo hay dos puntos disponibles. \date 12 de octubre de 2009: Creación de la constante. */ #define GEOC_ERR_EOP_DOS_PUNTOS 2002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_EOP_NO_DATOS \brief Indicador de que una estructura eop no contiene datos. \date 19 de junio de 2010: Creación de la constante. */ #define GEOC_ERR_EOP_NO_DATOS 2003 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //SINEX #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_LINEA_ILEGAL \brief Indicador de que una línea de un fichero SINEX no comienza por una de las cadenas permitidas (#GEOC_SNX_CAD_COMENTARIO, #GEOC_SNX_CAD_INI_CABECERA, #GEOC_SNX_CAD_INI_BLOQUE, #GEOC_SNX_CAD_FIN_BLOQUE o #GEOC_SNX_CAD_INI_DATOS). \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_LINEA_ILEGAL 3001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_LINEA_LARGA \brief Indicador de que una línea de un fichero SINEX es demasiado larga (más de #GEOC_SNX_LON_MAX_LIN_FICH carácteres). \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_LINEA_LARGA 3002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_LINEA_CORTA \brief Indicador de que una línea de un fichero SINEX es demasiado corta. \date 29 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_LINEA_CORTA 3003 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_NO_BLOQUES \brief Indicador de que en un fichero SINEX no hay bloques válidos. \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_NO_BLOQUES 3004 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_ID_BLOQUE_DISTINTO \brief Indicador de que en un fichero SINEX los identificadores de bloque tras las marcas de inicio y fin son distintos. \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_ID_BLOQUE_DISTINTO 3005 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BLOQUE_NO_INICIO \brief Indicador de que en un fichero SINEX un bloque no tiene identificador de inicio. \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_BLOQUE_NO_INICIO 3006 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BLOQUE_NO_FIN \brief Indicador de que en un fichero SINEX un bloque no tiene identificador de fin. \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_BLOQUE_NO_FIN 3007 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_NO_FIN_FICH \brief Indicador de que un fichero SINEX no tiene indicador de fin de fichero. \date 28 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_NO_FIN_FICH 3008 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_NO_ID_CABECERA \brief Indicador de que un fichero SINEX no tiene indicador cabecera. \date 29 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_NO_ID_CABECERA 3009 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_FORMATO_CABECERA \brief Indicador de que un fichero SINEX tiene una cabecera que no respeta el formato. \date 29 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_FORMATO_CABECERA 3010 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_CODFICH_INC \brief Indicador de que un fichero SINEX tiene un indicador de código de tipo de fichero incorrecto. \date 05 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_CODFICH_INC 3011 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_TIPODOC_INC \brief Indicador de que un fichero SINEX tiene un indicador de tipo de documento incorrecto. \date 05 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_TIPODOC_INC 3012 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_VERS_INC \brief Indicador de que un fichero SINEX tiene un indicador de versión incorrecto. \date 30 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_VERS_INC 3013 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_FECHA_INC \brief Indicador de que una fecha es incorrecta en un fichero SINEX. \date 30 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_FECHA_INC 3014 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_CODOBS_INC \brief Indicador de que el código de observación es incorrecto en un fichero SINEX. \date 30 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_CODOBS_INC 3015 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_CODCONSTR_INC \brief Indicador de que el código de constreñimiento es incorrecto en un fichero SINEX. \date 30 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_CODCONSTR_INC 3016 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_SOLCONT_INC \brief Indicador de que un código de solución contenida en un fichero SINEX es incorrecto. \date 31 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_SOLCONT_INC 3017 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_NSOLCONT_INC \brief Indicador de que un código de solución contenida en un fichero SINEX es incorrecto. \date 31 de diciembre de 2009: Creación de la constante. */ #define GEOC_ERR_SNX_NSOLCONT_INC 3018 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_FORM_LINEA_INC \brief Indicador de que una línea de un fichero SINEX tiene un formato incorrecto. \date 01 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_FORM_LINEA_INC 3019 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BFR_TIPOINF_INC \brief Indicador de que el código de tipo de información de un bloque FILE/REFERENCE de un fichero SINEX es incorrecto. \date 01 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BFR_TIPOINF_INC 3020 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BND_CODNUT_INC \brief Indicador de que el código de modelo de nutación de un bloque NUTATION/DATA de un fichero SINEX es incorrecto. \date 03 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BND_CODNUT_INC 3021 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BPD_CODPREC_INC \brief Indicador de que el código de modelo de precesión de un bloque PRECESSION/DATA de un fichero SINEX es incorrecto. \date 03 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BPD_CODPREC_INC 3022 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSII_GRADLATSEX_INC \brief Indicador de que un valor de grados sexagesimales de latitud de un bloque SITE/ID de un fichero SINEX es incorrecto. \date 15 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSII_GRADLATSEX_INC 3023 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSII_GRADLONSEX_INC \brief Indicador de que un valor de grados sexagesimales de longitud de un bloque SITE/ID de un fichero SINEX es incorrecto. \date 15 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSII_GRADLONSEX_INC 3024 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSII_MINSEX_INC \brief Indicador de que un valor de minutos sexagesimales de un bloque SITE/ID de un fichero SINEX es incorrecto. \date 15 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSII_MINSEX_INC 3025 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSII_SEGSEX_INC \brief Indicador de que un valor de segundos sexagesimales de un bloque SITE/ID de un fichero SINEX es incorrecto. \date 15 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSII_SEGSEX_INC 3026 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSE_CODSREX_INC \brief Indicador de que un código del sistema de referencia utilizado para definir la excentricidad de una antena de un bloque SITE/ECCENTRICITY de un fichero SINEX es incorrecto. \date 23 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSE_CODSREX_INC 3027 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_CODGNSS_INC \brief Indicador de que un código de constelación GNSS utilizado en un fichero SINEX es incorrecto. \date 28 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_CODGNSS_INC 3028 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSAP_CODFREC_INC \brief Indicador de que un código frecuencia de satélite GNSS de un bloque SATELLITE/PHASE_CENTER de un fichero SINEX es incorrecto. \date 28 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSAP_CODFREC_INC 3029 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSAP_TIPOPCV_INC \brief Indicador de que un código indicador de tipo de variación del centro de fase de un bloque SATELLITE/PHASE_CENTER de un fichero SINEX es incorrecto. \date 28 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSAP_TIPOPCV_INC 3030 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSAP_MODAPPCV_INC \brief Indicador de que un código indicador de modelo de aplicación de las variaciones del centro de fase de un bloque SATELLITE/PHASE_CENTER de un fichero SINEX es incorrecto. \date 28 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSAP_MODAPPCV_INC 3031 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_BSOES_IDPARAM_INC \brief Indicador de que un identificador de parámetro estadístico de un bloque SOLUTION/STATISTICS de un fichero SINEX es incorrecto. \date 28 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_BSOES_IDPARAM_INC 3032 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_IDUNID_INC \brief Indicador de que un identificador de unidades utilizado en un fichero SINEX es incorrecto. \date 29 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_IDUNID_INC 3033 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_TIPPAR_INC \brief Indicador de que un identificador de tipo de parámetro utilizado en un fichero SINEX es incorrecto. \date 29 de enero de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_TIPPAR_INC 3034 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_PTRIAN_INC \brief Indicador de que un identificador de parte triangular de una matriz simétrica utilizado en un fichero SINEX es incorrecto. \date 17 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_PTRIAN_INC 3035 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_TIPOMAT_INC \brief Indicador de que un identificador de tipo de matriz utilizado en un fichero SINEX es incorrecto. \date 17 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_TIPOMAT_INC 3036 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_SNX_POSMAT_INC \brief Indicador de que una posición en una matriz almacenada en un fichero SINEX es incorrecta. \date 17 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_SNX_POSMAT_INC 3037 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //GTS #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GTS_VERT_FHULL \brief Indicador de que un vértice de una nube de puntos está fuera del \em convex \em hull que la engloba. \date 09 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_GTS_VERT_FHULL 4001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GTS_VERT_FSUP \brief Indicador de que un vértice está fuera de una superficie. \date 22 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_GTS_VERT_FSUP 4002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GTS_VERT_DUPL \brief Indicador de que un vértice de una nube de puntos está duplicado. \date 09 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_GTS_VERT_DUPL 4003 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GTS_CONF_CONSTR \brief Indicador de que ha habido un conflicto con un constreñimiento en un proceso de triangulación. \date 09 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_GTS_CONF_CONSTR 4004 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //PMAREA #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PMAREA_NO_HAY_BLOQUE \brief Indicador de que no existe un bloque buscado en un fichero. \date 24 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_PMAREA_NO_HAY_BLOQUE 5001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PMAREA_LIN_FICH_INC \brief Indicador de que una línea de fichero de parámetros de marea es incorrecta. \date 25 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_PMAREA_LIN_FICH_INC 5002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PMAREA_DEF_BLOQUE_INC \brief Indicador de que una definición de bloque de parámetros de marea en un fichero es incorrecta. \date 25 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_PMAREA_DEF_BLOQUE_INC 5003 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PMAREA_LIM_FDOM \brief Indicador de que alguno de los límites de la malla está fuera de dominio. \date 25 de abril de 2010: Creación de la constante. */ #define GEOC_ERR_PMAREA_LIM_FDOM 5004 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //GEOPOT #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GEOPOT_GRADO_ORDEN_MAL \brief Indicador de que los grados y/u órdenes pasados a una función no son correctos. \date 25 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_GEOPOT_GRADO_ORDEN_MAL 6001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GEOPOT_GRACE_LINFO_NO \brief Indicador de que no hay línea (o la que hay no es la primera) de información general de un fichero de un desarrollo del potencial de la Tierra en armónicos esféricos en formato de GRACE. \date 16 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_GEOPOT_GRACE_LINFO_NO 6002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GEOPOT_GRACE_LINFO_REPE \brief Indicador de que la línea de información general de un fichero de un desarrollo del potencial de la Tierra en armónicos esféricos en formato de GRACE está repetida. \date 16 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_GEOPOT_GRACE_LINFO_REPE 6003 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GEOPOT_GRACE_CAB_INCOMP \brief Indicador de cabecera incompleta en un fichero de un desarrollo del potencial de la Tierra en armónicos esféricos en formato de GRACE está repetida. \date 17 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_GEOPOT_GRACE_CAB_INCOMP 6004 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GEOPOT_GRACE_MEZCLA_TIPO_COEF \brief Indicador de que en un fichero de un desarrollo del potencial de la Tierra en armónicos esféricos en formato de GRACE hay definiciones de coeficientes de distintas versiones. \date 23 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_GEOPOT_GRACE_MEZCLA_TIPO_COEF 6005 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GEOPOT_GRACE_NLINEAS_DATOS_MAL \brief Indicador de que en un fichero de un desarrollo del potencial de la Tierra en armónicos esféricos en formato de GRACE no coinciden el número de líneas de datos leídas en dos pasadas distintas sobre el fichero. \date 24 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_GEOPOT_GRACE_NLINEAS_DATOS_MAL 6006 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //NUMLOVE #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_NUMLOVE_NO_HAY_BLOQUE \brief Indicador de que no existe un bloque buscado en un fichero. \date 29 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_NUMLOVE_NO_HAY_BLOQUE 7001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_NUMLOVE_DEF_BLOQUE_INC \brief Indicador de que una línea de fichero de números de Love es incorrecta. \date 29 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_NUMLOVE_DEF_BLOQUE_INC 7002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_NUMLOVE_LIN_FICH_INC \brief Indicador de que una definición de bloque de números de Love en un fichero es incorrecta. \date 29 de noviembre de 2010: Creación de la constante. */ #define GEOC_ERR_NUMLOVE_LIN_FICH_INC 7003 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //GSHHS #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GSHHS_VERS_ANTIGUA \brief Indicador de que la versión de un fichero de GSHHS es antigua. \date 16 de abril de 2011: Creación de la constante. */ #define GEOC_ERR_GSHHS_VERS_ANTIGUA 8001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_GSHHS_CREA_POLI \brief Indicador de que ha ocurrido un error de tipo #GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG o #GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG al crear una estructura \ref polig o \ref polil \date 19 de junio de 2011: Creación de la constante. */ #define GEOC_ERR_GSHHS_CREA_POLI 8002 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //POLIG #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG \brief Indicador de que dos vectores de coordenadas no contienen el mismo número de polígonos. \date 27 de mayo de 2011: Creación de la constante. */ #define GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG 9001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG \brief Indicador de que dos vectores de coordenadas no contienen los mismos polígonos. \date 27 de mayo de 2011: Creación de la constante. */ #define GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG 9002 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //POLIL #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL \brief Indicador de que dos vectores de coordenadas no contienen el mismo número de polilíneas. \date 03 de junio de 2011: Creación de la constante. */ #define GEOC_ERR_POLIL_VEC_DISTINTO_NUM_POLIL 10001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL \brief Indicador de que dos vectores de coordenadas no contienen las mismas polilíneas. \date 03 de junio de 2011: Creación de la constante. */ #define GEOC_ERR_POLIL_VEC_DISTINTAS_POLIL 10002 /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus } #endif /******************************************************************************/ /******************************************************************************/ //PROYEC #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PROYEC_INI_PROJ \brief Indicador de que ha ocurrido un error en la inicialización de una proyección de PROJ.4. \date 31 de mayo de 2011: Creación de la constante. */ #define GEOC_ERR_PROYEC_INI_PROJ 11001 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PROYEC_NO_INV_PROJ \brief Indicador de que una proyección cartográfica de PROJ.4 no tiene paso inverso. \date 31 de mayo de 2011: Creación de la constante. */ #define GEOC_ERR_PROYEC_NO_INV_PROJ 11002 /******************************************************************************/ /******************************************************************************/ /** \def GEOC_ERR_PROYEC_PROJ_ERROR \brief Indicador de que ha ocurrido un error al proyectar un punto con PROJ.4. \date 31 de mayo de 2011: Creación de la constante. */ #define GEOC_ERR_PROYEC_PROJ_ERROR 11003 /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/libgeoc/recpolil.h0000755000175000017500000005575712032305135020101 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file recpolil.h \brief Definición de estructuras y declaración de funciones para el recorte de polilíneas por medio de polígonos. \author José Luis García Pallero, jgpallero@gmail.com \date 04 de junio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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 _RECPOLIL_H_ #define _RECPOLIL_H_ /******************************************************************************/ /******************************************************************************/ #include #include #include"libgeoc/errores.h" #include"libgeoc/eucli.h" #include"libgeoc/geocnan.h" #include"libgeoc/greiner.h" #include"libgeoc/polig.h" #include"libgeoc/polil.h" #include"libgeoc/ptopol.h" #include"libgeoc/segmento.h" /******************************************************************************/ /******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /******************************************************************************/ /** \def GEOC_RECPOLIL_BUFFER_PTOS \brief Número de puntos para ir asignando memoria en bloques para las polilíneas de salida en la funcion \ref Paso2Recpolil. Ha de ser un número mayor o igual a 2. \date 04 de junio de 2011: Creación de la constante. */ #define GEOC_RECPOLIL_BUFFER_PTOS 100 /******************************************************************************/ /******************************************************************************/ /** \enum GEOC_OP_BOOL_POLIL \brief Operación booleana entre polilínea y polígono. \date 04 de junio de 2011: Creación del tipo. */ enum GEOC_OP_BOOL_POLIL { /** \brief Polilínea interior al polígono. */ GeocOpBoolDentro=111, /** \brief Polilínea exterior al polígono. */ GeocOpBoolFuera=112 }; /******************************************************************************/ /******************************************************************************/ /** \struct _vertPolilClip \brief Estructura de definición de un vértice de una polilínea usada en operaciones de recorte. La polilínea se almacena en memoria como una lista doblemente enlazada de vértices. \date 04 de junio de 2011: Creación de la estructura. */ typedef struct _vertPolilClip { /** \brief Coordenada X del vértice. */ double x; /** \brief Coordenada Y del vértice. */ double y; /** \brief Vértice anterior. */ struct _vertPolilClip* anterior; /** \brief Vértice siguiente. */ struct _vertPolilClip* siguiente; /** \brief Indicador de punto de la polilínea original. Dos posibilidades: - 0: No es un punto de la polilínea original. - Distinto de 0: Sí es un punto de la polilínea original. */ char orig; /** \brief Posición del vértice con respecto al polígono de recorte. Tres posibilidades: - #GEOC_PTO_FUERA_POLIG: El punto está fuera del polígono. - #GEOC_PTO_BORDE_POLIG: El punto está en el borde o en un vértice del polígono. - #GEOC_PTO_DENTRO_POLIG: El punto está dentro del polígono. */ char pos; /** \brief Distancia, en tanto por uno, de un nodo de intersección con respecto al primer vértice del segmento que lo contiene. */ double alfa; }vertPolilClip; /******************************************************************************/ /******************************************************************************/ /** \brief Crea un vértice de tipo \ref _vertPolilClip y lo inserta entre otros dos. \param[in] x Coordenada X del vértice. \param[in] y Coordenada Y del vértice. \param[in] anterior Vértice anterior (puede ser \p NULL). \param[in] siguiente Vértice siguiente (puede ser \p NULL). \param[in] orig Campo _vertPolilClip::orig. \param[in] pos Campo _vertPolilClip::pos. \param[in] alfa Campo _vertPolilClip::alfa. \return Puntero al nuevo vértice creado. Si se devuelve \p NULL, ha ocurrido un error de asignación de memoria. \date 04 de junio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPolilClip* CreaVertPolilClip(const double x, const double y, vertPolilClip* anterior, vertPolilClip* siguiente, const char orig, const char pos, const double alfa); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una polilínea, como una lista doblemente enlazada de elementos \ref _vertPolilClip. \param[in] x Vector de coordenadas X de los nodos de la polilínea. \param[in] y Vector de coordenadas Y de los nodos de la polilínea. \param[in] nCoor Número de elementos de los vectores \em x e \em y. \param[in] incX Posiciones de separación entre los elementos del vector \em x. Este argumento siempre ha de ser un número positivo. \param[in] incY Posiciones de separación entre los elementos del vector \em y. Este argumento siempre ha de ser un número positivo. \return Puntero al primer vértice de la lista. Si se devuelve \p NULL, ha ocurrido un error de asignación de memoria. \note Esta función asume que el argumento \em nCoor es mayor que 0. \note Si en los vectores de coordenadas \em x e \em y hay valores #GEOC_NAN, éstos no se tienen en cuenta a la hora de la creación de la estructura de salida. \note Que los vectores de coordenadas \em x e \em y admitan vértices con coordenadas (#GEOC_NAN,#GEOC_NAN) no quiere decir que éstos sean separadores de múltiples polilíneas. \em x e \em y \b *SÓLO* deben almacenar una única polilínea. \note Esta función asigna el valor 0 a todos los campos _vertPolilClip::pos de los elementos creados. \date 04 de junio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPolilClip* CreaPolilClip(const double* x, const double* y, const size_t nCoor, const size_t incX, const size_t incY); /******************************************************************************/ /******************************************************************************/ /** \brief Libera la memoria asignada a una polilínea almacenada como una lista doblemente enlazada de elementos \ref _vertPolilClip. \param[in] poli Puntero al primer elemento de la polilínea. \note Esta función no comprueba si hay vértices de la polilínea anteriores al vértice de entrada, por lo que si se quiere liberar toda la memoria asignada a una polilínea, el vértice pasado ha de ser el primero de la lista. \date 04 de junio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void LibMemPolilClip(vertPolilClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Elimina los vértices no originales de una polilínea almacenada como una lista doblemente enlazada de elementos \ref _vertPolilClip. \param[in] poli Puntero al primer elemento de la polilínea. \return Puntero al primer elemento de la polilínea original. Si se devuelve \p NULL, ninguno de los vértices pertenecía a la polilínea original. \note Los vértices eliminados por esta función son todos aquéllos cuyo campo _vertPolilClip::orig sea igual a 0. \note Aunque se supone que el primer vértice de una polilínea siempre es un vértice original, si no lo es, la variable de entrada queda modificada. Por tanto, siempre es recomendable capturar la variable de salida, que garantiza la posición del primer elemento. \date 04 de junio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPolilClip* ReiniciaPolilClip(vertPolilClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Busca el siguiente vértice original en una polilínea. \param[in] vert Puntero al vértice a partir del cual se ha de buscar. \return Puntero al siguiente vértice original en la polilínea. Si se devuelve \p NULL, se ha llegado al final. \note Los vértices no originales son todos aquéllos cuyo campo _vertPolilClip::orig es distinto de 0. \date 04 de junio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ vertPolilClip* SiguienteVertOrigPolilClip(vertPolilClip* vert); /******************************************************************************/ /******************************************************************************/ /** \brief Inserta un vértice de tipo \ref _vertPolilClip entre otros dos, atendiendo al campo _vertPolilClip::alfa. \param[in] ins Vértice a insertar. \param[in] extremoIni Extremo inicial del segmento donde se insertará \em ins. \param[in] extremoFin Extremo final del segmento donde se insertará \em ins. \note Esta función asume que todos los elementos pasados tienen memoria asignada. \note Si entre \em extremoIni y \em extremoFin hay más vértices, \em ins se insertará de tal modo que los campos _vertPolilClip::alfa queden ordenados de menor a mayor. \note Si el campo _vertPolilClip::alfa de \em ins tiene el mismo valor que el de \em extremoIni, \em ins se insertará justo a continuación de \em extremoIni. \note Si el campo _vertPolilClip::alfa de \em ins tiene el mismo valor que el de \em extremoFin, \em ins se insertará justo antes de \em extremoIni. \date 04 de junio de 2011: Creación de la función. \todo Esta función todavía no está probada. */ void InsertaVertPolilClip(vertPolilClip* ins, vertPolilClip* extremoIni, vertPolilClip* extremoFin); /******************************************************************************/ /******************************************************************************/ /** \brief Cuenta el número de vértices originales que hay en una polilínea almacenada como una lista doblemente enlazada de elementos \ref _vertPolilClip. \param[in] poli Polilínea, almacenado como una lista doblemente enlazada de elementos \ref _vertPolilClip. Sólo se tienen en cuenta los vértices originales de la polilínea, que son todos aquéllos cuyo campo _vertPolilClip::orig es distinto de 0. \return Número de vértices originales almacenados. \note Esta función no comprueba si la variable \em poli es una polilínea correctamente almacenada. \date 04 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ size_t NumeroVertOrigPolilClip(vertPolilClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Cuenta el número total de vértices que hay en una polilínea almacenada como una lista doblemente enlazada de elementos \ref _vertPolilClip. \param[in] poli Polilínea, almacenado como una lista doblemente enlazada de elementos \ref _vertPolilClip. Se tienen en cuenta todos los vértices. \return Número total de vértices almacenados. \note Esta función no comprueba si la variable \em poli es una polilínea correctamente almacenada. \date 04 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ size_t NumeroVertPolilClip(vertPolilClip* poli); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza el paso número 1 del algoritmo de recorte de polilíneas, que consiste en el cálculo de los puntos de intersección de la polilínea de trabajo con el polígono de recorte. Este paso está inspirado en el primer paso del algoritmo de Greiner-Hormann. \param[in,out] poli Polilínea de trabajo, representada como una lista doblemente enlazada de elementos \ref _vertPolilClip. Al término de la ejecución de la función se le han añadido los puntos de intersección con el polígono de recorte y se han asignado los valores correctos al campo _vertPolilClip::pos de cada vértice. \param[in] poliRec Polígono de recorte, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[out] nIntersec Número de intersecciones (intersecciones propiamente dichas y puntos en el borde del polígono) calculadas. \return Variable de estado. Dos posibilidades: - #GEOC_ERR_NO_ERROR: Todo ha ido bien. - #GEOC_ERR_ASIG_MEMORIA: Ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si las variables \em polil y \em poliRec son estructuras correctamente almacenadas. \note El polígono \em poliRec puede provenir de una operación booleana previa entre polígonos, ya que sólo se recorrerán sus vértices originales, que serán aquéllos cuyo campo _vertPoliClip::interseccion valga 0. \date 06 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ int Paso1Recpolil(vertPolilClip* poli, vertPoliClip* poliRec, size_t* nIntersec); /******************************************************************************/ /******************************************************************************/ /** \brief Realiza el paso número 2 del algoritmo de recorte de polilíneas, que consiste en la generación de lss polilíneas resultado. \param[in] poli Polilínea a recortar, representada como una lista doblemente enlazada de elementos \ref _vertPolilClip, tal y como sale de la función \ref Paso1Recpolil. \param[in] op Identificador de la operación a realizar. Ha de ser un elemento del tipo enumerado #GEOC_OP_BOOL_POLIL. \return Estructura \ref polil con las polilíneas resultado de la operación. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si la variable \em polil es una polilínea correctamente almacenada. \date 06 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ polil* Paso2Recpolil(vertPolilClip* poli, const enum GEOC_OP_BOOL_POLIL op); /******************************************************************************/ /******************************************************************************/ /** \brief Recorta una polilínea según un polígono de recorte. \param[in,out] poli Polilínea de trabajo, representada como una lista doblemente enlazada de elementos \ref _vertPolilClip. Al término de la ejecución de la función se le han añadido los puntos de intersección con el polígono de recorte y se han asignado los valores correctos al campo _vertPolilClip::pos de cada vértice. \param[in] poliRec Polígono de recorte, representado como una lista doblemente enlazada de elementos \ref _vertPoliClip. \param[in] op Identificador de la operación a realizar. Ha de ser un elemento del tipo enumerado #GEOC_OP_BOOL_POLIL. Varias posibilidades: - #GeocOpBoolDentro: Calcula la porción de \em poli que está dentro \em poliRec. - #GeocOpBoolFuera: Calcula la porción de \em poli que está fuera \em poliRec. \param[out] nIntersec Número de intersecciones calculadas. \return Estructura \ref polil con las polilíneas resultado de la operación. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si las variables \em poli y \em poliRec son estructuras correctamente almacenadas. \note Esta función no comprueba internamente si \em op pertenece al tipo enumerado #GEOC_OP_BOOL_POLIL. Si se introduce un valor no perteneciente al tipo, se realiza la operación #GeocOpBoolDentro. \note Esta función asume que los puntos de borde pertenecen al interior del polígono de recorte. \note Esta función asume que los puntos de borde sólo pertenecen al exterior del polígono de recorte cuando son principio o final de polilínea recortada. \date 06 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ polil* RecortaPolil(vertPolilClip* poli, vertPoliClip* poliRec, const enum GEOC_OP_BOOL_POLIL op, size_t* nIntersec); /******************************************************************************/ /******************************************************************************/ /** \brief Recorta múltiples polilíneas según múltiples polígonos de recorte. \param[in] poli Estructura \ref polil que almacena las polilíneas de trabajo. \param[in] poliRec Estructura \ref polig que almacena los polígonos de recorte. \param[in] op Identificador de la operación a realizar. Ha de ser un elemento del tipo enumerado #GEOC_OP_BOOL_POLIL. Varias posibilidades: - #GeocOpBoolDentro: Calcula la porción de las polilíneas almacenadas en \em poli que están dentro de los polígonos almacenados en \em poliRec. - #GeocOpBoolFuera: Calcula la porción de las polilíneas almacenadas en \em poli que están fuera de los polígonos almacenados en \em poliRec. \param[out] nIntersec Número total de intersecciones calculadas entre todas las polilíneas con todos los polígonos. \return Estructura \ref polil con las polilíneas resultado de las operaciones. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función realiza la operación \em op con todas las combinaciones posibles de polilíneas y polígonos. Es decir, se recorren todas las polilíneas y con cada una de ellas se realiza la operación \em op con cada polígono almacenado en \em poliRec. \note Esta función no comprueba si las variables \em poli y \em poliRec son estructuras correctamente almacenadas. \note Esta función no comprueba internamente si \em op pertenece al tipo enumerado #GEOC_OP_BOOL_POLIL. Si se introduce un valor no perteneciente al tipo, se realiza la operación #GeocOpBoolDentro. \note Esta función asume que los puntos de borde pertenecen al interior de los polígonos de recorte. \note Esta función asume que los puntos de borde sólo pertenecen al exterior de los polígonos de recorte cuando son principio o final de polilínea recortada. \date 06 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ polil* RecortaPolilMult(const polil* poli, const polig* poliRec, const enum GEOC_OP_BOOL_POLIL op, size_t* nIntersec); /******************************************************************************/ /******************************************************************************/ /** \brief Crea una estructura \ref polil a partir de todos los vértices de una polilínea almacenada como una lista doblemente enlazada de elementos \ref _vertPolilClip. \param[in] poli Polilínea de trabajo, representada como una lista doblemente enlazada de elementos \ref _vertPolilClip. El puntero pasado ha de apuntar al primer elemento de la polilínea (no se controla internamente). \return Estructura \ref polil que representa la polilínea. Si se devuelve \p NULL ha ocurrido un error de asignación de memoria. \note Esta función no comprueba si la variable \em poli es una polilínea correctamente almacenada. \note Esta función realiza una copia en memoria de las coordenadas de los vértices de la estructura \em poli a la estructura de salida. \date 06 de junio de 2011: Creación de la función. \todo Esta función no está probada. */ polil* CreaPolilPolilClip(vertPolilClip* poli); /******************************************************************************/ /******************************************************************************/ #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; */ geometry/src/octclip/recpolil.c0000755000175000017500000017236012035672422016467 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file recpolil.c \brief Definición funciones para el recorte de polilíneas por medio de polígonos. \author José Luis García Pallero, jgpallero@gmail.com \date 05 de junio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/recpolil.h" /******************************************************************************/ /******************************************************************************/ vertPolilClip* CreaVertPolilClip(const double x, const double y, vertPolilClip* anterior, vertPolilClip* siguiente, const char orig, const char pos, const double alfa) { //variable de salida (nuevo vértice) vertPolilClip* nuevoVert=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos memoria para el nuevo vértice nuevoVert = (vertPolilClip*)malloc(sizeof(vertPolilClip)); //comprobamos los posibles errores if(nuevoVert==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos los vértices anterior y posterior nuevoVert->anterior = anterior; nuevoVert->siguiente = siguiente; //si anterior es un vértice bueno if(anterior!=NULL) { //lo apuntamos al vértice creado nuevoVert->anterior->siguiente = nuevoVert; } //si siguiente es un vértice bueno if(siguiente!=NULL) { //indicamos que el vértice creado es el anterior nuevoVert->siguiente->anterior = nuevoVert; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos el resto de campos nuevoVert->x = x; nuevoVert->y = y; nuevoVert->orig = orig; nuevoVert->pos = pos; nuevoVert->alfa = alfa; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return nuevoVert; } /******************************************************************************/ /******************************************************************************/ vertPolilClip* CreaPolilClip(const double* x, const double* y, const size_t nCoor, const size_t incX, const size_t incY) { //índice para recorrer bucles size_t i=0; //variable auxiliar de posición size_t posIni=0; //otra variable auxiliar int hayVert=0; //estructura auxiliar vertPolilClip* aux=NULL; //variable de salida vertPolilClip* poli=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //buscamos el primer punto que sea distinto de NaN for(i=0;isiguiente; //liberamos la memoria free(aux); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ vertPolilClip* ReiniciaPolilClip(vertPolilClip* poli) { //estructura que apunta al espacio en memoria a liberar vertPolilClip* borra=NULL; //estructura auxiliar vertPolilClip* aux=NULL; //estructura de salida vertPolilClip* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar aux = poli; //comprobamos una posible salida rápida if(aux==NULL) { //salimos de la función return NULL; } //buscamos para la estructura de salida el primer vértice original while(aux!=NULL) { //comprobamos si estamos ante un vértice bueno if(aux->orig) { //asignamos la variable de salida sal = aux; //salimos del bucle break; } //siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //volvemos a inicializar la variable auxiliar aux = poli; //mientras la variable de trabajo no apunte a NULL while(aux!=NULL) { //comprobamos si estamos ante un vértice a borrar if(aux->orig==0) { //lo almacenamos en la estructura de borrado borra = aux; //actualizamos el puntero de vértice siguiente if(aux->anterior!=NULL) { //cuando el vértice a borrar no es el primero de la lista aux->anterior->siguiente = aux->siguiente; } else if(aux->siguiente!=NULL) { //cuando el vértice a borrar es el primero de la lista aux->siguiente->anterior = NULL; } //actualizamos el puntero de vértice anterior if(aux->siguiente!=NULL) { //cuando el vértice a borrar no es el último de la lista aux->siguiente->anterior = aux->anterior; } else if(aux->anterior!=NULL) { //cuando el vértice a borrar es el último de la lista aux->anterior->siguiente = NULL; } //apuntamos al siguiente elemento aux = aux->siguiente; //liberamos la memoria free(borra); } else { //reinicializamos el resto de miembros, menos las coordenadas //originales y el identificador de vértice original aux->pos = GEOC_PTO_FUERA_POLIG; aux->alfa = 0.0; //siguiente elemento aux = aux->siguiente; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ vertPolilClip* SiguienteVertOrigPolilClip(vertPolilClip* vert) { //variable de salida, que inicializamos con la dirección de entrada vertPolilClip* sal=vert; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //si estamos ante un vértice original, pasamos al siguiente if((sal!=NULL)&&sal->orig) { //apuntamos al siguiente vértice sal = sal->siguiente; } //vamos rechazando vérties no originales (el bucle se para cuando llegamos //al final o a un vértice que no es original) while((sal!=NULL)&&(sal->orig==0)) { //pasamos al siguiente vértice sal = sal->siguiente; } //si hemos llegado a un vértice que no es original, apuntamos a NULL if((sal!=NULL)&&(sal->orig==0)) { //asignamos NULL sal = NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ void InsertaVertPolilClip(vertPolilClip* ins, vertPolilClip* extremoIni, vertPolilClip* extremoFin) { //estructura auxiliar vertPolilClip* aux=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el vértice auxiliar como el extremo inicial pasado aux = extremoIni; //mientras no lleguemos al extremo final y el punto a insertar esté más //lejos del origen que el punto de trabajo while((aux!=extremoFin)&&((aux->alfa)<=(ins->alfa))) { //avanzamos al siguiente vértice aux = aux->siguiente; } //insertamos el punto y ordenamos los punteros de vértices anterior y //posterior ins->siguiente = aux; ins->anterior = aux->anterior; ins->anterior->siguiente = ins; ins->siguiente->anterior = ins; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ size_t NumeroVertOrigPolilClip(vertPolilClip* poli) { //estructura auxiliar vertPolilClip* aux=NULL; //variable de salida size_t num=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //comprobamos si estamos ante un vértice original if(aux->orig) { //si no es un vértice original, nos posicionamos en el siguiente que sí //lo sea aux = SiguienteVertOrigPolilClip(aux); } //mientras no lleguemos al final while(aux!=NULL) { //aumentamos el contador de vértices originales num++; //nos posicionamos en el siguiente vértice original aux = SiguienteVertOrigPolilClip(aux); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return num; } /******************************************************************************/ /******************************************************************************/ size_t NumeroVertPolilClip(vertPolilClip* poli) { //estructura auxiliar vertPolilClip* aux=NULL; //variable de salida size_t num=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //mientras no lleguemos al final while(aux!=NULL) { //aumentamos el contador de vértices num++; //nos posicionamos en el siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return num; } /******************************************************************************/ /******************************************************************************/ int Paso1Recpolil(vertPolilClip* poli, vertPoliClip* poliRec, size_t* nIntersec) { //estructuras auxiliares que apuntan a los elementos pasados vertPolilClip* auxA=NULL; vertPoliClip* auxC=NULL; //estructuras auxiliares para trabajar con el siguiente vértice vertPolilClip* auxB=NULL; vertPoliClip* auxD=NULL; //vértices de intersección a insertar vertPolilClip* insPolil=NULL; //coordenadas de la intersección de dos segmentos double xI=0.0,yI=0.0; //longitud de segmento y parámetro alfa double lon=0.0,alfa=0.0; //código de intersección de segmentos int intersec=0; //variable auxiliar int nuevoPunto=0; //variable de salida int salida=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el número de intersecciones a 0 *nIntersec = 0; //EL PRIMER PASO DEL ALGORITMO DE RECORTE DE POLILÍNEAS ES EL CÁLCULO DE //TODOS LOS PUNTOS DE INTERSECCIÓN ENTRE LOS POLÍGONOS //recorremos los vértices de la polilínea for(auxA=poli;auxA->siguiente!=NULL;auxA=auxA->siguiente) { //sólo trabajamos si el vértice es original if(auxA->orig) { //recorremos los vértices del polígono de recorte for(auxC=poliRec;auxC->siguiente!=NULL;auxC=auxC->siguiente) { //sólo trabajamos si el vértice es original (esto hace que //podamos trabajar con un polígono proveniente de una operación //booleana previa entre polígonos if(auxC->interseccion==0) { //siguiente vértice de los segmentos auxB = SiguienteVertOrigPolilClip(auxA); auxD = SiguienteVertOrigPoliClip(auxC); //calculamos la intersección de los segmentos intersec = IntersecSegmentos2D(auxA->x,auxA->y,auxB->x, auxB->y,auxC->x,auxC->y, auxD->x,auxD->y,&xI,&yI); //comprobamos la posición relativa del primer punto del //segmento de la polilínea con respecto al polígono //esta función sólo marca dentro o fuera auxA->pos = (char)PtoEnPoliClip(auxA->x,auxA->y,poliRec); //comprobamos si el segmento de la polilínea contiene al //último punto de ésta, por lo que el bucle se acabará aquí if(auxB->siguiente==NULL) { //comprobamos la posición relativa del último punto auxB->pos = (char)PtoEnPoliClip(auxB->x,auxB->y, poliRec); } //comprobamos si hay que aumentar el contador de //intersecciones if(intersec!=GEOC_SEG_NO_INTERSEC) { //aumentamos el contador de intersecciones (*nIntersec)++; } //comprobamos el tipo de intersección if(intersec==GEOC_SEG_INTERSEC) { //INTERSECCIÓN LIMPIA //calculamos la longitud del segmento de la polilínea lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y); //calculamos los parámetros alfa alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon; //creamos el nuevo vértice a insertar insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0, (char)GEOC_PTO_BORDE_POLIG, alfa); //comprobamos los posibles errores if(insPolil==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //añadimos el punto de intersección InsertaVertPolilClip(insPolil,auxA,auxB); } else if(intersec==GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN) { //EL EXTREMO DE UN SEGMENTO TOCA AL OTRO SEGMENTO, PERO //LOS SEGMENTOS NO SON COLINEALES //comprobamos si el extremo que toca es el inicial del //segmento de la polilínea if((xI==auxA->x)&&(yI==auxA->y)) { //el primer punto del segmento está en el borde auxA->pos = (char)GEOC_PTO_BORDE_POLIG; } else if((xI!=auxB->x)||(yI!=auxB->y)) { //el extremo que toca es del segmento del polígono y //no toca al punto final del segmento de la //polilínea //calculamos la longitud del segmento de la //polilínea lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y); //calculamos los parámetros alfa alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon; //creamos el nuevo vértice a insertar insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0, (char)GEOC_PTO_BORDE_POLIG, alfa); //comprobamos los posibles errores if(insPolil==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //añadimos el punto de intersección InsertaVertPolilClip(insPolil,auxA,auxB); } else { //comprobamos si estamos ante el segmento que //contiene al último punto de la polilínea if(auxB->siguiente==NULL) { //el último punto del segmento está en el borde auxB->pos = (char)GEOC_PTO_BORDE_POLIG; } else { //disminuimos el contador de intersecciones, ya //que esta se detectará en la siguiente vuelta //del bucle (*nIntersec)--; } } } else if(intersec==GEOC_SEG_INTERSEC_EXTREMO_COLIN) { //LOS SEGMENTOS SON COLINEALES PERO SÓLO SE TOCAN EN EL //EXTREMO //comprobamos si el extremo que toca es el primero if((xI==auxA->x)&&(yI==auxA->y)) { //el primer punto del segmento está en el borde auxA->pos = (char)GEOC_PTO_BORDE_POLIG; } else { //comprobamos si estamos ante el segmento que //contiene al último punto de la polilínea if(auxB->siguiente==NULL) { //el último punto del segmento está en el borde auxB->pos = (char)GEOC_PTO_BORDE_POLIG; } else { //disminuimos el contador de intersecciones, ya //que esta se detectará en la siguiente vuelta //del bucle (*nIntersec)--; } } } else if(intersec==GEOC_SEG_INTERSEC_MISMO_SEG) { //AMBOS SEGMENTOS SON EL MISMO //el primer punto del segmento está en el borde auxA->pos = (char)GEOC_PTO_BORDE_POLIG; //comprobamos si estamos ante el segmento que contiene //al último punto de la polilínea if(auxB->siguiente==NULL) { //aumentamos el contador de intersecciones (*nIntersec)++; //el último punto del segmento está en el borde auxB->pos = (char)GEOC_PTO_BORDE_POLIG; } } else if(intersec==GEOC_SEG_INTERSEC_COLIN) { //LOS SEGMENTOS TIENEN MÁS DE UN PUNTO EN COMÚN, PERO NO //SON EL MISMO //comprobamos si el extremo inicial está tocando el //polígono o no if((xI==auxA->x)&&(yI==auxA->y)) { //el primer punto del segmento está en el borde auxA->pos = (char)GEOC_PTO_BORDE_POLIG; //identificador de nuevo punto nuevoPunto = 0; //comprobamos si alguno de los extremos del segmento //del polígono está dentro del segmento de la //polilínea if(PuntoEntreDosPuntos2DColin(auxC->x,auxC->y, auxA->x,auxA->y, auxB->x,auxB->y)) { //nuevo punto nuevoPunto = 1; //coordenadas del punto intersección xI = auxC->x; yI = auxC->y; } else if(PuntoEntreDosPuntos2DColin(auxD->x,auxD->y, auxA->x,auxA->y, auxB->x,auxB->y)) { //nuevo punto nuevoPunto = 1; //coordenadas del punto intersección xI = auxD->x; yI = auxD->y; } //comprobamos si hay que añadir el nuevo punto if(nuevoPunto) { //aumentamos el contador de intersecciones (*nIntersec)++; //calculamos la longitud del segmento de la //polilínea lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y); //calculamos los parámetros alfa alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon; //creamos el nuevo vértice a insertar insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0, (char)GEOC_PTO_BORDE_POLIG, alfa); //comprobamos los posibles errores if(insPolil==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //añadimos el punto de intersección InsertaVertPolilClip(insPolil,auxA,auxB); } //comprobamos si estamos ante el segmento que //contiene al último punto de la polilínea if(auxB->siguiente==NULL) { //comprobamos si el último punto del segmento //de la polilínea está contenido en el segmento //del polígono if(PuntoEntreDosPuntos2DColin(auxB->x,auxB->y, auxC->x,auxC->y, auxD->x,auxD->y)) { //aumentamos el contador de intersecciones (*nIntersec)++; //indicamos que el último punto del segmento //de la polilínea está en el borde auxB->pos = (char)GEOC_PTO_BORDE_POLIG; } } } else { //comprobamos si el vértice a añadir es el extremo //final del segmento del polígono (la función //devuelve las coordenadas del extremo final del //segmento de la polilínea if((xI==auxB->x)&&(yI==auxB->y)) { //asignamos las coordenadas de salida correctas xI = auxD->x; yI = auxD->y; } //calculamos la longitud del segmento de la //polilínea lon = Dist2D(auxA->x,auxA->y,auxB->x,auxB->y); //calculamos los parámetros alfa alfa = Dist2D(auxA->x,auxA->y,xI,yI)/lon; //creamos el nuevo vértice a insertar insPolil = CreaVertPolilClip(xI,yI,NULL,NULL,0, (char)GEOC_PTO_BORDE_POLIG, alfa); //comprobamos los posibles errores if(insPolil==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //añadimos el punto de intersección InsertaVertPolilClip(insPolil,auxA,auxB); //comprobamos si estamos ante el segmento que //contiene al último punto de la polilínea if(auxB->siguiente==NULL) { //aumentamos el contador de intersecciones (*nIntersec)++; //indicamos que el último punto del segmento de //la polilínea está en el borde auxB->pos = (char)GEOC_PTO_BORDE_POLIG; } } } } } } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ polil* Paso2Recpolil(vertPolilClip* poli, const enum GEOC_OP_BOOL_POLIL op) { //estructura auxiliar vertPolilClip* aux=NULL; //vectores de coordenadas de los vértices del resultado double* x=NULL; double* y=NULL; //número de elementos de los vectores x e y size_t nPtos=0; //número de elementos para los que ha sido asignada memoria size_t nElem=0; //variable de estado int estado=GEOC_ERR_NO_ERROR; //polilínea de salida polil* resultado=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //chequeamos una posible salida rápida porque la polilínea sea NULL if(poli==NULL) { //creamos la estructura vacía resultado = IniciaPolilVacia(); //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //salimos de la función return resultado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //distinguimos entre las dos operaciones //por defecto, recorte if(op!=GeocOpBoolFuera) { //vamos recorriendo vértices de la polilínea do { //comprobamos si el vértice es del borde o de dentro del polígono if(aux->pos==GEOC_PTO_DENTRO_POLIG) { //un punto de dentro del polígono siempre pertenece a la //polilínea recortada //no hace falta asignar los elementos NaN de separación de //polilíneas, que ya se añaden cuando de trabaja con un punto de //borde //aumentamos el número de elementos almacenados en los vectores //de coordenadas nPtos++; //comprobamos si hay que reasignar memoria if(nPtos>nElem) { //aumentamos el número de elementos nElem += GEOC_RECPOLIL_BUFFER_PTOS; //reasignamos memoria x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos los posibles errores if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //asignamos las coordenadas del vértice x[nPtos-1] = aux->x; y[nPtos-1] = aux->y; } else if(aux->pos==GEOC_PTO_BORDE_POLIG) { //comprobamos la situación de los vértices anterior y siguiente //para la posible reasignación de memoria if((aux->anterior==NULL)||(aux->siguiente==NULL)|| (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)|| (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG)) { //este es un vértice de comienzo o fin de una polilínea, por //lo que necesitamos memoria para las coordenadas y el //marcador NaN nPtos += 2; } else { //este vértice pertenece al interior del polígono nPtos++; } //comprobamos si hay que reasignar memoria if(nPtos>nElem) { //aumentamos el número de elementos nElem += GEOC_RECPOLIL_BUFFER_PTOS; //reasignamos memoria x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos los posibles errores if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //comprobamos de nuevo la situación de los vértices anterior y //posterior if((aux->anterior==NULL)|| (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)) { //el vértice es inicio de polilínea //asignamos los valores NaN de separación x[nPtos-2] = GeocNan(); y[nPtos-2] = GeocNan(); //asignamos las coordenadas del vértice x[nPtos-1] = aux->x; y[nPtos-1] = aux->y; } else if((aux->siguiente==NULL)|| (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG)) { //el vértice es final de polilínea //asignamos las coordenadas del vértice x[nPtos-2] = aux->x; y[nPtos-2] = aux->y; //asignamos los valores NaN de separación x[nPtos-1] = GeocNan(); y[nPtos-1] = GeocNan(); } else { //el vértice pertenece a la polilínea recortada x[nPtos-1] = aux->x; y[nPtos-1] = aux->y; } } //avanzamos al siguiente vértice aux = aux->siguiente; }while(aux!=NULL); } else { //vamos recorriendo vértices de la polilínea do { //comprobamos si el vértice es del borde o de fuera del polígono if(aux->pos==GEOC_PTO_FUERA_POLIG) { //un punto de fuera del polígono siempre pertenece a la //polilínea exterior //no hace falta asignar los elementos NaN de separación de //polilíneas, que ya se añaden cuando de trabaja con un punto de //borde //aumentamos el número de elementos almacenados en los vectores //de coordenadas nPtos++; //comprobamos si hay que reasignar memoria if(nPtos>nElem) { //aumentamos el número de elementos nElem += GEOC_RECPOLIL_BUFFER_PTOS; //reasignamos memoria x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos los posibles errores if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //asignamos las coordenadas del vértice x[nPtos-1] = aux->x; y[nPtos-1] = aux->y; } else if(aux->pos==GEOC_PTO_BORDE_POLIG) { //comprobamos la situación de los vértices anterior y siguiente //para la posible reasignación de memoria if((aux->anterior!=NULL)&&(aux->siguiente!=NULL)&& (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)&& (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG)) { //este vértice pertenece al exterior del polígono nPtos++; } else if(((aux->anterior==NULL)|| (aux->anterior->pos!=GEOC_PTO_FUERA_POLIG))&& (aux->siguiente!=NULL)&& (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG)) { //este es un vértice de comienzo de una polilínea, por lo //que necesitamos memoria para las coordenadas y el marcador //NaN nPtos += 2; } else if(((aux->siguiente==NULL)|| (aux->siguiente->pos!=GEOC_PTO_FUERA_POLIG))&& (aux->anterior!=NULL)&& (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)) { //este es un vértice de fin de una polilínea, por lo que //necesitamos memoria para las coordenadas y el marcador NaN nPtos += 2; } //comprobamos si hay que reasignar memoria if(nPtos>nElem) { //aumentamos el número de elementos nElem += GEOC_RECPOLIL_BUFFER_PTOS; //reasignamos memoria x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos los posibles errores if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //comprobamos de nuevo la situación de los vértices anterior y //posterior if((aux->anterior!=NULL)&&(aux->siguiente!=NULL)&& (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)&& (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG)) { //el vértice pertenece a la polilínea recortada x[nPtos-1] = aux->x; y[nPtos-1] = aux->y; } else if(((aux->anterior==NULL)|| (aux->anterior->pos!=GEOC_PTO_FUERA_POLIG))&& (aux->siguiente!=NULL)&& (aux->siguiente->pos==GEOC_PTO_FUERA_POLIG)) { //el vértice es inicio de polilínea //asignamos los valores NaN de separación x[nPtos-2] = GeocNan(); y[nPtos-2] = GeocNan(); //asignamos las coordenadas del vértice x[nPtos-1] = aux->x; y[nPtos-1] = aux->y; } else if(((aux->siguiente==NULL)|| (aux->siguiente->pos!=GEOC_PTO_FUERA_POLIG))&& (aux->anterior!=NULL)&& (aux->anterior->pos==GEOC_PTO_FUERA_POLIG)) { //el vértice es final de polilínea //asignamos las coordenadas del vértice x[nPtos-2] = aux->x; y[nPtos-2] = aux->y; //asignamos los valores NaN de separación x[nPtos-1] = GeocNan(); y[nPtos-1] = GeocNan(); } } //avanzamos al siguiente vértice aux = aux->siguiente; }while(aux!=NULL); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos la estructura de salida resultado = CreaPolil(x,y,nPtos,1,1,&estado); //comprobamos los posibles errores if(resultado==NULL) { //liberamos la memoria asignada free(x); free(y); //comprobamos el error if(estado==GEOC_ERR_ASIG_MEMORIA) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); } else { //mensaje de error GEOC_ERROR("Error en la llamada a 'CreaPolil()'\nEste error no " "puede producirse aquí porque los NaN deben estar " "bien puestos"); } //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria utilizada free(x); free(y); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return resultado; } /******************************************************************************/ /******************************************************************************/ polil* RecortaPolil(vertPolilClip* poli, vertPoliClip* poliRec, const enum GEOC_OP_BOOL_POLIL op, size_t* nIntersec) { //identificador de error int idError=GEOC_ERR_NO_ERROR; //polilínea de salida de salida polil* resultado=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //PRIMER PASO DEL ALGORITMO: CÁLCULO DE TODOS LOS PUNTOS DE INTERSECCIÓN //ENTRE LA POLILÍNEA Y EL POLÍGONO //calculamos los puntos de intersección idError = Paso1Recpolil(poli,poliRec,nIntersec); //comprobamos los posibles errores if(idError==GEOC_ERR_ASIG_MEMORIA) { //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'Paso1Recpolil'"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si no hay intersecciones if(!(*nIntersec)) { //comprobamos las posibles situaciones relativas entre la polilínea y el //polígono que pueden producir cero intersecciones if(PtoEnPoliClip(poli->x,poli->y,poliRec)==GEOC_PTO_FUERA_POLIG) { //LA POLILÍNEA ESTÁ FUERA DEL POLÍGONO DE RECORTE //distinguimos las operaciones (por defecto, dentro) if(op!=GeocOpBoolFuera) { //el resultado es una polilínea vacía resultado = CreaPolilPolilClip(NULL); } else { //el resultado es la polilínea original resultado = CreaPolilPolilClip(poli); } } else { //LA POLILÍNEA ESTÁ DENTRO DEL POLÍGONO DE RECORTE //distinguimos las operaciones (por defecto, dentro) if(op!=GeocOpBoolFuera) { //el resultado es la polilínea original resultado = CreaPolilPolilClip(poli); } else { //el resultado es una polilínea vacía resultado = CreaPolilPolilClip(NULL); } } //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //salimos de la función return resultado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //realizamos la operación si hay alguna intersección resultado = Paso2Recpolil(poli,op); //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'Paso2Recpolil'"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return resultado; } /******************************************************************************/ /******************************************************************************/ polil* RecortaPolilMult(const polil* poli, const polig* poliRec, const enum GEOC_OP_BOOL_POLIL op, size_t* nIntersec) { //índices para recorrer bucles size_t i=0,j=0; //variable de posición size_t pos=0; //posición de un rectángulo con respecto a otro int pr=0; //número de intersecciones auxiliar size_t nInt=0; //variable de error int estado=GEOC_ERR_NO_ERROR; //listas de trabajo vertPolilClip* polilClip=NULL; vertPoliClip* poligClip=NULL; //polilínea auxiliar polil* polilAux=NULL; //variable de salida polil* resultado=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el número total de intersecciones *nIntersec = 0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la variable de salida resultado = IniciaPolilVacia(); //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos las polilíneas a recortar for(i=0;inPolil;i++) { //dirección de inicio de los vértices de la polilínea pos = poli->posIni[i]; //creamos la polilínea a recortar de trabajo polilClip = CreaPolilClip(&(poli->x[pos]),&(poli->y[pos]), poli->nVert[i],1,1); //comprobamos los posibles errores if(polilClip==NULL) { //liberamos la memoria asignada hasta ahora LibMemPolil(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //recorremos los polígonos de recorte for(j=0;jnPolig;j++) { //comprobamos si la polilínea y el polígono tienen definidos sus //límites if((poli->hayLim)&&(poliRec->hayLim)) { //comprobamos si los restángulos que encierran a la polilínea y //al polígono son disjuntos o no pr = RectDisjuntos(poli->xMin[i],poli->xMax[i],poli->yMin[i], poli->yMax[i], poliRec->xMin[j],poliRec->xMax[j], poliRec->yMin[j],poliRec->yMax[j]); //comprobamos los casos particulares si los rectángulos son //disjuntos if(pr&&(op==GeocOpBoolDentro)) { //si buscamos la parte de la polilínea que cae dentro del //polígono, no se añade nada //vamos a la siguiente vuelta del bucle continue; } else if(pr&&(op==GeocOpBoolFuera)) { //si buscamos la parte de la polilínea que cae fuera del //polígono, se añade la polilínea entera estado = AnyadeDatosPolil(resultado,&(poli->x[pos]), &(poli->y[pos]),poli->nVert[i],1, 1); //comprobamos los posibles errores, que sólo pueden ser de //asignación de memoria if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la posible memoria asignada hasta ahora LibMemPolilClip(polilClip); LibMemPolil(resultado); //lanzamos el mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //vamos a la siguiente vuelta del bucle continue; } } //dirección de inicio de los vértices del polígono de recorte pos = poliRec->posIni[j]; //creamos el polígono de recorte de trabajo poligClip = CreaPoliClip(&(poliRec->x[pos]),&(poliRec->y[pos]), poliRec->nVert[j],1,1); //comprobamos los posibles errores if(poligClip==NULL) { //liberamos la memoria asignada hasta ahora LibMemPolilClip(polilClip); LibMemPolil(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //recortamos polilAux = RecortaPolil(polilClip,poligClip,op,&nInt); //comprobamos los posibles errores if(polilAux==NULL) { //liberamos la posible memoria asignada hasta ahora LibMemPolilClip(polilClip); LibMemPoliClip(poligClip); LibMemPolil(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //sumamos el número de intersecciones (*nIntersec) += nInt; //añadimos la polilínea recortada a la variable de salida if(AnyadePolilPolil(resultado,polilAux)==GEOC_ERR_ASIG_MEMORIA) { //liberamos la posible memoria asignada hasta ahora LibMemPolilClip(polilClip); LibMemPoliClip(poligClip); LibMemPolil(polilAux); LibMemPolil(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //liberamos la memoria asignada al polígono de esta vuelta del bucle LibMemPoliClip(poligClip); //liberamos la memoria asignada a la polilínea auxiliar LibMemPolil(polilAux); //reinicializamos la polilínea a recortar polilClip = ReiniciaPolilClip(polilClip); } //liberamos la memoria asignada a la polilínea de esta vuelta del bucle LibMemPolilClip(polilClip); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return resultado; } /******************************************************************************/ /******************************************************************************/ polil* CreaPolilPolilClip(vertPolilClip* poli) { //índice para recorrer bucles size_t i=0; //número de elementos size_t nVert=0,nElem=0; //estructura auxiliar vertPolilClip* aux=poli; //variable de salida polil* result=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos la estructura vacía result = IniciaPolilVacia(); //comprobamos los posibles errores if(result==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contamos todos los vértices de la polilínea nVert = NumeroVertPolilClip(poli); //contemplamos una posible salida rápida if(nVert==0) { //devolvemos la estructura vacía return result; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //número de elementos de los vectores de coordenadas nElem = nVert+2; //asignamos memoria para los vectores de coordenadas de la estructura result->x = (double*)malloc(nElem*sizeof(double)); result->y = (double*)malloc(nElem*sizeof(double)); //asignamos memoria para los vectores de posición result->posIni = (size_t*)malloc(sizeof(size_t)); result->nVert = (size_t*)malloc(sizeof(size_t)); //comprobamos los posibles errores de asignación de memoria if((result->x==NULL)||(result->y==NULL)||(result->posIni==NULL)|| (result->nVert==NULL)) { //liberamos la posible memoria asignada LibMemPolil(result); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos el número de elementos de los vectores de coordenadas y de //polilíneas result->nElem = nElem; result->nPolil = 1; //asignamos la posición de inicio y el número de vértices result->posIni[0] = 1; result->nVert[0] = nVert; //asignamos los separadores de polilínea al principio y al final result->x[0] = GeocNan(); result->y[0] = GeocNan(); result->x[nElem-1] = GeocNan(); result->y[nElem-1] = GeocNan(); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos los vértices de la polilínea for(i=1;i<=nVert;i++) { //copio las coordenadas del vértice result->x[i] = aux->x; result->y[i] = aux->y; //siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return result; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/greiner.c0000644000175000017500000022772512035672422016314 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file greiner.c \brief Definición de funciones para el recorte de polígonos mediante el algoritmo de Greiner-Hormann (http://davis.wpi.edu/~matt/courses/clipping/). \author José Luis García Pallero, jgpallero@gmail.com \date 14 de mayo de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/greiner.h" /******************************************************************************/ /******************************************************************************/ vertPoliClip* CreaVertPoliClip(const double x, const double y, vertPoliClip* anterior, vertPoliClip* siguiente, vertPoliClip* vecino, const char ini, const char interseccion, const char entrada, const char visitado, const double alfa) { //variable de salida (nuevo vértice) vertPoliClip* nuevoVert=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos memoria para el nuevo vértice nuevoVert = (vertPoliClip*)malloc(sizeof(vertPoliClip)); //comprobamos los posibles errores if(nuevoVert==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos los vértices anterior y posterior nuevoVert->anterior = anterior; nuevoVert->siguiente = siguiente; //si anterior es un vértice bueno if(anterior!=NULL) { //lo apuntamos al vértice creado nuevoVert->anterior->siguiente = nuevoVert; } //si siguiente es un vértice bueno if(siguiente!=NULL) { //indicamos que el vértice creado es el anterior nuevoVert->siguiente->anterior = nuevoVert; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos el resto de campos nuevoVert->x = x; nuevoVert->y = y; nuevoVert->xP = x; nuevoVert->yP = y; nuevoVert->vecino = vecino; nuevoVert->ini = ini; nuevoVert->interseccion = interseccion; nuevoVert->entrada = entrada; nuevoVert->visitado = visitado; nuevoVert->alfa = alfa; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return nuevoVert; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* CreaPoliClip(const double* x, const double* y, const size_t nCoor, const size_t incX, const size_t incY) { //índice para recorrer bucles size_t i=0; //variables auxiliares de posición size_t posIni=0,posFin=0; //otra variable auxiliar int hayVert=0; //estructura auxiliar vertPoliClip* aux=NULL; //variable de salida vertPoliClip* poli=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //buscamos el primer punto que sea distinto de NaN for(i=0;isiguiente; //liberamos la memoria free(aux); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* ReiniciaPoliClip(vertPoliClip* poli) { //estructura que apunta al espacio en memoria a liberar vertPoliClip* borra=NULL; //estructura auxiliar vertPoliClip* aux=NULL; //estructura de salida vertPoliClip* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar aux = poli; //comprobamos una posible salida rápida if(aux==NULL) { //salimos de la función return NULL; } //buscamos para la estructura de salida el primer vértice que no sea una //intersección while(aux!=NULL) { //comprobamos si estamos ante un vértice bueno if(aux->interseccion==0) { //asignamos la variable de salida sal = aux; //salimos del bucle break; } //siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //volvemos a inicializar la variable auxiliar aux = poli; //mientras la variable de trabajo no apunte a NULL while(aux!=NULL) { //comprobamos si estamos ante un vértice a borrar if(aux->interseccion) { //lo almacenamos en la estructura de borrado borra = aux; //actualizamos el puntero de vértice siguiente if(aux->anterior!=NULL) { //cuando el vértice a borrar no es el primero de la lista aux->anterior->siguiente = aux->siguiente; } else if(aux->siguiente!=NULL) { //cuando el vértice a borrar es el primero de la lista aux->siguiente->anterior = NULL; } //actualizamos el puntero de vértice anterior if(aux->siguiente!=NULL) { //cuando el vértice a borrar no es el último de la lista aux->siguiente->anterior = aux->anterior; } else if(aux->anterior!=NULL) { //cuando el vértice a borrar es el último de la lista aux->anterior->siguiente = NULL; } //apuntamos al siguiente elemento aux = aux->siguiente; //liberamos la memoria free(borra); } else { //reinicializamos el resto de miembros, menos las coordenadas //originales y el identificador de primer elemento aux->xP = aux->x; aux->yP = aux->y; aux->vecino = NULL; aux->interseccion = 0; aux->entrada = 0; aux->visitado = 0; aux->alfa = 0.0; //siguiente elemento aux = aux->siguiente; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* ReiniciaVerticesPoliClip(vertPoliClip* poli) { //estructura auxiliar vertPoliClip* aux=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura de auxiliar con la dirección de entrada aux = poli; //mientras no lleguemos al final while(aux!=NULL) { //vamos poniendo a 0 el campo 'visitado' aux->visitado = 0; //vamos poniendo a 0 el campo 'entrada' aux->entrada = 0; //nos posicionamos en el siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return poli; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* SiguienteVertOrigPoliClip(vertPoliClip* vert) { //variable de salida, que inicializamos con la dirección de entrada vertPoliClip* sal=vert; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //si estamos ante un vértice original, pasamos al siguiente if((sal!=NULL)&&(sal->interseccion==0)) { //apuntamos al siguiente vértice sal = sal->siguiente; } //vamos rechazando intersecciones (el bucle se para cuando llegamos al final //o a un vértice que no es intersección) while((sal!=NULL)&&(sal->interseccion!=0)) { //pasamos al siguiente vértice sal = sal->siguiente; } //si hemos llegado a un vértice que no es original, apuntamos a NULL if((sal!=NULL)&&(sal->interseccion!=0)) { //asignamos NULL sal = NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* SiguienteIntersecNoVisitadaPoliClip(vertPoliClip* vert) { //variable de salida, que inicializamos con la dirección de entrada vertPoliClip* sal=vert; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //si estamos ante una intersección no visitada o ante el vértice original //del polígono, pasamos al siguiente vértice if((sal!=NULL)&& (((sal->interseccion!=0)&&(sal->visitado==0))||(sal->ini!=0))) { //apuntamos al siguiente vértice sal = sal->siguiente; } //vamos rechazando vértices originales e intersecciones visitadas: el bucle //se para cuando llegamos al final (si la lista no es circular), cuando //volvamos al principio (si la lista es circular) o cuando lleguemos a una //intersección no visitada while(((sal!=NULL)&&(sal->ini==0))&& ((sal->interseccion==0)|| ((sal->interseccion!=0)&&(sal->visitado!=0)))) { //pasamos al siguiente vértice sal = sal->siguiente; } //si hemos llegado a un vértice que no es una intersección no visitada o es //de nuevo el punto inicial (lista circular), apuntamos a NULL if((sal!=NULL)&& (((sal->interseccion!=0)&&(sal->visitado!=0))||(sal->ini!=0))) { //asignamos NULL sal = NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* UltimoVertPoliClip(vertPoliClip* poli) { //variable de salida, que inicializamos con la dirección de entrada vertPoliClip* sal=poli; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //sólo trabajamos si la entrada es distinta de NULL if(sal!=NULL) { //mientras el siguiente vértice sea distinto de NULL while(sal->siguiente!=NULL) { //avanzamos un vértice sal = sal->siguiente; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ void InsertaVertPoliClip(vertPoliClip* ins, vertPoliClip* extremoIni, vertPoliClip* extremoFin) { //estructura auxiliar vertPoliClip* aux=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el vértice auxiliar como el extremo inicial pasado aux = extremoIni; //mientras no lleguemos al extremo final y el punto a insertar esté más //lejos del origen que el punto de trabajo while((aux!=extremoFin)&&((aux->alfa)<=(ins->alfa))) { //avanzamos al siguiente vértice aux = aux->siguiente; } //insertamos el punto y ordenamos los punteros de vértices anterior y //posterior ins->siguiente = aux; ins->anterior = aux->anterior; ins->anterior->siguiente = ins; ins->siguiente->anterior = ins; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ vertPoliClip* CierraPoliClip(vertPoliClip* poli) { //estructura auxiliar vertPoliClip* aux=NULL; //variable de salida: último vértice de la lista original vertPoliClip* ultimo=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si se ha pasado NULL if(poli==NULL) { //salimos de la función return NULL; } //buscamos el último vértice de la lista original ultimo = UltimoVertPoliClip(poli); //almacenamos el penúltimo vértice en la estructura auxiliar aux = ultimo->anterior; //apuntamos el penúltimo vértice al primero aux->siguiente = poli; //le decimos al primer vértice cuál es el anterior aux->siguiente->anterior = aux; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return ultimo; } /******************************************************************************/ /******************************************************************************/ void AbrePoliClip(vertPoliClip* poli, vertPoliClip* ultimo) { //estructuras auxiliares vertPoliClip* aux=poli; vertPoliClip* ult=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //buscamos el vértice inicial while((aux!=NULL)&&(aux->ini==0)) { //pasamos al siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //último vértice ult = aux->anterior; //le decimos al falso último vértice cuál es el último verdadero ult->siguiente = ultimo; //ajustamos los parámetros del nuevo último vértice ultimo->anterior = ult; ultimo->siguiente = NULL; //le decimos al primer vértice que el anterior es NULL aux->anterior = NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int PtoEnPoliClip(const double x, const double y, vertPoliClip* poli) { //estructuras auxiliares vertPoliClip* aux=NULL; vertPoliClip* aux1=NULL; //coordenadas auxiliares double x1=0.0,y1=0.0,x2=0.0,y2=0.0; //variable de salida int c=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //comprobamos si no es un vértice original if(aux->interseccion!=0) { //nos posicionamos en el siguiente vértice original aux = SiguienteVertOrigPoliClip(aux); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //entramos en un bucle infinito while(1) { //nos posicionamos en el siguiente vértice original aux1 = SiguienteVertOrigPoliClip(aux); //sólo continuamos si el siguiente vértice no es NULL if(aux1!=NULL) { //extraemos las coordenadas de trabajo x1 = aux->xP; y1 = aux->yP; x2 = aux1->xP; y2 = aux1->yP; //actalizamos el vértice inicial de trabajo para la siguiente vuelta aux = aux1; //calculamos if(((y1>y)!=(y2>y))&&(x<(x2-x1)*(y-y1)/(y2-y1)+x1)) { c = !c; } } else { //salimos del bucle break; } } //asignamos el elemento de salida if(c) { //el punto está dentro del polígono c = GEOC_PTO_DENTRO_POLIG; } else { //el punto está fuera del polígono c = GEOC_PTO_FUERA_POLIG; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return c; } /******************************************************************************/ /******************************************************************************/ int PtoEnPoliClipVertice(const double x, const double y, vertPoliClip* poli) { //estructura auxiliar vertPoliClip* aux=NULL; //variable de salida, que inicializamos fuera del polígono int pos=GEOC_PTO_FUERA_POLIG; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //comprobamos si no es un vértice original if(aux->interseccion!=0) { //nos posicionamos en el siguiente vértice original aux = SiguienteVertOrigPoliClip(aux); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si el punto es un vértice while(aux!=NULL) { //comprobamos si las coordenadas coinciden if((aux->xP==x)&&(aux->yP==y)) { //indicamos que el punto es un vértice pos = GEOC_PTO_VERTICE_POLIG; //salimos del bucle break; } //nos posicionamos en el siguiente vértice original aux = SiguienteVertOrigPoliClip(aux); } //sólo continuamos si el punto no es un vértice if(pos!=GEOC_PTO_VERTICE_POLIG) { //calculamos la posición sin tener en cuenta el borde pos = PtoEnPoliClip(x,y,poli); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return pos; } /******************************************************************************/ /******************************************************************************/ size_t NumeroVertOrigPoliClip(vertPoliClip* poli) { //estructura auxiliar vertPoliClip* aux=NULL; //variable de salida size_t num=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //comprobamos si estamos ante un vértice original if(aux->interseccion!=0) { //si no es un vértice original, nos posicionamos en el siguiente que sí //lo sea aux = SiguienteVertOrigPoliClip(aux); } //mientras no lleguemos al final while(aux!=NULL) { //aumentamos el contador de vértices originales num++; //nos posicionamos en el siguiente vértice original aux = SiguienteVertOrigPoliClip(aux); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return num; } /******************************************************************************/ /******************************************************************************/ size_t NumeroVertPoliClip(vertPoliClip* poli) { //estructura auxiliar vertPoliClip* aux=NULL; //variable de salida size_t num=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar con la dirección de entrada aux = poli; //mientras no lleguemos al final while(aux!=NULL) { //aumentamos el contador de vértices num++; //nos posicionamos en el siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return num; } /******************************************************************************/ /******************************************************************************/ double CantPerturbMin(const double x, const double factor) { //valor absoluto del argumento de entrada double xAbs=fabs(x); //variable auxiliar double aux=0.0; //variable de salida, que inicializamos como el épsilon para el tipo de dato double sal=fabs(DBL_EPSILON); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //mientras la variable auxiliar sea igual a la de antrada (la primera vuelta //del bucle se ejecuta siempre) do { //escalamos la variable de salida sal *= factor; //sumamos el nuevo valor a la coordenada de entrada //esta suma es necesario realizarla aquí, en lugar de en la propia //comparación del while, para obligar al resultado a almacenarse en una //variable y evitar errores porque las variables intermedias de la //comparación puede que se almacenen en registros de más precisión que //el tipo de dato aux = xAbs+sal; }while(aux==xAbs); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ double PerturbaPuntoMin(const double x, const double factor) { //variable para almacenar un número seudoaleatorio int aleat=0; //cantidad perturbadora double perturb=0.0; //signo para multiplicar por la cantidad perturbadora double signo=0.0; //variable de salida double sal=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //plantamos la semilla para la función rand() srand((unsigned int)time(NULL)); //generamos el número seudoaleatorio aleat = rand(); //calculamos el signo para la multiplicación, basándonos en la paridad del //número seudoaleatorio generado: si es par vale 1 y si es impar -1 signo = (aleat%2) ? -1.0 : 1.0; //calculamos la cantidad perturbadora perturb = CantPerturbMin(x,factor); //perturbamos la coordenada sal = x+signo*perturb; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ int Paso1Greiner(vertPoliClip* poliBas, vertPoliClip* poliRec, const double facPer, size_t* nIntersec, size_t* nPerturb) { //estructuras auxiliares que apuntan a los polígonos pasados vertPoliClip* auxA=NULL; vertPoliClip* auxC=NULL; //estructuras auxiliares para trabajar con el siguiente vértice vertPoliClip* auxB=NULL; vertPoliClip* auxD=NULL; //vértices de intersección a insertar vertPoliClip* insBas=NULL; vertPoliClip* insRec=NULL; //coordenadas de la intersección de dos segmentos double xI=0.0,yI=0.0; //longitudes de segmentos y parámetros alfa double lonAB=0.0,lonCD=0.0,alfaAB=0.0,alfaCD=0.0; //código de intersección de segmentos int intersec=0; //variable de salida int salida=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el número de intersecciones a 0 *nIntersec = 0; //inicializamos el número de puntos perturbados a 0 *nPerturb = 0; //EL PRIMER PASO DEL ALGORITMO DE GREINER-HORMANN ES EL CÁLCULO DE TODOS LOS //PUNTOS DE INTERSECCIÓN ENTRE LOS POLÍGONOS //recorremos los vértices del polígono base for(auxA=poliBas;auxA->siguiente!=NULL;auxA=auxA->siguiente) { //sólo trabajamos si el vértice es original if(auxA->interseccion==0) { //recorremos los vértices del polígono de recorte for(auxC=poliRec;auxC->siguiente!=NULL;auxC=auxC->siguiente) { //sólo trabajamos si el vértice es original if(auxC->interseccion==0) { //siguiente vértice de los segmentos auxB = SiguienteVertOrigPoliClip(auxA); auxD = SiguienteVertOrigPoliClip(auxC); //calculamos la intersección de los segmentos intersec = IntersecSegmentos2D(auxA->xP,auxA->yP,auxB->xP, auxB->yP,auxC->xP,auxC->yP, auxD->xP,auxD->yP,&xI,&yI); //perturbamos las coordenadas de los extremos de los //segmentos mientras haya una intersección no limpia while((intersec!=GEOC_SEG_NO_INTERSEC)&& (intersec!=GEOC_SEG_INTERSEC)) { //distinguimos entre intersecciones donde sólo se toca //un extremo e intersecciones colineales donde se //comparte más de un punto if((intersec==GEOC_SEG_INTERSEC_EXTREMO_NO_COLIN)|| (intersec==GEOC_SEG_INTERSEC_EXTREMO_COLIN)) { if((xI==auxC->xP)&&(yI==auxC->yP)) { //perturbamos el extremo C auxC->xP = PerturbaPuntoMin(auxC->x,facPer); auxC->yP = PerturbaPuntoMin(auxC->y,facPer); //aumentamos el contador de puntos perturbados (*nPerturb)++; } else if((xI==auxD->xP)&&(yI==auxD->yP)) { //perturbamos el extremo D auxD->xP = PerturbaPuntoMin(auxD->x,facPer); auxD->yP = PerturbaPuntoMin(auxD->y,facPer); //aumentamos el contador de puntos perturbados (*nPerturb)++; } else { //si el punto de contacto es un extremo de AB y //los segmentos no son paralelos, perturbamos //todo el segmento CD auxC->xP = PerturbaPuntoMin(auxC->x,facPer); auxC->yP = PerturbaPuntoMin(auxC->y,facPer); auxD->xP = PerturbaPuntoMin(auxD->x,facPer); auxD->yP = PerturbaPuntoMin(auxD->y,facPer); //aumentamos el contador de puntos perturbados (*nPerturb) += 2; } } else if((intersec==GEOC_SEG_INTERSEC_MISMO_SEG)|| (intersec==GEOC_SEG_INTERSEC_COLIN)) { //perturbamos todo el segmento CD auxC->xP = PerturbaPuntoMin(auxC->x,facPer); auxC->yP = PerturbaPuntoMin(auxC->y,facPer); auxD->xP = PerturbaPuntoMin(auxD->x,facPer); auxD->yP = PerturbaPuntoMin(auxD->y,facPer); //aumentamos el contador de puntos perturbados (*nPerturb) += 2; } //volvemos a calcular la intersección de los segmentos intersec = IntersecSegmentos2D(auxA->xP,auxA->yP, auxB->xP,auxB->yP, auxC->xP,auxC->yP, auxD->xP,auxD->yP, &xI,&yI); } //comprobamos si los segmentos se cortan limpiamente if(intersec==GEOC_SEG_INTERSEC) { //aumentamos el contador de intersecciones (*nIntersec)++; //calculamos las longitudes de los segmentos lonAB = Dist2D(auxA->xP,auxA->yP,auxB->xP,auxB->yP); lonCD = Dist2D(auxC->xP,auxC->yP,auxD->xP,auxD->yP); //calculamos los parámetros alfa alfaAB = Dist2D(auxA->xP,auxA->yP,xI,yI)/lonAB; alfaCD = Dist2D(auxC->xP,auxC->yP,xI,yI)/lonCD; //creamos los nuevos vértices a insertar insBas = CreaVertPoliClip(xI,yI,NULL,NULL,NULL,0,1,0,0, alfaAB); insRec = CreaVertPoliClip(xI,yI,NULL,NULL,NULL,0,1,0,0, alfaCD); //comprobamos los posibles errores if((insBas==NULL)||(insRec==NULL)) { //liberamos la memoria previamente asignada free(insBas); free(insRec); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //asignamos el código de error salida = GEOC_ERR_ASIG_MEMORIA; //salimos de la función return salida; } //enlazamos los vértices mediante el campo 'vecino' insBas->vecino = insRec; insRec->vecino = insBas; //los insertamos en los polígonos InsertaVertPoliClip(insBas,auxA,auxB); InsertaVertPoliClip(insRec,auxC,auxD); } } } } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ void Paso2Greiner(vertPoliClip* poliBas, vertPoliClip* poliRec, const enum GEOC_OP_BOOL_POLIG op) { //estructuras auxiliares que apuntan a los polígonos pasados vertPoliClip* auxA=NULL; vertPoliClip* auxC=NULL; //identificador de si una intersección es de entrada o salida char entrada=0; //variables auxiliares char entA=0,entC=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos los valores iniciales a los identificadores de intersección switch(op) { //distinguimos los tipos de operación case GeocOpBoolInter: //intersección entA = 1; entC = 1; break; case GeocOpBoolUnion: //unión entA = 0; entC = 0; break; case GeocOpBoolAB: //A-B entA = 0; entC = 1; break; case GeocOpBoolBA: //B-A entA = 1; entC = 0; break; default: //por defecto, intersección entA = 1; entC = 1; break; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //EL SEGUNDO PASO DEL ALGORITMO DE GREINER-HORMANN ES LA IDENTIFICACIÓN DE //INTERSECCIONES COMO ENTRADA-SALIDA //comprobamos si el primer punto del polígono base está fuera del polígono //de recorte if(PtoEnPoliClipVertice(poliBas->xP,poliBas->yP,poliRec)) { //si el punto está fuera, la siguiente intersección es de entrada entrada = !entA; } else { entrada = entA; } //recorremos los vértices del polígono de recorte for(auxA=poliBas;auxA->siguiente!=NULL;auxA=auxA->siguiente) { //sólo trabajamos si el vértice es intersección if(auxA->interseccion!=0) { //indicamos la dirección auxA->entrada = entrada; //actualizamos la variable de entrada para la siguiente vuelta entrada = !entrada; } } //comprobamos si el primer punto del polígono de recorte está fuera del //polígono base if(PtoEnPoliClipVertice(poliRec->xP,poliRec->yP,poliBas)) { //si el punto está fuera, la siguiente intersección es de entrada entrada = !entC; } else { entrada = entC; } //recorremos los vértices del polígono base for(auxC=poliRec;auxC->siguiente!=NULL;auxC=auxC->siguiente) { //sólo trabajamos si el vértice es intersección if(auxC->interseccion!=0) { //indicamos la dirección auxC->entrada = entrada; //actualizamos la variable de entrada para la siguiente vuelta entrada = !entrada; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ polig* Paso3Greiner(vertPoliClip* poliBas, vertPoliClip* poliRec) { //vértices colgados al cerrar los polígonos vertPoliClip* ultBas=NULL; vertPoliClip* ultRec=NULL; //estructura auxiliar vertPoliClip* aux=NULL; //vectores de coordenadas de los vértices del resultado double* x=NULL; double* y=NULL; //número de elementos de los vectores x e y size_t nPtos=0; //número de elementos para los que ha sido asignada memoria size_t nElem=0; //variable de estado int estado=GEOC_ERR_NO_ERROR; //polígono de salida polig* resultado=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //cerramos los polígonos, convirtiéndolos en listas circulares ultBas = CierraPoliClip(poliBas); ultRec = CierraPoliClip(poliRec); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //mientras queden intersecciones sin visitar while((aux = SiguienteIntersecNoVisitadaPoliClip(poliBas))!=NULL) { //aumentamos el contador de elementos para los vectores x e y en 2 //unidades: una para el marcador de inicio de polígono y la otra para //las coordenadas del primer vértice nPtos+=2; //comprobamos si hay que reasignar memoria a los vectores de coordenadas if(nPtos>nElem) { //actualizamos el número de elementos de los vectores de puntos nElem += GEOC_GREINER_BUFFER_PTOS; //reasignamos memoria para los vectores x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos si ha ocurrido algún error if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //reabrimos los polígonos AbrePoliClip(poliBas,ultBas); AbrePoliClip(poliRec,ultRec); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //asignamos el marcador NaN como identificador de comienzo de polígono x[nPtos-2] = GeocNan(); y[nPtos-2] = GeocNan(); //asignamos las coordenadas del punto de intersección x[nPtos-1] = aux->xP; y[nPtos-1] = aux->yP; //EN ESTE NIVEL SIEMPRE ESTAMOS ANTE UN PUNTO DE INTERSECCIÓN //mientras el punto no haya sido visitado con anterioridad do { //lo marcamos como visitado aux->visitado = 1; aux->vecino->visitado = 1; //comprobamos si el punto es de entrada o no if(aux->entrada!=0) { //mientras no encontremos otra intersección do { //caminamos en la lista hacia adelante aux = aux->siguiente; //aumentamos el contador de elementos para x e y nPtos++; //comprobamos si hay que reasignar memoria a los vectores de //coordenadas if(nPtos>nElem) { //actualizamos el número de elementos de los vectores de //puntos nElem += GEOC_GREINER_BUFFER_PTOS; //reasignamos memoria para los vectores x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos si ha ocurrido algún error if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //reabrimos los polígonos AbrePoliClip(poliBas,ultBas); AbrePoliClip(poliRec,ultRec); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //asignamos las coordenadas del punto de intersección x[nPtos-1] = aux->xP; y[nPtos-1] = aux->yP; } while(aux->interseccion==0); //mientras no sea intersección } else { ////mientras no encontremos otra intersección do { //caminamos hacia atrás aux = aux->anterior; //aumentamos el contador de elementos para x e y nPtos++; //comprobamos si hay que reasignar memoria a los vectores de //coordenadas if(nPtos>nElem) { //actualizamos el número de elementos de los vectores de //puntos nElem += GEOC_GREINER_BUFFER_PTOS; //reasignamos memoria para los vectores x = (double*)realloc(x,nElem*sizeof(double)); y = (double*)realloc(y,nElem*sizeof(double)); //comprobamos si ha ocurrido algún error if((x==NULL)||(y==NULL)) { //liberamos la posible memoria asignada free(x); free(y); //reabrimos los polígonos AbrePoliClip(poliBas,ultBas); AbrePoliClip(poliRec,ultRec); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //asignamos las coordenadas del punto de intersección x[nPtos-1] = aux->xP; y[nPtos-1] = aux->yP; } while(aux->interseccion==0); //mientras no sea intersección } //saltamos al otro polígono aux = aux->vecino; }while(aux->visitado==0); //mientras el punto no haya sido visitado } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos la estructura de salida resultado = CreaPolig(x,y,nPtos,1,1,&estado); //comprobamos los posibles errores if(resultado==NULL) { //liberamos la memoria asignada free(x); free(y); //reabrimos los polígonos AbrePoliClip(poliBas,ultBas); AbrePoliClip(poliRec,ultRec); //comprobamos el error if(estado==GEOC_ERR_ASIG_MEMORIA) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); } else { //mensaje de error GEOC_ERROR("Error en la llamada a 'CreaPolig()'\nEste error no " "puede producirse aquí porque los NaN deben estar " "bien puestos"); } //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //reabrimos los polígonos AbrePoliClip(poliBas,ultBas); AbrePoliClip(poliRec,ultRec); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria asignada free(x); free(y); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return resultado; } /******************************************************************************/ /******************************************************************************/ polig* PoliBoolGreiner(vertPoliClip* poliBas, vertPoliClip* poliRec, const enum GEOC_OP_BOOL_POLIG op, const double facPer, size_t* nIntersec, size_t* nPerturb) { //factor de perturbación double factor=0.0; //variables de posición int posBas=0,posRec=0; //identificador de error int idError=GEOC_ERR_NO_ERROR; //polígono auxiliar polig* ba=NULL; //polígono de salida polig* resultado=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si se ha pasado factor de perturbación if(facPer<=1.0) { //utilizamos el valor por defecto factor = GEOC_GREINER_FAC_EPS_PERTURB; } else { //utilizamos el valor pasado factor = facPer; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //PRIMER PASO DEL ALGORITMO DE GREINER-HORMANN: CÁLCULO DE TODOS LOS PUNTOS //DE INTERSECCIÓN ENTRE LOS POLÍGONOS //calculamos los puntos de intersección idError = Paso1Greiner(poliBas,poliRec,factor,nIntersec,nPerturb); //comprobamos los posibles errores if(idError==GEOC_ERR_ASIG_MEMORIA) { //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'Paso1Greiner'"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si no hay intersecciones if(!(*nIntersec)) { //calculo la situación relativa entre los polígonos posBas = PtoEnPoliClipVertice(poliBas->xP,poliBas->yP,poliRec); posRec = PtoEnPoliClipVertice(poliRec->xP,poliRec->yP,poliBas); //comprobamos las posibles situaciones relativas entre los polígonos que //pueden producir cero intersecciones if((posBas==GEOC_PTO_DENTRO_POLIG)||(posBas==GEOC_PTO_VERTICE_POLIG)) { //EL POLÍGONO BASE ESTÁ DENTRO DEL POLÍGONO DE RECORTE //distinguimos las operaciones (por defecto, intersección) if(op==GeocOpBoolUnion) { //el resultado es el polígono de recorte resultado = CreaPoligPoliClip(poliRec,0); } else if(op==GeocOpBoolAB) { //el resultado es un polígono vacío resultado = CreaPoligPoliClip(NULL,0); } else if((op==GeocOpBoolBA)||(op==GeocOpBoolXor)) { //el resultado son los dos polígonos //polígono base resultado = CreaPoligPoliClip(poliBas,0); //añadimos el polígono de recorte AnyadePoligClipPolig(resultado,poliRec,0); } else { //el resultado es el polígono base resultado = CreaPoligPoliClip(poliBas,0); } } else if((posRec==GEOC_PTO_DENTRO_POLIG)|| (posRec==GEOC_PTO_VERTICE_POLIG)) { //EL POLÍGONO DE RECORTE ESTÁ DENTRO DEL POLÍGONO BASE //distinguimos las operaciones (por defecto, intersección) if(op==GeocOpBoolUnion) { //el resultado es el polígono base resultado = CreaPoligPoliClip(poliBas,0); } else if((op==GeocOpBoolAB)||(op==GeocOpBoolXor)) { //el resultado son los dos polígonos //polígono base resultado = CreaPoligPoliClip(poliBas,0); //añadimos el polígono de recorte AnyadePoligClipPolig(resultado,poliRec,0); } else if(op==GeocOpBoolBA) { //el resultado es un polígono vacío resultado = CreaPoligPoliClip(NULL,0); } else { //el resultado es el polígono de recorte resultado = CreaPoligPoliClip(poliRec,0); } } else { //NINGÚN POLÍGONO ESTÁ DENTRO DEL OTRO //distinguimos las operaciones (por defecto, intersección) if((op==GeocOpBoolUnion)||(op==GeocOpBoolXor)) { //el resultado son los dos polígonos //polígono base resultado = CreaPoligPoliClip(poliBas,0); //añadimos el polígono de recorte AnyadePoligClipPolig(resultado,poliRec,0); } else if(op==GeocOpBoolAB) { //el resultado es el polígono base resultado = CreaPoligPoliClip(poliBas,0); } else if(op==GeocOpBoolBA) { //el resultado es el polígono de recorte resultado = CreaPoligPoliClip(poliRec,0); } else { //el resultado es un polígono vacío resultado = CreaPoligPoliClip(NULL,0); } } //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //salimos de la función return resultado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //distinguimos entre XOR y el resto de operaciones if(op!=GeocOpBoolXor) { //SEGUNDO PASO DEL ALGORITMO DE GREINER-HORMANN: IDENTIFICACIÓN DE //INTERSECCIONES COMO ENTRADA-SALIDA //marcamos los puntos como entrada o salida Paso2Greiner(poliBas,poliRec,op); //TERCER PASO DEL ALGORITMO DE GREINER-HORMANN: EXTRACCIÓN DE LOS POLÍGONOS //RESULTADO DE LA OPERACIÓN //extraemos los polígonos resultado = Paso3Greiner(poliBas,poliRec); //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'Paso3Greiner'"); //salimos de la función return NULL; } } else { //LA OPERCIÓN XOR LA HACEMOS COMO LA UNIÓN DE LA OPERACIÓN A-B CON B-A //marcamos los puntos como entrada o salida para la operación A-B Paso2Greiner(poliBas,poliRec,GeocOpBoolAB); //extraemos los polígonos resultado = Paso3Greiner(poliBas,poliRec); //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'Paso3Greiner'"); //salimos de la función return NULL; } //reinicializamos los polígonos, pero manteniendo las intersecciones poliBas = ReiniciaVerticesPoliClip(poliBas); poliRec = ReiniciaVerticesPoliClip(poliRec); //marcamos los puntos como entrada o salida para la operación B-A Paso2Greiner(poliBas,poliRec,GeocOpBoolBA); //extraemos los polígonos ba = Paso3Greiner(poliBas,poliRec); //comprobamos los posibles errores if(ba==NULL) { //liberamos la memoria asignada LibMemPolig(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'Paso3Greiner'"); //salimos de la función return NULL; } //añadimos el resultado de la operación B-A al anterior de A-B idError = AnyadePoligPolig(resultado,ba); //comprobamos los posibles errores if(idError==GEOC_ERR_ASIG_MEMORIA) { //liberamos la memoria asignada LibMemPolig(resultado); LibMemPolig(ba); //mensaje de error GEOC_ERROR("Error de asignación de memoria en la llamada a " "'AnyadePoligPolig' para la operación XOR"); //salimos de la función return NULL; } //liberamos la memoria asociada a la estructura auxiliar ba LibMemPolig(ba); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return resultado; } /******************************************************************************/ /******************************************************************************/ polig* PoliBoolGreinerMult(const polig* poliBas, const polig* poliRec, const enum GEOC_OP_BOOL_POLIG op, const double facPer, size_t* nIntersec, size_t* nPerturb) { //índices para recorrer bucles size_t i=0,j=0; //variable de posición size_t pos=0; //número de intersecciones y de puntos perturbados auxiliar size_t nInt=0,nPer=0; //posición de un rectángulo con respecto a otro int pr=0; //variables de error int estado1=GEOC_ERR_NO_ERROR,estado2=GEOC_ERR_NO_ERROR; //listas de trabajo vertPoliClip* poligBas=NULL; vertPoliClip* poligRec=NULL; //polígono auxiliar polig* poligAux=NULL; //variable de salida polig* resultado=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el número total de intersecciones y de puntos perturbados *nIntersec = 0; *nPerturb = 0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la variable de salida resultado = IniciaPoligVacio(); //comprobamos los posibles errores if(resultado==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos los polígonos base for(i=0;inPolig;i++) { //dirección de inicio de los vértices del polígono base pos = poliBas->posIni[i]; //creamos el polígono base de trabajo poligBas = CreaPoliClip(&(poliBas->x[pos]),&(poliBas->y[pos]), poliBas->nVert[i],1,1); //comprobamos los posibles errores if(poligBas==NULL) { //liberamos la memoria asignada hasta ahora LibMemPolig(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //recorremos los polígonos de recorte for(j=0;jnPolig;j++) { //comprobamos si los polígonos tienen definidos sus límites if((poliBas->hayLim)&&(poliRec->hayLim)) { //comprobamos si los restángulos que encierran a los polígonos //son disjuntos o no pr = RectDisjuntos(poliBas->xMin[i],poliBas->xMax[i], poliBas->yMin[i],poliBas->yMax[i], poliRec->xMin[j],poliRec->xMax[j], poliRec->yMin[j],poliRec->yMax[j]); //comprobamos los casos particulares si los rectángulos son //disjuntos if(pr&&(op==GeocOpBoolInter)) { //EN CASO DE INTERSECCIÓN, NO SE AÑADE NADA //vamos a la siguiente vuelta del bucle continue; } else if(pr&&((op==GeocOpBoolUnion)||(op==GeocOpBoolXor))) { //EN CASO DE UNIÓN O UNIÓN EXCLUSIVA, SE AÑADEN LOS DOS //POLÍGONOS //añadimos el polígono base estado1 = AnyadeDatosPolig(resultado,&(poliBas->x[pos]), &(poliBas->y[pos]), poliBas->nVert[i],1,1); //añadimos el polígono de recorte pos = poliRec->posIni[j]; estado2 = AnyadeDatosPolig(resultado,&(poliRec->x[pos]), &(poliRec->y[pos]), poliRec->nVert[j],1,1); //comprobamos los posibles errores, que sólo pueden ser de //asignación de memoria if((estado1!=GEOC_ERR_NO_ERROR)|| (estado2!=GEOC_ERR_NO_ERROR)) { //liberamos la posible memoria asignada hasta ahora LibMemPoliClip(poligBas); LibMemPolig(resultado); //lanzamos el mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //vamos a la siguiente vuelta del bucle continue; } else if(pr&&(op==GeocOpBoolAB)) { //EN CASO DE OPERACIÓN A-B, SE AÑADE EL POLÍGONO BASE //añadimos el polígono base estado1 = AnyadeDatosPolig(resultado,&(poliBas->x[pos]), &(poliBas->y[pos]), poliBas->nVert[i],1,1); //comprobamos los posibles errores, que sólo pueden ser de //asignación de memoria if(estado1!=GEOC_ERR_NO_ERROR) { //liberamos la posible memoria asignada hasta ahora LibMemPoliClip(poligBas); LibMemPolig(resultado); //lanzamos el mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //vamos a la siguiente vuelta del bucle continue; } else if(pr&&(op==GeocOpBoolBA)) { //EN CASO DE OPERACIÓN B-A, SE AÑADE EL POLÍGONO DE RECORTE //añadimos el polígono de recorte pos = poliRec->posIni[j]; estado1 = AnyadeDatosPolig(resultado,&(poliRec->x[pos]), &(poliRec->y[pos]), poliRec->nVert[j],1,1); //comprobamos los posibles errores, que sólo pueden ser de //asignación de memoria if(estado1!=GEOC_ERR_NO_ERROR) { //liberamos la posible memoria asignada hasta ahora LibMemPoliClip(poligBas); LibMemPolig(resultado); //lanzamos el mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //vamos a la siguiente vuelta del bucle continue; } } //dirección de inicio de los vértices del polígono de recorte pos = poliRec->posIni[j]; //creamos el polígono de recorte de trabajo poligRec = CreaPoliClip(&(poliRec->x[pos]),&(poliRec->y[pos]), poliRec->nVert[j],1,1); //comprobamos los posibles errores if(poligRec==NULL) { //liberamos la memoria asignada hasta ahora LibMemPoliClip(poligBas); LibMemPolig(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //recortamos poligAux = PoliBoolGreiner(poligBas,poligRec,op,facPer,&nInt,&nPer); //comprobamos los posibles errores if(poligAux==NULL) { //liberamos la posible memoria asignada hasta ahora LibMemPoliClip(poligBas); LibMemPoliClip(poligRec); LibMemPolig(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //sumamos el número de intersecciones y de puntos perturbados (*nIntersec) += nInt; (*nPerturb) += nPer; //añadimos los polígonos recortados a la variable de salida if(AnyadePoligPolig(resultado,poligAux)==GEOC_ERR_ASIG_MEMORIA) { //liberamos la posible memoria asignada hasta ahora LibMemPoliClip(poligBas); LibMemPoliClip(poligRec); LibMemPolig(poligAux); LibMemPolig(resultado); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //liberamos la memoria asignada al polígono de esta vuelta del bucle LibMemPoliClip(poligRec); //liberamos la memoria asignada al polígono auxiliar LibMemPolig(poligAux); //reinicializamos el polígono base poligBas = ReiniciaPoliClip(poligBas); } //liberamos la memoria asignada al polígono de esta vuelta del bucle LibMemPoliClip(poligBas); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return resultado; } /******************************************************************************/ /******************************************************************************/ polig* CreaPoligPoliClip(vertPoliClip* poli, const int coorOrig) { //índice para recorrer bucles size_t i=0; //número de elementos size_t nVert=0,nElem=0; //estructura auxiliar vertPoliClip* aux=poli; //variable de salida polig* result=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos la estructura vacía result = IniciaPoligVacio(); //comprobamos los posibles errores if(result==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contamos todos los vértices del polígono nVert = NumeroVertPoliClip(poli); //contemplamos una posible salida rápida if(nVert==0) { //devolvemos la estructura vacía return result; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //número de elementos de los vectores de coordenadas nElem = nVert+2; //asignamos memoria para los vectores de coordenadas de la estructura result->x = (double*)malloc(nElem*sizeof(double)); result->y = (double*)malloc(nElem*sizeof(double)); //asignamos memoria para los vectores de posición result->posIni = (size_t*)malloc(sizeof(size_t)); result->nVert = (size_t*)malloc(sizeof(size_t)); //comprobamos los posibles errores de asignación de memoria if((result->x==NULL)||(result->y==NULL)||(result->posIni==NULL)|| (result->nVert==NULL)) { //liberamos la posible memoria asignada LibMemPolig(result); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos el número de elementos de los vectores de coordenadas y de //polígonos result->nElem = nElem; result->nPolig = 1; //asignamos la posición de inicio y el número de vértices result->posIni[0] = 1; result->nVert[0] = nVert; //asignamos los separadores de polígono al principio y al final result->x[0] = GeocNan(); result->y[0] = GeocNan(); result->x[nElem-1] = GeocNan(); result->y[nElem-1] = GeocNan(); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos los vértices del polígono for(i=1;i<=nVert;i++) { //distinguimos el tipo de coordenadas a copiar if(coorOrig) { //coordenadas originales result->x[i] = aux->x; result->y[i] = aux->y; } else { //coordenadas perturbadas result->x[i] = aux->xP; result->y[i] = aux->yP; } //siguiente vértice aux = aux->siguiente; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return result; } /******************************************************************************/ /******************************************************************************/ int AnyadePoligClipPolig(polig* poli, vertPoliClip* anyade, const int coorOrig) { //número de elementos a añadir size_t nVert=0; //polígono auxiliar polig* aux=NULL; //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contamos todos los vértices del polígono a añadir nVert = NumeroVertPoliClip(anyade); //contemplamos una posible salida rápida if(nVert==0) { //devolvemos la estructura vacía return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos un nuevo polígono con los datos a añadir aux = CreaPoligPoliClip(anyade,coorOrig); //comprobamos los posibles errores if(aux==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //añadimos la nueva estructura estado = AnyadePoligPolig(poli,aux); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria utilizada LibMemPolig(aux); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/polig.c0000644000175000017500000021501712035672422015762 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom gshhs @{ \file polig.c \brief Definición de funciones para el trabajo con polígonos. \author José Luis García Pallero, jgpallero@gmail.com \note Este fichero contiene funciones paralelizadas con OpenMP. \date 20 de abril de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/polig.h" /******************************************************************************/ /******************************************************************************/ int GeocParOmpPolig(char version[]) { //comprobamos si hay paralelización #if defined(_OPENMP) //comprobamos si hay que extraer versión if(version!=NULL) { //calculamos la versión VersionOpenMP(_OPENMP,version); } //salimos de la función return 1; #else if(version!=NULL) { //utilizamos la variable version para que no dé warming al compilar strcpy(version,""); } //salimos de la función return 0; #endif } /******************************************************************************/ /******************************************************************************/ polig* IniciaPoligVacio(void) { //estructura de salida polig* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos memoria para la estructura sal = (polig*)malloc(sizeof(polig)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //inicializamos los campos escalares a 0 sal->nElem = 0; sal->nPolig = 0; sal->hayLim = 0; sal->hayArea = 0; //inicializamos los campos vectoriales a NULL sal->x = NULL; sal->y = NULL; sal->posIni = NULL; sal->nVert = NULL; sal->xMin = NULL; sal->xMax = NULL; sal->yMin = NULL; sal->yMax = NULL; sal->area = NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ int AuxCreaPolig1(const size_t nElem, const size_t* posNanX, const size_t* posNanY, const size_t nNanX, const size_t nNanY, size_t* nElemMax, size_t* nPolig) { //índice para recorrer bucles size_t i=0; //variable de salida int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay el mismo número de NaN en los dos vectores if(nNanX!=nNanY) { //salimos de la función return GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG; } //comprobamos si hay NaN en las mismas posiciones de los vectores for(i=0;i fin del #pragma omp parallel sections //comprobamos los posibles errores de asignación de memoria if(((posNanX==NULL)&&(nNanX!=0))||((posNanY==NULL)&&(nNanY!=0))) { //liberamos la memoria asignada LibMemPolig(sal); free(posNanX); free(posNanY); //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si los vectores tienen bien colocados los NaN y calculamos //el número máximo de elementos de los vectores de la estructura y el //número de polígonos *idError = AuxCreaPolig1(nElem,posNanX,posNanY,nNanX,nNanY,&nElemMax, &nPolig); //comprobamos los posibles errores if(*idError!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(sal); free(posNanX); free(posNanY); //escribimos el mensaje de error if(*idError==GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG) { GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo " "número de polígonos"); } else if(*idError==GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG) { GEOC_ERROR("Error: Los vectores de trabajo no contienen los mismos " "polígonos"); } //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos el número de polígonos sal->nPolig = nPolig; //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(sal,nElemMax,nPolig) #endif { //asignamos memoria para los vectores de la estructura #if defined(_OPENMP) #pragma omp section #endif sal->x = (double*)malloc(nElemMax*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif sal->y = (double*)malloc(nElemMax*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif sal->posIni = (size_t*)malloc(nPolig*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif sal->nVert = (size_t*)malloc(nPolig*sizeof(double)); } // --> fin del #pragma omp parallel sections //comprobamos los posibles errores if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL)) { //liberamos la memoria asignada LibMemPolig(sal); free(posNanX); free(posNanY); //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //copiamos los polígonos a la estructura //como ya sabemos que el número de NaN y sus posiciones son los mismos para //los vectores x e y, trabajamos con los valores para el vector x AuxCreaPolig3(x,y,nElem,incX,incY,posNanX,nNanX,sal->x,sal->y,sal->posIni, sal->nVert,&ptos,&nPolig); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay de verdad algún polígono if(nPolig==0) { //liberamos la memoria asignada LibMemPolig(sal); free(posNanX); free(posNanY); //creamos la estructura vacía sal = IniciaPoligVacio(); //comprobamos los posibles errores if(sal==NULL) { //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //salimos de la función return sal; } //asignamos el número de elementos a la estructura sal->nElem = ptos; //comprobamos si hay que reajustar el tamaño de los vectores de coordenadas if(ptos!=nElemMax) { //asignamos el nuevo tamaño de los vectores sal->nElem = ptos; //reajustamos los tamaños sal->x = (double*)realloc(sal->x,ptos*sizeof(double)); sal->y = (double*)realloc(sal->y,ptos*sizeof(double)); } //comprobamos si el número de polígonos es el estimado if(nPolig!=sal->nPolig) { //asignamos de nuevo la variable de número de polígonos sal->nPolig = nPolig; //reajustamos los tamaños sal->posIni = (size_t*)realloc(sal->posIni,nPolig*sizeof(size_t)); sal->nVert = (size_t*)realloc(sal->nVert,nPolig*sizeof(size_t)); } //comprobamos los posibles errores if((sal->x==NULL)||(sal->y==NULL)||(sal->posIni==NULL)||(sal->nVert==NULL)) { //liberamos la memoria asignada LibMemPolig(sal); free(posNanX); free(posNanY); //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria asignada free(posNanX); free(posNanY); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ void EnlazaCamposPolig(polig* poliEnt, polig* poliSal) { //LIBERAMOS LA POSIBLE MEMORIA ASIGNADA A LOS CAMPOS VECTORIALES DE LA //ESTRUCTURA DE SALIDA //comprobamos si hay algún elemento en los vectores de coordenadas if(poliSal->nElem) { free(poliSal->x); free(poliSal->y); } //comprobamos si hay algún polígono en los vectores de posiciones if(poliSal->nPolig) { free(poliSal->posIni); free(poliSal->nVert); } //comprobamos si hay límites calculados if(poliSal->hayLim) { free(poliSal->xMin); free(poliSal->xMax); free(poliSal->yMin); free(poliSal->yMax); } //comprobamos si hay superficies calculadas if(poliSal->hayArea) { free(poliSal->area); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //enlazamos todos los campos de la estructura de entrada en la de salida poliSal->nElem = poliEnt->nElem; poliSal->x = poliEnt->x; poliSal->y = poliEnt->y; poliSal->nPolig = poliEnt->nPolig; poliSal->posIni = poliEnt->posIni; poliSal->nVert = poliEnt->nVert; poliSal->hayLim = poliEnt->hayLim; poliSal->xMin = poliEnt->xMin; poliSal->xMax = poliEnt->xMax; poliSal->yMin = poliEnt->yMin; poliSal->yMax = poliEnt->yMax; poliSal->hayArea = poliEnt->hayArea; poliSal->area = poliEnt->area; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ polig* CopiaPolig(const polig* poli, int* idError) { //polígono de salida polig* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la variable de error *idError = GEOC_ERR_NO_ERROR; //inicializamos el polígono de salida sal = IniciaPoligVacio(); //comprobamos los posibles errores if(sal==NULL) { //asignamos la variable de error *idError = GEOC_ERR_ASIG_MEMORIA; //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //sólo continuamos si el polígono de entrada contiene datos if(poli->nElem) { //copiamos las coordenadas de los vértices *idError = AnyadeDatosPolig(sal,poli->x,poli->y,poli->nElem,1,1); //comprobamos si ha ocurrido algún error if((*idError)!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(sal); //escribimos el mensaje de error if((*idError)==GEOC_ERR_ASIG_MEMORIA) { GEOC_ERROR("Error de asignación de memoria"); } else if((*idError)==GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG) { GEOC_ERROR("Error: Los vectores de coordenadas del polígono\n" "de entrada no contienen el mismo número de " "polígonos"); } else if((*idError)==GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG) { GEOC_ERROR("Error: Los vectores de coordenadas del polígono\n" "de entrada no contienen los mismos polígonos"); } //salimos de la función return NULL; } //comprobamos si hay que calcular límites if(poli->hayLim) { //calculamos los límites *idError = CalcLimitesPolig(sal); //comprobamos los posibles errores if((*idError)!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(sal); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //comprobamos si hay que calcular superficies if(poli->hayArea) { //calculamos las áreas *idError = CalcAreaPolig(sal); //comprobamos los posibles errores if((*idError)!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(sal); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ int AnyadePoligPolig(polig* poli, const polig* anyade) { //índice para recorrer bucles size_t i=0; //variable de posición size_t pos=0; //número total de elementos size_t nElem=0,nPolig=0; //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //si el polígono a añadir está vacío, salimos de la función if((anyade!=NULL)&&(anyade->nPolig==0)) { //salimos de la función sin hacer nada return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el número total de elementos del polígono conjunto nElem = poli->nElem+anyade->nElem; //si el polígono original contenía datos, al número total de elementos hay //que restarle 1 por el NaN común que sobra al juntar las dos estructuras if(poli->nPolig) { nElem--; } //calculamos el número total de polígonos nPolig = poli->nPolig+anyade->nPolig; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //reasignamos memoria para cubrir los nuevos datos poli->x = (double*)realloc(poli->x,nElem*sizeof(double)); poli->y = (double*)realloc(poli->y,nElem*sizeof(double)); poli->posIni = (size_t*)realloc(poli->posIni,nPolig*sizeof(size_t)); poli->nVert = (size_t*)realloc(poli->nVert,nPolig*sizeof(size_t)); //reasignamos también para los posibles vectores de límites y superficies if(poli->hayLim) { poli->xMin = (double*)realloc(poli->xMin,nPolig*sizeof(double)); poli->xMax = (double*)realloc(poli->xMax,nPolig*sizeof(double)); poli->yMin = (double*)realloc(poli->yMin,nPolig*sizeof(double)); poli->yMax = (double*)realloc(poli->yMax,nPolig*sizeof(double)); } if(poli->hayArea) { poli->area = (double*)realloc(poli->area,nPolig*sizeof(double)); } //comprobamos los posibles errores en las asignaciones obligatorias if((poli->x==NULL)||(poli->y==NULL)||(poli->posIni==NULL)|| (poli->nVert==NULL)) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //comprobamos los posibles errores en las asignaciones de límites if(poli->hayLim) { if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)|| (poli->yMax==NULL)) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } } //comprobamos los posibles errores en las asignaciones de áreas if(poli->hayArea) { if(poli->area==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos la posición de inicio para copiar en la estructura de salida //si la estructura de salida está vacía, se comienza en la primera posición //si tiene datos, se comienza a continuación en la última (dentro del bucle, //la suma de posIni hace que se comience a continuación de la última) pos = (poli->nPolig==0) ? 0 : poli->nElem-1; //recorremos el número de nuevos elementos for(i=0;inElem;i++) { //copiamos las coordenadas poli->x[pos+i] = anyade->x[i]; poli->y[pos+i] = anyade->y[i]; } //calculamos las posiciones a sumar para ajustar las posiciones de inicio de //los polígonos añadidos //si la estructura de salida está vacía, se copian las posiciones tal cual //si tiene datos, se suman las posiciones ya ocupadas pos = (poli->nPolig==0) ? 0 : poli->nElem-1; //recorremos el número de polígonos for(i=0;inPolig;i++) { //copiamos las posiciones de inicio actualizadas y el número de vértices poli->posIni[poli->nPolig+i] = anyade->posIni[i]+pos; poli->nVert[poli->nPolig+i] = anyade->nVert[i]; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que calcular límites if(poli->hayLim) { //comprobamos si ya están calculados if(anyade->hayLim) { //recorremos el número de polígonos y copiamos los límites for(i=0;inPolig;i++) { //copiamos los límites poli->xMin[poli->nPolig+i] = anyade->xMin[i]; poli->xMax[poli->nPolig+i] = anyade->xMax[i]; poli->yMin[poli->nPolig+i] = anyade->yMin[i]; poli->yMax[poli->nPolig+i] = anyade->yMax[i]; } } else { //calculamos los límites y los copiamos LimitesPoligonosPolig(&(anyade->x[1]),&(anyade->y[1]),1,1, anyade->posIni,anyade->nVert,anyade->nPolig, anyade->posIni[0],&(poli->xMin[poli->nPolig]), &(poli->xMax[poli->nPolig]), &(poli->yMin[poli->nPolig]), &(poli->yMax[poli->nPolig])); } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que calcular áreas if(poli->hayArea) { //comprobamos si ya están calculadas if(anyade->hayArea) { //recorremos el número de polígonos y copiamos las superficies for(i=0;inPolig;i++) { //copiamos los límites poli->area[poli->nPolig+i] = anyade->area[i]; } } else { //calculamos las superficies y las copiamos AreaPoligonosSimplesPolig(&(anyade->x[1]),&(anyade->y[1]),1,1, anyade->posIni,anyade->nVert, anyade->nPolig,anyade->posIni[0], &(poli->area[poli->nPolig])); } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ajustamos los tamaños antes de salir poli->nElem = nElem; poli->nPolig = nPolig; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ int AnyadeDatosPolig(polig* poli, const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY) { //polígono auxiliar polig* aux=NULL; //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contemplamos una posible salida rápida if(nElem==0) { //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos un nuevo polígono con los datos a añadir aux = CreaPolig(x,y,nElem,incX,incY,&estado); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(aux); //escribimos el mensaje de error if(estado==GEOC_ERR_ASIG_MEMORIA) { GEOC_ERROR("Error de asignación de memoria"); } else if(estado==GEOC_ERR_POLIG_VEC_DISTINTO_NUM_POLIG) { GEOC_ERROR("Error: Los vectores de trabajo no contienen el mismo " "número de polígonos"); } else if(estado==GEOC_ERR_POLIG_VEC_DISTINTOS_POLIG) { GEOC_ERROR("Error: Los vectores de trabajo no contienen los mismos " "polígonos"); } //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //añadimos la nueva estructura estado = AnyadePoligPolig(poli,aux); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //liberamos la memoria utilizada LibMemPolig(aux); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ void LibMemPolig(polig* datos) { //comprobamos si hay memoria que liberar if(datos!=NULL) { //liberamos la memoria asignada al vector de coordenadas X if(datos->x!=NULL) { free(datos->x); } //liberamos la memoria asignada al vector de coordenadas Y if(datos->y!=NULL) { free(datos->y); } //liberamos la memoria asignada al vector de posiciones if(datos->posIni!=NULL) { free(datos->posIni); } //liberamos la memoria asignada al vector de número de vértices if(datos->nVert!=NULL) { free(datos->nVert); } //liberamos la memoria asignada a los vector de coordenadas X mínimas if(datos->xMin!=NULL) { free(datos->xMin); } //liberamos la memoria asignada a los vector de coordenadas X máximas if(datos->xMax!=NULL) { free(datos->xMax); } //liberamos la memoria asignada a los vector de coordenadas Y mínimas if(datos->yMin!=NULL) { free(datos->yMin); } //liberamos la memoria asignada a los vector de coordenadas Y máximas if(datos->yMax!=NULL) { free(datos->yMax); } //liberamos la memoria asignada al vector de áreas if(datos->area!=NULL) { free(datos->area); } //liberamos la memoria asignada a la estructura free(datos); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int CalcLimitesPolig(polig* poli) { //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos salida rápida if((poli->nPolig==0)||(poli->hayLim)) { //salimos de la función si la estructura no contiene polígonos o si //éstos ya tienen calculados sus límites return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli) #endif { //asignamos memoria para los vectores de límites #if defined(_OPENMP) #pragma omp section #endif poli->xMin = (double*)malloc((poli->nPolig)*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif poli->xMax = (double*)malloc((poli->nPolig)*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif poli->yMin = (double*)malloc((poli->nPolig)*sizeof(double)); #if defined(_OPENMP) #pragma omp section #endif poli->yMax = (double*)malloc((poli->nPolig)*sizeof(double)); } // --> fin del #pragma omp parallel sections //comprobamos los posibles errores if((poli->xMin==NULL)||(poli->xMax==NULL)||(poli->yMin==NULL)|| (poli->yMax==NULL)) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //indicamos que sí hay límites poli->hayLim = 1; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos los límites de todos los polígonos LimitesPoligonosPolig(poli->x,poli->y,1,1,poli->posIni,poli->nVert, poli->nPolig,0,poli->xMin,poli->xMax,poli->yMin, poli->yMax); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ void LimitesPoligono(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY, double* xMin, double* xMax, double* yMin, double* yMax) { //posiciones de los elementos máximo y mínimo size_t posXMin=0,posXMax=0,posYMin=0,posYMax=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //buscamos las posiciones de los elementos máximo y mínimo //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(x,posXMin,posXMax,y,posYMin,posYMax) #endif { //posiciones en el vector X #if defined(_OPENMP) #pragma omp section #endif MinMax(x,nElem,incX,&posXMin,&posXMax); //posiciones en el vector Y #if defined(_OPENMP) #pragma omp section #endif MinMax(y,nElem,incY,&posYMin,&posYMax); } // --> fin del #pragma omp parallel sections //extraemos los valores de las posiciones calculadas *xMin = x[posXMin*incX]; *xMax = x[posXMax*incX]; *yMin = y[posYMin*incY]; *yMax = y[posYMax*incY]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void LimitesPoligonosPolig(const double* x, const double* y, const size_t incX, const size_t incY, const size_t* posIni, const size_t* nVert, const size_t nPolig, const size_t restaPosIni, double* xMin, double* xMax, double* yMin, double* yMax) { //índice para recorrer bucles size_t i=0; //posición inicial del polígono de trabajo size_t pI=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel for default(none) schedule(dynamic) \ shared(posIni,x,y,nVert,xMin,xMax,yMin,yMax) \ private(i,pI) #endif //recorremos el número de polígonos for(i=0;i fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int CalcAreaPolig(polig* poli) { //variable de estado (salida) int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos salida rápida if((poli->nPolig==0)||(poli->hayArea)) { //salimos de la función si la estructura no contiene polígonos o si //éstos ya tienen calculada su superficie return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //asignamos memoria para el vector de superficies poli->area = (double*)malloc((poli->nPolig)*sizeof(double)); //comprobamos los posibles errores if(poli->area==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //indicamos que sí hay superficies poli->hayArea = 1; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos las superficies de todos los polígonos AreaPoligonosSimplesPolig(poli->x,poli->y,1,1,poli->posIni,poli->nVert, poli->nPolig,0,poli->area); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ double AreaPoligonoSimple(const double* x, const double* y, const size_t nElem, const size_t incX, const size_t incY) { //índice para recorrer bucles size_t i=0; //número de elementos de trabajo, que inicializamos con el valor pasado size_t nElemTrab=nElem; //variable de salida double area=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //si el primero punto es el mismo que el último, restamos una unidad al //número de elementos pasado, ya que el algoritmo está preparado para //trabajar con un vector en el que no se repite el primer punto if((x[0]==x[(nElem-1)*incX])&&(y[0]==y[(nElem-1)*incY])) { //el número de elementos de trabajo es uno menos que el pasado nElemTrab = nElem-1; } //el algoritmo utilizado es la segunda expresión de la ecuación 21.4.20 del //Numerical Recipes, tercera edición, página 1127 //recorremos los puntos hasta el penúltimo for(i=0;i<(nElemTrab-1);i++) { //vamos sumando area += (x[(i+1)*incX]+x[i*incX])*(y[(i+1)*incY]-y[i*incY]); } //sumamos la contribución del último lado, es decir, el lado que contiene //como vértice final al primer punto area += (x[0]+x[(nElemTrab-1)*incX])*(y[0]-y[(nElemTrab-1)*incY]); //dividimos entre dos para calcular el área real area /= 2.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return area; } /******************************************************************************/ /******************************************************************************/ void AreaPoligonosSimplesPolig(const double* x, const double* y, const size_t incX, const size_t incY, const size_t* posIni, const size_t* nVert, const size_t nPolig, const size_t restaPosIni, double* area) { //índice para recorrer bucles size_t i=0; //posición inicial del polígono de trabajo size_t pI=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel for default(none) schedule(dynamic) \ shared(posIni,area,x,y,nVert) \ private(i,pI) #endif //recorremos el número de polígonos for(i=0;i fin del #pragma omp parallel for //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void EscalaYTrasladaPolig(polig* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim, const int aplicaArea) { //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli) #endif { #if defined(_OPENMP) #pragma omp section #endif //aplicamos los factores de escala y las traslaciones a las coordenadas X EscalaYTrasladaVector(poli->x,poli->nElem,1,escalaX,trasladaX); #if defined(_OPENMP) #pragma omp section #endif //aplicamos los factores de escala y las traslaciones a las coordenadas Y EscalaYTrasladaVector(poli->y,poli->nElem,1,escalaY,trasladaY); } // --> fin del #pragma omp parallel sections //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO //TOTAL DE VÉRTICES //comprobamos si hay que aplicar el factor a los límites if(aplicaLim&&poli->hayLim) { //aplicamos los factores de escala y las traslaciones a los límites EscalaYTrasladaVector(poli->xMin,poli->nPolig,1,escalaX,trasladaX); EscalaYTrasladaVector(poli->xMax,poli->nPolig,1,escalaX,trasladaX); EscalaYTrasladaVector(poli->yMin,poli->nPolig,1,escalaY,trasladaY); EscalaYTrasladaVector(poli->yMax,poli->nPolig,1,escalaY,trasladaY); } //comprobamos si hay que aplicar el factor a las superficies if(aplicaArea&&poli->hayArea) { //aplicamos el factor de escala a las áreas EscalaYTrasladaVector(poli->area,poli->nPolig,1,fabs(escalaX*escalaY), 0.0); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void TrasladaYEscalaPolig(polig* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int aplicaLim, const int aplicaArea) { //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli) #endif { #if defined(_OPENMP) #pragma omp section #endif //aplicamos las traslaciones y los factores de escala a las coordenadas X TrasladaYEscalaVector(poli->x,poli->nElem,1,escalaX,trasladaX); #if defined(_OPENMP) #pragma omp section #endif //aplicamos las traslaciones y los factores de escala a las coordenadas Y TrasladaYEscalaVector(poli->y,poli->nElem,1,escalaY,trasladaY); } // --> fin del #pragma omp parallel sections //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ESTA PARTE NO LA PARALELIZAMOS, YA QUE SUPONEMOS QUE EL NÚMERO DE //POLÍGONOS EN UNA ESTRUCTURA SIEMPRE SERÁ MUCHÍSIMO MENOR QUE EL NÚMERO //TOTAL DE VÉRTICES //comprobamos si hay que aplicar el factor a los límites if(aplicaLim&&poli->hayLim) { //aplicamos las traslaciones y los factores de escala a los límites TrasladaYEscalaVector(poli->xMin,poli->nPolig,1,escalaX,trasladaX); TrasladaYEscalaVector(poli->xMax,poli->nPolig,1,escalaX,trasladaX); TrasladaYEscalaVector(poli->yMin,poli->nPolig,1,escalaY,trasladaY); TrasladaYEscalaVector(poli->yMax,poli->nPolig,1,escalaY,trasladaY); } //comprobamos si hay que aplicar el factor a las superficies if(aplicaArea&&poli->hayArea) { //aplicamos el factor de escala a las áreas TrasladaYEscalaVector(poli->area,poli->nPolig,1,fabs(escalaX*escalaY), 0.0); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void MuevePolig(polig* poli, const double escalaX, const double escalaY, const double trasladaX, const double trasladaY, const int orden, const int aplicaLim, const int aplicaArea) { //comprobamos el orden de aplicación de los factores if(orden==0) { //primero los factores de escala y luego las traslaciones EscalaYTrasladaPolig(poli,escalaX,escalaY,trasladaX,trasladaY,aplicaLim, aplicaArea); } else { //primero las traslaciones y luego los factores de escala TrasladaYEscalaPolig(poli,escalaX,escalaY,trasladaX,trasladaY,aplicaLim, aplicaArea); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ int AligeraPolig(polig* poli, const double tol, const enum GEOC_DPEUCKER_ROBUSTO robusto, const size_t nPtosRobusto, const size_t nSegRobusto) { //índices para recorrer bucles size_t i=0,j=0; //posición inicial del polígono de trabajo y número de puntos del aligerado size_t posIni=0,nPtos=0; //puntos colineales int colin=0; //coordenadas de los polígonos aligerados double* x=NULL; double* y=NULL; //estructura auxiliar polig* aux=NULL; //vector de posiciones después del aligerado size_t* pos=NULL; //variable de salida int estado=GEOC_ERR_NO_ERROR; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos una posible salida rápida if(poli->nPolig==0) { //salimos de la función return estado; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la estructura auxiliar vacía aux = IniciaPoligVacio(); //comprobamos los posibles errores if(aux==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos el número de polígonos almacenados for(i=0;inPolig;i++) { //extraemos la posición inicial del polígono de trabajo posIni = poli->posIni[i]; //aligeramos el polígono de trabajo pos = AligeraPolilinea(&(poli->x[posIni]),&(poli->y[posIni]), poli->nVert[i],1,1,tol,robusto,nPtosRobusto, nSegRobusto,&nPtos); //comprobamos posibles errores if(pos==NULL) { //liberamos la memoria asignada LibMemPolig(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //comprobamos si el polígono se ha quedado en tres puntos if(nPtos==3) { //comprobamos si los tres puntos son colineales colin = TresPuntosColineales2D(poli->x[posIni+pos[0]], poli->y[posIni+pos[0]], poli->x[posIni+pos[1]], poli->y[posIni+pos[1]], poli->x[posIni+pos[2]], poli->y[posIni+pos[2]]); } //comprobamos si después del aligerado queda algún polígono if((nPtos>3)||((nPtos==3)&&(!colin))) { //asignamos memoria para los vectores de coordenadas del polígono //aligerado x = (double*)malloc(nPtos*sizeof(double)); y = (double*)malloc(nPtos*sizeof(double)); //comprobamos posibles errores if((x==NULL)||(y==NULL)) { //liberamos la memoria asignada LibMemPolig(aux); free(pos); free(x); free(y); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //recorremos el número de puntos del polígono aligerado for(j=0;jx[posIni+pos[j]]; y[j] = poli->y[posIni+pos[j]]; } //añadimos las coordenadas al polígono aligerado estado = AnyadeDatosPolig(aux,x,y,nPtos,1,1); //sólo puede haber ocurrido un error de asignación de memoria, ya //que suponemos que el polígono de entrada es correcto if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(aux); free(pos); free(x); free(y); //escribimos el mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } //liberamos la memoria asignada a los vectores de coordenadas free(x); free(y); } //liberamos la memoria asignada al vector de posiciones del aligerado free(pos); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que calcular límites if(poli->hayLim) { //calculamos los límites estado = CalcLimitesPolig(aux); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } } //comprobamos si hay que calcular superficies if(poli->hayArea) { //calculamos las áreas estado = CalcAreaPolig(aux); //comprobamos los posibles errores if(estado!=GEOC_ERR_NO_ERROR) { //liberamos la memoria asignada LibMemPolig(aux); //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return GEOC_ERR_ASIG_MEMORIA; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //enlazamos los campos de la estructura auxiliar a los de la estructura de //salida EnlazaCamposPolig(aux,poli); //liberamos la memoria asignada a la estructura auxiliar (pero no a sus //campos) free(aux); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return estado; } /******************************************************************************/ /******************************************************************************/ void ImprimeCabeceraPoligFichero(const polig* poli, const size_t indice, const char iniCab[], const int impLim, const char formCoor[], const int impArea, const char formArea[], const double factorX, const double factorY, const int repitePrimerPunto, FILE* idFich) { //número de vértices del polígono de trabajo size_t nVert=0; //superficie de los polígonos double area=0.0; //límites double xMin=0.0,xMax=0.0,yMin=0.0,yMax=0.0,limAux=0.0; //variables de posición size_t pos=0,posXMin=0,posXMax=0,posYMin=0,posYMax=0; //variable auxiliar size_t aux=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //ajustamos la variable auxiliar como el posible número a restar si no hay //que repetir el primer vértice del polígono aux = (repitePrimerPunto) ? 0 : 1; //número de vértices a imprimir del polígono nVert = poli->nVert[indice]-aux; //posición de inicio del polígono pos = poli->posIni[indice]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //imprimimos la marca de inicio y el número de vértices fprintf(idFich,"%s %8zu",iniCab,nVert); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que imprimir la superficie if(impArea) { //comprobamos si ya está calculada la superficie o no if(poli->hayArea) { //aplicamos los factores de escala y extraemos la superficie area = poli->area[indice]*fabs(factorX)*fabs(factorY); } else { //calculamos la superficie area = AreaPoligonoSimple(&(poli->x[pos]),&(poli->y[pos]), poli->nVert[indice],1,1); //aplicamos los factores de escala area *= fabs(factorX)*fabs(factorY); } //imprimimos el valor de la superficie fprintf(idFich," "); fprintf(idFich,formArea,area); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si hay que imprimir los límites if(impLim) { //comprobamos si ya están calculados los límites if(poli->hayLim) { //extraemos los límites xMin = poli->xMin[indice]; xMax = poli->xMax[indice]; yMin = poli->yMin[indice]; yMax = poli->yMax[indice]; } else { //buscamos las posiciones de los elementos máximo y mínimo //paralelización con OpenMP #if defined(_OPENMP) #pragma omp parallel sections default(none) \ shared(poli,pos,nVert,posXMin,posXMax,posYMin,posYMax) #endif { //posiciones en el vector X #if defined(_OPENMP) #pragma omp section #endif MinMax(&(poli->x[pos]),nVert,1,&posXMin,&posXMax); //posiciones en el vector Y #if defined(_OPENMP) #pragma omp section #endif MinMax(&(poli->y[pos]),nVert,1,&posYMin,&posYMax); } // --> fin del #pragma omp parallel sections //extraemos los valores extremos xMin = poli->x[pos+posXMin]; xMax = poli->x[pos+posXMax]; yMin = poli->y[pos+posYMin]; yMax = poli->y[pos+posYMax]; } //comprobamos si el factor de escala para X es negativo if(factorX<0.0) { //los límites cambian limAux = xMin; xMin = xMax; xMax = limAux; //aplicamos el factor de escala xMin *= factorX; xMax *= factorX; } //comprobamos si el factor de escala para Y es negativo if(factorY<0.0) { //los límites cambian limAux = yMin; yMin = yMax; yMax = limAux; //aplicamos el factor de escala yMin *= factorY; yMax *= factorY; } //imprimimos los límites fprintf(idFich," "); fprintf(idFich,formCoor,xMin); fprintf(idFich," "); fprintf(idFich,formCoor,xMax); fprintf(idFich," "); fprintf(idFich,formCoor,yMin); fprintf(idFich," "); fprintf(idFich,formCoor,yMax); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salto de línea final fprintf(idFich,"\n"); //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void ImprimePoligFichero(const polig* poli, const double factorX, const double factorY, const int repitePrimerPunto, const int iniNan, const int finNan, const char formCoor[], const int impCabecera, const char iniCab[], const int impLim, const int impArea, const char formArea[], FILE* idFich) { //índices para recorrer bucles size_t i=0,j=0; //cadena de formato para imprimir los posibles valores NaN char formNan[GEOC_NAN_LON_FORM_NUM_SIMPLE+1]; //variable de posición size_t pos=0; //variable auxiliar size_t aux=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si la estructura contiene algún polígono if(poli->nPolig==0) { //salimos sin imprimir nada return; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //creamos la cadena de formato para imprimir los polibles NaN FormatoNumFormatoTexto(formCoor,formNan); //ajustamos la variable auxiliar como el posible número a restar si no hay //que repetir el primer vértice de los polígonos aux = (repitePrimerPunto) ? 0 : 1; //comprobamos si hay que imprimir la marca separadora al principio if(iniNan) { //la imprimimos ImprimeGeocNanTexto(idFich,2,formNan,1); } //recorremos el número de polígonos for(i=0;inPolig;i++) { //comprobamos si hay que imprimir la cabecera if(impCabecera) { //imprimos la cabecera ImprimeCabeceraPoligFichero(poli,i,iniCab,impLim,formCoor,impArea, formArea,factorX,factorY, repitePrimerPunto,idFich); } //posición del punto inicial del polígono pos = poli->posIni[i]; //recorremos el número de vértices del polígono de trabajo for(j=0;j<(poli->nVert[i]-aux);j++) { //imprimimos las coordenadas, multiplicadas por los factores fprintf(idFich,formCoor,factorX*poli->x[pos+j]); fprintf(idFich,formCoor,factorY*poli->y[pos+j]); fprintf(idFich,"\n"); } //imprimimos la marca separadora al final (menos para el último) if(i!=(poli->nPolig-1)) { ImprimeGeocNanTexto(idFich,2,formNan,1); } } //comprobamos si hay que imprimir la marca separadora al final if(finNan) { //la imprimimos ImprimeGeocNanTexto(idFich,2,formNan,1); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/_oc_polybool.cc0000644000175000017500000002223612035672422017471 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /* Copyright (C) 2011 José Luis García Pallero, * * This file is part of OctCLIP. * * OctCLIP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, see * . */ /******************************************************************************/ /******************************************************************************/ #define HELPTEXT "\ -*- texinfo -*-\n\ @deftypefn{Loadable Function}{[@var{X},@var{Y},@var{nPol},@var{nInt},\ @var{nPert}] =}_oc_polybool(@var{sub},@var{clip},@var{op})\n\ \n\ @cindex Performs boolean operations between two polygons.\n\ \n\ This function performs boolean operations between two polygons using the\n\ Greiner-Hormann algorithm (http://davis.wpi.edu/~matt/courses/clipping/).\n\ \n\ @var{sub} is a two column matrix containing the X and Y coordinates of the\n\ vertices for the subject polygon.\n\n\ @var{clip} is a two column matrix containing the X and Y coordinates of the\n\ vertices for the clipper polygon.\n\n\ @var{op} is a text string containing the operation to perform between\n\ @var{sub} and @var{clip}. Possible values are:\n\ \n\ @itemize @bullet\n\ @item @var{'AND'}\n\ Intersection of @var{sub} and @var{clip}.\n\n\ @item @var{'OR'}\n\ Union of @var{subt} and @var{clip}.\n\n\ @item @var{'AB'}\n\ Operation @var{sub} - @var{clip}.\n\n\ @item @var{'BA'}\n\ Operation of @var{clip} - @var{sub}.\n\ @end itemize\n\ \n\ For the matrices @var{sub} and @var{clip}, the first point is not needed to\n\ be repeated at the end (but is permitted). Pairs of (NaN,NaN) coordinates in\n\ @var{sub} and/or @var{clip} are ommitted.\n\ \n\ @var{X} is a column vector containing the X coordinates of the vertices of\n\ the resultant polygon(s).\n\n\ @var{Y} is a column vector containing the Y coordinates of the vertices of\n\ the resultant polygon(s).\n\n\ @var{nPol} is the number of output polygons.\n\n\ @var{nInt} is the number of intersections between @var{sub} and @var{clip}.\n\n\ @var{nPert} is the number of perturbed points of the @var{clip} polygon in\n\ any particular case (points in the oborder of the other polygon) occurs see\n\ http://davis.wpi.edu/~matt/courses/clipping/ for details.\n\ \n\ This function do not check if the dimensions of @var{sub} and @var{clip} are\n\ correct.\n\ \n\ @end deftypefn" /******************************************************************************/ /******************************************************************************/ #include #include #include #include #include #include"octclip.h" /******************************************************************************/ /******************************************************************************/ #define ERRORTEXT 1000 /******************************************************************************/ /******************************************************************************/ DEFUN_DLD(_oc_polybool,args,,HELPTEXT) { //error message char errorText[ERRORTEXT+1]="_oc_polybool:\n\t"; //output list octave_value_list outputList; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //checking input arguments if(args.length()!=3) { //error text sprintf(&errorText[strlen(errorText)], "Incorrect number of input arguments\n\t" "See help _oc_polybool"); //error message error(errorText); } else { //loop index size_t i=0; //polygons and operation ColumnVector xSubj=args(0).matrix_value().column(0); ColumnVector ySubj=args(0).matrix_value().column(1); ColumnVector xClip=args(1).matrix_value().column(0); ColumnVector yClip=args(1).matrix_value().column(1); std::string opchar=args(2).string_value(); //computation vectors double* xA=NULL; double* yA=NULL; double* xB=NULL; double* yB=NULL; //double linked lists vertPoliClip* polA=NULL; vertPoliClip* polB=NULL; //operation identifier enum GEOC_OP_BOOL_POLIG op=GeocOpBoolInter; //output struct polig* result=NULL; //number of polygons, intersections and perturbations size_t nPol=0,nInter=0,nPert=0; //number of elements for the output vectors size_t nElem=0; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //pointers to data xA = xSubj.fortran_vec(); yA = ySubj.fortran_vec(); xB = xClip.fortran_vec(); yB = yClip.fortran_vec(); //create double linked lists for subject and clipper polygons polA = CreaPoliClip(xA,yA,static_cast(xSubj.length()),1,1); polB = CreaPoliClip(xB,yB,static_cast(xClip.length()),1,1); //error checking if((polB==NULL)||(polB==NULL)) { //free peviously allocated memory LibMemPoliClip(polA); LibMemPoliClip(polB); //error text sprintf(&errorText[strlen(errorText)],"Error in memory allocation"); //error message error(errorText); //exit return outputList; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //select operation if((!strcmp(opchar.c_str(),"AND"))||(!strcmp(opchar.c_str(),"and"))) { op = GeocOpBoolInter; } else if((!strcmp(opchar.c_str(),"OR"))||(!strcmp(opchar.c_str(),"or"))) { op = GeocOpBoolUnion; } else if((!strcmp(opchar.c_str(),"AB"))||(!strcmp(opchar.c_str(),"ab"))) { op = GeocOpBoolAB; } else if((!strcmp(opchar.c_str(),"BA"))||(!strcmp(opchar.c_str(),"ba"))) { op = GeocOpBoolBA; } else { //free peviously allocated memory LibMemPoliClip(polA); LibMemPoliClip(polB); //error text sprintf(&errorText[strlen(errorText)], "The third input argument (op=%s) is not correct", opchar.c_str()); //error message error(errorText); //exit return outputList; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //clipping result = PoliBoolGreiner(polA,polB,op,GEOC_GREINER_FAC_EPS_PERTURB, &nInter,&nPert); //error checking if(result==NULL) { //free peviously allocated memory LibMemPoliClip(polA); LibMemPoliClip(polB); //error text sprintf(&errorText[strlen(errorText)],"Error in memory allocation"); //error message error(errorText); //exit return outputList; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //number or output polygons nPol = result->nPolig; //dimensions for the output vectors if(nPol) { nElem = result->nElem; } else { nElem = 0; } //output vectors ColumnVector xResult(nElem); ColumnVector yResult(nElem); //copy output data for(i=0;ix[i]; yResult(i) = result->y[i]; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //output parameters list outputList(0) = xResult; outputList(1) = yResult; outputList(2) = nPol; outputList(3) = nInter; outputList(4) = nPert; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //free memory LibMemPoliClip(polA); LibMemPoliClip(polB); LibMemPolig(result); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //exit return outputList; } geometry/src/octclip/compilador.c0000644000175000017500000000744112035672422017001 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup general geopot @{ \file compilador.c \brief Definición de funciones para la detección de compiladores. \author José Luis García Pallero, jgpallero@gmail.com \date 28 de abril de 2011 \version 1.0 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/compilador.h" /******************************************************************************/ /******************************************************************************/ int EsCompiladorGNU(int* noGnu) { //variable de salida int salida=0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos la variable noGnu, si ha lugar if(noGnu!=NULL) { //inicializamos la variable a 0 *noGnu = 0; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //para que sea GCC, la constante __GNUC__ ha de estar definida #if defined(__GNUC__) //el compilador es GCC salida = 1; //comprobamos si es el compilador de intel #if defined(__INTEL_COMPILER) if(noGnu!=NULL) { //el compilador es de intel *noGnu = 1; } #endif #endif //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return salida; } /******************************************************************************/ /******************************************************************************/ /** @} */ /******************************************************************************/ /******************************************************************************/ /* 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; */ geometry/src/octclip/dpeucker.c0000644000175000017500000004552412035672422016456 0ustar juanpijuanpi/* -*- coding: utf-8 -*- */ /** \ingroup geom @{ \file dpeucker.c \brief Definición de funciones para el aligerado de polilíneas basadas en el algoritmo de Douglas-Peucker. \author José Luis García Pallero, jgpallero@gmail.com \date 04 de julio de 2011 \section Licencia Licencia Copyright (c) 2011, José Luis García Pallero. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 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. 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. */ /******************************************************************************/ /******************************************************************************/ #include"libgeoc/dpeucker.h" /******************************************************************************/ /******************************************************************************/ size_t* AligeraPolilinea(const double* x, const double* y, const size_t nPtos, const size_t incX, const size_t incY, const double tol, const enum GEOC_DPEUCKER_ROBUSTO robusto, const size_t nPtosRobusto, const size_t nSegRobusto, size_t* nPtosSal) { //índice para recorrer bucles size_t p=0; //índice de los puntos de trabajo size_t i=0,j=0,k=0; //coordenadas de trabajo double xIni=0.0,yIni=0.0,xFin=0.0,yFin=0.0,xTrab=0.0,yTrab=0.0; //altura del triángulo de trabajo double h=0.0; //variable indicadora de punto a mantener int usado=0; //número de elementos de trabajo internos del vector de salida size_t nElem=0; //vector de salida size_t* sal=NULL; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //iniciamos la variable de salida de número de puntos a 0 *nPtosSal = 0; //comprobamos casos especiales de nPtos if(nPtos==0) { //salimos de la función con NULL return NULL; } else if(nPtos<=2) { //asignamos el número de puntos usados *nPtosSal = nPtos; //asignamos memoria para el vector de salida sal = (size_t*)malloc((*nPtosSal)*sizeof(size_t)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //asignamos valores al vector de salida for(i=0;i<(*nPtosSal);i++) { //asignamos el índice de trabajo sal[i] = i; } //salimos de la función return sal; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //inicializamos el indicador interno de tamaño del vector nElem = GEOC_DPEUCKER_BUFFER_PTOS; //asignamos memoria para el vector de salida sal = (size_t*)malloc(nElem*sizeof(size_t)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } //indicamos que el primer punto siempre se usa *nPtosSal = 1; sal[0] = 0; //puntos de trabajo para iniciar los cálculos i = 0; j = 1; k = 2; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //entramos en un bucle infinito while(1) { //comprobamos si hay que salir del bucle if(k>(nPtos-1)) { //salimos del bucle break; } //coordenadas de la base del triángulo xIni = x[i*incX]; yIni = y[i*incY]; xFin = x[k*incX]; yFin = y[k*incY]; //inicializamos a 0 la variable de punto usado usado = 0; //recorremos los puntos a testear for(p=j;ptol) { //indicamos que el punto ha sido usado usado = 1; //comprobamos si se utiliza el algoritmo robusto if(robusto!=GeocDPeuckerRobNo) { //comprobamos si hay que aplicar el algoritmo de //intersección con puntos originales if((robusto==GeocDPeuckerRobSi)|| (robusto==GeocDPeuckerRobOrig)) { //aplicamos el algoritmo AligPolilRobIntersecOrig(x,y,nPtos,incX,incY, nPtosRobusto,i,&p); } //comprobamos si hay que aplicar el algoritmo de auto //intersección if((robusto==GeocDPeuckerRobSi)|| (robusto==GeocDPeuckerRobAuto)) { //indicamos un número de puntos para el vector de salida //una unidad menor que el número realmente almacenado //para evitar el segmento inmediatamente anterior al que //vamos a crear AligPolilRobAutoIntersec(x,y,incX,incY,sal, (*nPtosSal)-1,nSegRobusto,i, &p); } } //añadimos al contador este nuevo punto (*nPtosSal)++; //comprobamos si hay que reasignar memoria if((*nPtosSal)>nElem) { //añadimos otro grupo de puntos nElem += GEOC_DPEUCKER_BUFFER_PTOS; //asignamos memoria para el vector de salida sal = (size_t*)realloc(sal,nElem*sizeof(size_t)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //añadimos el nuevo punto usado sal[(*nPtosSal)-1] = p; //actualizamos los índices de los puntos de trabajo i = p; j = i+1; k = j+1; //salimos del bucle break; } } //comprobamos si no se ha utilizado ninguno de los vértices candidatos if(!usado) { //pasamos al siguiente punto como extremo del segmento k++; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si el último punto se ha añadido if(sal[(*nPtosSal)-1]!=(nPtos-1)) { //añadimos al contador el último punto (*nPtosSal)++; //comprobamos si hay que reasignar memoria if((*nPtosSal)>nElem) { //añadimos otro grupo de puntos nElem += GEOC_DPEUCKER_BUFFER_PTOS; //asignamos memoria para el vector de salida sal = (size_t*)realloc(sal,nElem*sizeof(size_t)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //asignamos el último punto sal[(*nPtosSal)-1] = nPtos-1; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //comprobamos si el vector de salida tiene demasiada memoria asignada if(nElem>(*nPtosSal)) { //ajustamos el tamaño del vector de salida sal = (size_t*)realloc(sal,(*nPtosSal)*sizeof(size_t)); //comprobamos los posibles errores if(sal==NULL) { //mensaje de error GEOC_ERROR("Error de asignación de memoria"); //salimos de la función return NULL; } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return sal; } /******************************************************************************/ /******************************************************************************/ void AligPolilRobIntersecOrig(const double* x, const double* y, const size_t nPtos, const size_t incX, const size_t incY, const size_t ptosAUsar, const size_t posIni, size_t* posFin) { //índices para recorrer bucles size_t i=0,j=0; //coordenadas de trabajo double xA=0.0,yA=0.0,xB=0.0,yB=0.0,xC=0.0,yC=0.0,xD=0.0,yD=0.0; //punto de parada para comprobar la intersección de segmentos size_t parada=0; //identificador de intersección int inter=0; //variables auxiliares size_t aux=0; double xAux=0.0,yAux=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contemplamos una posible salida rápida if((*posFin)<=(posIni+1)) { //salimos de la función return; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el número de puntos que quedan hasta el final de los vectores //de coordenadas desde la posición de fin de segmento (contándola) aux = nPtos-(*posFin); //calculamos el punto de parada para la intersección de segmentos if((aux>ptosAUsar)&&(ptosAUsar!=0)) { //paramos en un pnto tal que usemos ptosAUsar puntos parada = *posFin+ptosAUsar-1; } else { //paramos en el penúltimo punto parada = nPtos-2; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //las coordenadas del punto inicial del segmento base no cambian nunca xA = x[posIni*incX]; yA = y[posIni*incY]; //recorremos los puntos candidatos hasta el anterior al punto base for(i=(*posFin);i>posIni;i--) { //comprobamos si estamos ante el punto posterior al inicial if(i==(posIni+1)) { //terminamos, porque este punto es el siguiente al punto base en el //listado original *posFin = i; //salimos del bucle break; } else { //coordenadas de los puntos inicial y final del segmento base xB = x[i*incX]; yB = y[i*incY]; //recorremos los puntos posteriores hasta el de parada for(j=i;j<=parada;j++) { //coordenadas de los puntos inicial y final del siguiente //segmento xC = x[j*incX]; yC = y[j*incY]; xD = x[(j+1)*incX]; yD = y[(j+1)*incY]; //calculamos la intersección entre los segmentos inter = IntersecSegmentos2D(xA,yA,xB,yB,xC,yC,xD,yD,&xAux, &yAux); //comprobamos si hay intersección entre los segmentos if(inter!=GEOC_SEG_NO_INTERSEC) { //salimos del bucle break; } } //comprobamos si no ha habido ninguna intersección if(inter==GEOC_SEG_NO_INTERSEC) { //indicamos el índice del vértice final *posFin = i; //salimos del bucle break; } } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //salimos de la función return; } /******************************************************************************/ /******************************************************************************/ void AligPolilRobAutoIntersec(const double* x, const double* y, const size_t incX, const size_t incY, const size_t* posAlig, const size_t nPosAlig, const size_t segAUsar, const size_t posIni, size_t* posFin) { //índices para recorrer bucles size_t i=0,j=0; //variables de posición size_t k=0,l=0,pos=0; //coordenadas de trabajo double xA=0.0,yA=0.0,xB=0.0,yB=0.0,xC=0.0,yC=0.0,xD=0.0,yD=0.0; //número de segmentos calculados hasta ahora, excepto el último size_t nSeg=0; //identificador de intersección int inter=0; //variables auxiliares double xAux=0.0,yAux=0.0; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //contemplamos una posible salida rápida if(((*posFin)<=(posIni+1))||(nPosAlig<2)) { //salimos de la función return; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //calculamos el número de segmentos calculados hasta ahora, excepto el //anterior al de trabajo nSeg = nPosAlig-1; //comprobamos si se usan todos los segmentos o sólo parte if(segAUsar!=0) { //asignamos el número de segmentos a utilizar nSeg = (nSeg>segAUsar) ? segAUsar : nSeg; } //las coordenadas del punto inicial del segmento base no cambian nunca xA = x[posIni*incX]; yA = y[posIni*incY]; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //recorremos los puntos candidatos hasta el anterior al punto base for(i=(*posFin);i>posIni;i--) { //comprobamos si estamos ante el punto posterior al inicial if(i==(posIni+1)) { //terminamos, porque este punto es el siguiente al punto inicial *posFin = i; //salimos del bucle break; } else { //coordenadas del punto final del segmento base xB = x[i*incX]; yB = y[i*incY]; //recorremos el número de segmentos de trabajo for(j=0;j> Computational Geometry 2D Descriptive geom2d_Contents points2d vectors2d angles2d edges2d rays2d lines2d boxes2d circles2d ellipses2d transforms2d polygons2d 2D Points centroid closed_path distancePoints drawPoint isCounterClockwise isPointOnRay isPointInCircle isPointOnCircle isPointOnLine isPointInEllipse midPoint minDistancePoints polarPoint 2D Vectors createVector vectorNorm normalizeVector rotateVector 2D Angles angle2Points angle3Points angleAbsDiff angleDiff normalizeAngle vectorAngle angleSort lineAngle edgeAngle deg2rad rad2deg 2D Edges createEdge distancePointEdge drawCenteredEdge drawEdge edgeLength edgePosition edgeToLine intersectEdges intersectLineEdge reverseEdge transformEdge isPointOnEdge 2D Rays drawRay createRay 2D Lines cartesianLine createLine distancePointLine drawLine intersectLines isParallel isPerpendicular linePosition medianLine isLeftOriented orthogonalLine parallelLine pointOnLine projPointOnLine reverseLine 2D Boxes clipEdge clipLine clipPoints clipRay mergeBoxes intersectBoxes drawBox randomPointInBox drawRect drawOrientedBox 2D Circles createCircle createDirectedCircle circleArcAsCurve circleAsPolygon drawCircleArc drawCircle enclosingCircle intersectCircles intersectLineCircle radicalAxis 2D Ellipses cov2ellipse drawEllipseArc drawEllipse ellipseAsPolygon ellipse2cov inertiaEllipse 2D Transformations transformLine transformPoint transformVector createBasisTransform createHomothecy createLineReflection createRotation createScaling createTranslation fitAffineTransform2d 2D Cubic Bezier drawBezierCurve cbezier2poly 2D Polygons curvature distancePolygons distancePointPolygon distancePointPolyline drawPolygon drawPolyline expandPolygon medialAxisConvex oc_polybool parametrize polygonLoops polygonPoint polygonSubcurve polygonSelfIntersections polylineSelfIntersections reversePolyline reversePolygon simplifypolygon simplifypolyline splitPolygons supportFunction 2D Piecewise polynomial shapes polygon2shape shape2polygon shapecentroid shapeplot shapetransform curveval curve2polyline 2D Polynomial curves drawPolynomialCurve polynomialCurveCentroid polynomialCurveDerivative polynomialCurveFit polynomialCurvePoint polynomialCurveSetFit 2D Others beltproblem bisector crackPattern2 crackPattern drawArrow drawLabels drawParabola drawShape hexagonalGrid squareGrid triangleGrid 3D Descriptive geom3d_Contents meshes3d_Contents angles3d boxes3d circles3d lines3d planes3d points3d polygons3d spheres vectors3d 3D Points anglePoints3d angleSort3d distancePoints drawPoint3d projPointOnPlane 3D Lines distancePointLine3d 3D Edges drawEdge3d drawSphericalEdge 3D Planes createPlane intersectLinePlane intersectPlaneSphere normalizePlane planeNormal planePosition projPointOnPlane 3D Meshes createCubeOctahedron createCube drawCube drawMesh 3D Spheres circle3dOrigin circle3dPoint circle3dPosition drawCircle3d drawCircleArc3d drawSphere drawSphericalTriangle 3D Boxes boundingBox3d box3dVolume drawBox3d 3D Polygons drawPolygon3d drawPolyline3d drawSphericalPolygon polygonArea3d 3D Transformations createRotationOx createRotationOy createRotationOz createTranslation3d createScaling3d transformPoint3d 3D Others cart2cyl cart2sph2 cart2sph2d cyl2cart drawAxis3d drawCylinder drawTorus drawVector3d revolutionSurface sph2cart2 sph2cart2d vectorAngle3d Geometric graphs descriptive graphs_Contents Geometric graphs creation delaunayGraph knnGraph voronoi2d Geometric graphs visualization drawGraph Geometric graphs manipulation Input @svg/svg @svg/plot @svg/getpath @svg/path2polygon @svg/normalize @svg/pathid @svg/height @svg/width Output data2geo geometry/NEWS0000644000175000017500000002270512130272770012755 0ustar juanpijuanpiSummary of important user-visible changes for releases of the geometry package =============================================================================== geometry-1.7.0 Release Date: 2013-04-07 Release Manager: Juan Pablo Carbajal =============================================================================== ** Added Functions box3dVolume cart2cyl circle3dPoint cyl2cart drawCircle3d drawPoint3d createScaling3d drawCube createCube drawSphericalTriangle drawTorus revolutionSurface drawVector3d spheres drawPolyline drawPolynomialCurve polynomialCurveCentroid polynomialCurveDerivative polynomialCurveFit polynomialCurvePoint polynomialCurveSetFit polygonPoint polygonSubcurve ** Bug Fixes: - cov2ellipse scale and orientation of axis. =============================================================================== geometry-1.6.0 Release Date: 2012-10-12 Release Manager: Juan Pablo Carbajal =============================================================================== ** geometry doesn't autoloads anymore ** Added Functions anglePoints3d angles3d boxes3d geom3d_Contents lines3d planes3d points3d polygons3d vectors3d graphs_Contents meshes3d_Contents angleSort3d createPlane intersectLinePlane normalizePlane planeNormal planePosition projPointOnPlane sph2cart2 vectorAngle3d distancePointLine3d cart2sph2d createRotationOx createRotationOy createRotationOz createTranslation3d drawAxis3d drawCylinder drawSphere polygonArea3d transformPoint3d drawBox3d drawEdge3d drawMesh createCubeOctahedron boundingBox3d cart2sph2 circle3dOrigin circle3dPosition drawCircleArc3d drawPolygon3d drawSphericalEdge drawSphericalPolygon intersectPlaneSphere sph2cart2d ** Updated functions distancePoints ** Bug Fixes: - drawArrow was not working due to porting errors. =============================================================================== geometry-1.5.0 Release Date: 2012-06-05 Release Manager: Juan Pablo Carbajal =============================================================================== * Added functions: - cov2ellipse & ellipse2cov: transform between ellipses and covariances matrices. - beltproblem : Finds the four lines tangent to two circles with given centers and radii. This is the solution to the belt problem in 2D. - curveval : Evaluates a polynomial curve defined as a 2-by-N matrix. - curve2polyline : Converts a polynomial curve into a polyline by the adaptive sampling method. - simplifypolyline : Ramer-Douglas-Peucker algorithm to simplify polylines. - parametrize : Estimate a parametrization of a polygon/line based on the distance between the points. - curvature : Estimation of the curvature of a polygon/line based on polynomial approximation. - reversePolygon and reversePolyline : reverse the orders of the points in of polygon/line. - supportFunction : Compute support function of a polygon. - distancePointPolygon , distancePointPolyline , distancePolygons , expandPolygon , medialAxisConvex , polygonLoops , polygonSelfIntersections polylineSelfIntersections , splitPolygons - close_path : given a set of points in the plane calculate a piecewise linear simple path that passes through all points. * Changed functions: - distancePointEdge : Now the function computes the distance between all points and all edges. A third optional argument provides backward compatibility. * Solved bugs: - simplifypolygon returned empty polygons when points are repeated, i.e when the polygon is not correctly formed. - Removed installation warnings. =============================================================================== geometry-1.4.1 Release Date: 2012-03-24 Release Manager: Juan Pablo Carbajal =============================================================================== * Renamed functions - Contents renamed to geom2d_Contents to avoid clashes. * Deprecated functions - svgload, svgnormalize, svgpath2polygon: Use the methods in class svg. * Bug fixes - @svg/path2polygon - Fix addpath/rmpath installation warnings - Fix octclip/src/Makefile - Fix shapecentriod for piece-wise polynomial shapes. * Known issues - simplifypolygon returns empty polygons when points are repeated, i.e when the polygon is not correctly formed. =============================================================================== geometry-1.4.0 Release Date: 2012-01-25 Release Manager: Juan Pablo Carbajal =============================================================================== * Added basic geometric graphs creation and manipulation. =============================================================================== geometry-1.3.0 Release Date: 2011-11-24 Release Manager: Juan Pablo Carbajal =============================================================================== * Geometry merged with octCLIP. * Geometry autoloads. =============================================================================== geometry-1.2.2 Release Date: 2011-11-04 Release Manager: Juan Pablo Carbajal =============================================================================== * Improved SVG interface. Thanks to jwe and carandraug. * Adding files to manipulate and convert 2D shapes defined with smooth polynomials. shape2polygon shapearea shapecentroid shapeplot shapetransform * Inverted the order in the NEWS file. New entries are on top. =============================================================================== geometry-1.2.1 Release Date: 2011-11-02 Release Manager: Juan Pablo Carbajal =============================================================================== * Adding SVG object and demo for data2geom (converting SVG to msh format) =============================================================================== geometry-1.2.0 Release Date: 2011-10-21 Release Manager: Juan Pablo Carbajal =============================================================================== * All geom2d added createCircle createDirectedCircle createEdge medianLine Contents bisector cartesianLine drawArrow edges2d lines2d orthogonalLine parallelLine projPointOnLine drawCenteredEdge drawCircle drawCircleArc drawEllipse drawEllipseArc drawLabels drawOrientedBox drawParabola drawRect drawShape circles2d ellipses2d createVector inertiaEllipse changelog.txt readme.txt hexagonalGrid squareGrid triangleGrid intersectCircles intersectEdges intersectLineCircle isLeftOriented isPointInCircle isPointInEllipse isPointOnCircle isPointOnLine edgeLength edgePosition edgeToLine circleArcAsCurve circleAsPolygon crackPattern crackPattern2 distancePointEdge distancePointLine ellipseAsPolygon enclosingCircle radicalAxis reverseEdge reverseLine =============================================================================== geometry-1.1.3 Release Date: 2011-10-13 Release Manager: Juan Pablo Carbajal =============================================================================== * Continue to add geom2d from matGeom (transforms and points2d) createBasisTransform createHomothecy createLineReflection createRotation createScaling createTranslation transformPoint transforms2d fitAffineTransform2d transformEdge transformLine centroid distancePoints midPoint polarPoint drawPoint isCounterClockwise minDistancePoints pointOnLine points2d intersectLineEdge isPointOnEdge =============================================================================== geometry-1.1.2 Release Date: 2011-10-09 Release Manager: Juan Pablo Carbajal =============================================================================== * Continue to add geom2d from matGeom (rays and vectors) createRay drawEdge drawRay isParallel isPerpendicular isPointOnRay normalizeVector rays2d rotateVector transformVector vectorNorm vectors2d =============================================================================== geometry-1.1.1 Release Date: 2011-10-06 Release Manager: Juan Pablo Carbajal =============================================================================== * Continue to add geom2d from matGeom (boxes and clips) cbezier2poly boxes2d clipEdge clipLine clipPoints drawBezierCurve drawBox clipRay intersectBoxes intersectLines linePosition mergeBoxes randomPointInBox drawLine =============================================================================== geometry-1.1.0 Release Date: 2011-10-04 Release Manager: Juan Pablo Carbajal =============================================================================== * Starting to add geom2d from matGeom angle2Points angle3Points angleAbsDiff angleDiff angles2d angleSort createLine deg2rad edgeAngle lineAngle normalizeAngle rad2deg vectorAngle =============================================================================== geometry-1.0.1 Release Date: 2011-09-27 Release Manager: Juan Pablo Carbajal =============================================================================== Improvements to the docstrings of all functions. =============================================================================== geometry-1.0.0 Release Date: 2011-09-26 Release Manager: Juan Pablo Carbajal =============================================================================== ** First official release. =============================================================================== geometry/pre_install.m0000644000175000017500000000140012035672422014737 0ustar juanpijuanpifunction pre_install (desc) %{ %% Prepares for installation a package that is organized in subfolders %% List of folders with src subfolder subfld = {"octclip"}; %% Create correct strings subfld_ready = strcat ({[pwd() filesep() "inst" filesep()]}, subfld,[filesep() "src" filesep() "*"]); %% Destination folder to_fld = strcat (pwd (),[filesep() "src"]); %% Copy files to package/src folder %% TODO handle merging of Makefiles warning ("Copying subfolder src to package main dir, but multiple Makefiles are not handled") if !exist("src","dir") system(["mkdir " to_fld]); end for from_fld = subfld_ready system (["mv " from_fld{1} " " to_fld]); system (["rm -R " from_fld{1}(1:end-2)]); end %} end geometry/DESCRIPTION0000644000175000017500000000125012130272770013754 0ustar juanpijuanpiName: Geometry Version: 1.7.0 Date: 2013-04-07 Author: David Legland , Jose Luis Garcia Pallero , Juan Pablo Carbajal , Simeon Simeonov Maintainer: Juan Pablo Carbajal Title: Computational Geometry Description: Library for geometric computing extending MatGeom functions. Useful to create, transform, manipulate and display geometric primitives. Depends: octave (>= 3.4.0), general (>= 1.3.0) Autoload: no License: GPLv3+, FreeBSD Url: http://octave.sf.net, http://matgeom.sf.net, http://davis.wpi.edu/~matt/courses/clipping/, https://bitbucket.org/jgpallero/octclip geometry/PKG_DEL0000644000175000017500000000273712114701140013277 0ustar juanpijuanpi%1 dirlist = {"geom2d","io","polygons2d","shape2d","octclip", "graphs",... "geom3d","meshes3d","polynomialCurves2d"}; dirname = fileparts (canonicalize_file_name (mfilename ("fullpath"))); pp = strsplit (dirname,filesep (), true); arch = cstrcat (octave_config_info ("canonical_host_type"), "-", octave_config_info ("api_version")); %% Get the correct path % Search installed packages [local_packages, global_packages] = pkg("list"); installed_pkgs_lst = {local_packages{:}, global_packages{:}}; pkg_data = installed_pkgs_lst (cellfun(@(x) ismember (x.name, {"geometry"}), ... installed_pkgs_lst, "unif", true)); if isempty(pkg_data) % The package is not installed yet [pkg_folder dep_folder] = pkg ("prefix"); pkg_folder = [pkg_folder strcat(filesep(),{pp{end}}){:} ]; if strcmp (arch , pp{end}) %% If we are in Architecture dependent folder add from outside pkg_folder = strsplit (pkg_folder,filesep (), true); pkg_folder = [strcat(filesep(),{pkg_folder{1:end-1}}){:}]; end else pkg_folder = pkg_data{1}.dir; end if (! exist (fullfile (dirname, "inst"), "dir")) ## Run this if the package is installed for ii=1:length (dirlist) rmpath ( [ pkg_folder filesep() dirlist{ii}]) endfor else warning("geometry:Devel","Removing path for testing."); for ii=1:length(dirlist) rmpath ([ dirname "/inst/" dirlist{ii}]) endfor endif clear dirlist dirname pp arch pkg_folder dep_folder geometry/COPYING0000644000175000017500000010451311650352637013316 0ustar juanpijuanpi GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . geometry/PKG_ADD0000644000175000017500000000312412114701140013252 0ustar juanpijuanpi%1 dirlist = {"geom2d","io","polygons2d","shape2d","octclip", "graphs",... "geom3d","meshes3d","polynomialCurves2d"}; dirname = fileparts (canonicalize_file_name (mfilename ("fullpath"))); %keyboard pp = strsplit (dirname,filesep (), true); arch = cstrcat (octave_config_info ("canonical_host_type"), "-", octave_config_info ("api_version")); %% Get the correct path % Search installed packages [local_packages, global_packages] = pkg("list"); installed_pkgs_lst = {local_packages{:}, global_packages{:}}; pkg_data = installed_pkgs_lst (cellfun(@(x) ismember (x.name, {"geometry"}), ... installed_pkgs_lst, "unif", true)); if isempty(pkg_data) % The package is not installed yet [pkg_folder dep_folder] = pkg ("prefix"); pkg_folder = [pkg_folder strcat(filesep(),{pp{end}}){:} ]; if strcmp (arch , pp{end}) %% If we are in Architecture dependent folder add from outside pkg_folder = strsplit (pkg_folder,filesep (), true); pkg_folder = [strcat(filesep(),{pkg_folder{1:end-1}}){:}]; end else pkg_folder = pkg_data{1}.dir; end if (! exist (fullfile (dirname, "inst"), "dir")) %% Installing for ii=1:length (dirlist) addpath ( [ pkg_folder filesep() dirlist{ii}],"-end") endfor else %% Testing warning("geometry:Devel","Adding path for testing."); for ii=1:length(dirlist) addpath ([ dirname "/inst/" dirlist{ii}]) endfor endif warning('off', 'Octave:fopen-file-in-path'); clear dirlist dirname pp arch pkg_folder dep_folder clear global_packages ii installed_pkgs_lst local_packages pkg_data geometry/inst/0000755000175000017500000000000012130273004013214 5ustar juanpijuanpigeometry/inst/geom3d/0000755000175000017500000000000012130276034014400 5ustar juanpijuanpigeometry/inst/geom3d/angles3d.m0000644000175000017500000000621312035504503016257 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} angles3d () ##ANGLES3D Conventions for manipulating angles in 3D ## ## Contrary to the plane, there are no oriented angles in 3D. Angles ## between lines or between planes are comprised between 0 and PI. ## ## Spherical angles ## Spherical angles are defined by 2 angles: ## * THETA, the colatitude, representing angle with Oz axis (between 0 and ## PI) ## * PHI, the azimut, representing angle with Ox axis of horizontal ## projection of the direction (between 0 and 2*PI) ## ## Spherical coordinates can be represented by THETA, PHI, and the ## distance RHO to the origin. ## ## Euler angles ## Some functions for creating rotations use Euler angles. They follow the ## ZYX convention in the global reference system, that is eqivalent to the ## XYZ convention ine a local reference system. ## Euler angles are given by a triplet of angles [PHI THETA PSI] that ## represents the succession of 3 rotations: ## * rotation around X by angle PSI ("roll") ## * rotation around Y by angle THETA ("pitch") ## * rotation around Z by angle PHI ("yaw") ## ## In this library, euler angles are given in degrees. The functions that ## use euler angles use the keyword 'Euler' in their name. ## ## ## @seealso{cart2sph2, sph2cart2, cart2sph2d, sph2cart2d ## anglePoints3d, angleSort3d, sphericalAngle, randomAngle3d ## dihedralAngle, polygon3dNormalAngle, eulerAnglesToRotation3d ## rotation3dAxisAndAngle, rotation3dToEulerAngles} ## @end deftypefn function angles3d() help angles3d endfunction geometry/inst/geom3d/intersectLinePlane.m0000644000175000017500000000764312035673610020365 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pt} =} intersectLinePlane (@var{line}, @var{plane}) ## @deftypefnx {Function File} {@var{pt} =} intersectLinePlane (@dots{}, @var{tol}) ## Intersection point between a 3D line and a plane ## ## PT = intersectLinePlane(LINE, PLANE) ## Returns the intersection point of the given line and the given plane. ## LINE: [x0 y0 z0 dx dy dz] ## PLANE: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] ## PT: [xi yi zi] ## If LINE and PLANE are parallel, return [NaN NaN NaN]. ## If LINE (or PLANE) is a matrix with 6 (or 9) columns and N rows, result ## is an array of points with N rows and 3 columns. ## ## PT = intersectLinePlane(LINE, PLANE, TOL) ## Specifies the tolerance factor to test if a line is parallel to a ## plane. Default is 1e-14. ## ## Example ## @example ## # define horizontal plane through origin ## plane = [0 0 0 1 0 0 0 1 0]; ## # intersection with a vertical line ## line = [2 3 4 0 0 1]; ## intersectLinePlane(line, plane) ## ans = ## 2 3 0 ## # intersection with a line "parallel" to plane ## line = [2 3 4 1 2 0]; ## intersectLinePlane(line, plane) ## ans = ## NaN NaN NaN ## @end example ## ## @seealso{lines3d, planes3d, points3d, clipLine3d} ## @end deftypefn function point = intersectLinePlane (line, plane, varargin) # extract tolerance if needed tol = 1e-14; if nargin > 2 tol = varargin{1}; end # unify sizes of data nLines = size (line, 1); nPlanes = size (plane, 1); # N planes and M lines not allowed if nLines ~= nPlanes && min (nLines, nPlanes) > 1 error ('geometry:geom3d:intersectLinePlane', ... 'Input must have same number of rows, or one must be 1'); end # plane normal n = cross (plane(:,4:6), plane(:,7:9)); # difference between origins of plane and line dp = bsxfun (@minus, plane(:, 1:3), line(:, 1:3)); # dot product of line direction with plane normal denom = sum (bsxfun (@times, n, line(:,4:6)), 2); # relative position of intersection point on line (can be inf in case of a # line parallel to the plane) t = sum (bsxfun (@times, n, dp),2) ./ denom; # compute coord of intersection point point = bsxfun (@plus, line(:,1:3), bsxfun (@times, [t t t], line(:,4:6))); # set indices of line and plane which are parallel to NaN par = abs (denom) < tol; point(par,:) = NaN; endfunction geometry/inst/geom3d/boundingBox3d.m0000644000175000017500000000545312035504503017271 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{box} =} boundingBox3d (@var{points}) ## Bounding box of a set of 3D points ## ## Returns the bounding box of the set of points POINTS. POINTS is a ## N-by-3 array containing points coordinates. The result BOX is a 1-by-6 ## array, containing: ## [XMIN XMAX YMIN YMAX ZMIN ZMAX] ## ## Example ## @group ## # Draw bounding box of a cubeoctehedron ## [v e f] = createCubeOctahedron; ## box3d = boundingBox3d(v); ## figure; hold on; ## drawMesh(v, f); ## drawBox3d(box3d); ## axis([-2 2 -2 2 -2 2]); ## view(3) ## @end group ## ## @seealso{boxes3d, drawBox3d} ## @end deftypefn function box = boundingBox3d(points) # compute extreme x and y values xmin = min(points(:,1)); xmax = max(points(:,1)); ymin = min(points(:,2)); ymax = max(points(:,2)); box = [xmin xmax ymin ymax]; # process case of 3D points if size(points, 2) > 2 zmin = min(points(:,3)); zmax = max(points(:,3)); box = [xmin xmax ymin ymax zmin zmax]; end endfunction %!demo %! # Draw bounding box of a cubeoctehedron %! [v e f] = createCubeOctahedron; %! box3d = boundingBox3d(v); %! figure; hold on; %! drawMesh(v, f); %! drawBox3d(box3d); %! axis([-2 2 -2 2 -2 2]); %! view(3) geometry/inst/geom3d/drawAxis3d.m0000644000175000017500000000542412035504503016573 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawAxis3d () ## @deftypefnx {Function File} drawAxis3d (@var{l},@var{r}) ## Draw a coordinate system and an origin ## ## Adds 3 cylinders to the current axis, corresponding to the directions ## of the 3 basis vectors Ox, Oy and Oz. ## Ox vector is red, Oy vector is green, and Oz vector is blue. ## ## @var{l} specifies the length and @var{r} the radius of the cylinders ## representing the different axes. ## ## WARNING: This function doesn't work in gnuplot (as of version 4.2). ## ## @seealso{drawAxisCube} ## @end deftypefn function drawAxis3d(L=1,r=1/10) if strcmpi (graphics_toolkit(),"gnuplot") error ("geometry:Incompatibility", ... ["This function doesn't work with gnuplot (as of version 4.1)." ... "Use graphics_toolkit('fltk').\n"]); end # geometrical data origin = [0 0 0]; v1 = [1 0 0]; v2 = [0 1 0]; v3 = [0 0 1]; # draw 3 cylinders and a ball hold on; drawCylinder([origin origin+v1*L r], 16, 'facecolor', 'r', 'edgecolor', 'none'); drawCylinder([origin origin+v2*L r], 16, 'facecolor', 'g', 'edgecolor', 'none'); drawCylinder([origin origin+v3*L r], 16, 'facecolor', 'b', 'edgecolor', 'none'); drawSphere([origin 2*r], 'faceColor', 'black'); endfunction geometry/inst/geom3d/transformPoint3d.m0000644000175000017500000001211612035673610020040 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pt2} =} transformPoint3d (@var{pt1}, @var{trans}) ## @deftypefnx {Function File} {@var{pt2} =} transformPoint3d (@var{x1},@var{y1},@var{z1}, @var{trans}) ## @deftypefnx {Function File} {[@var{x2},@var{y2},@var{z2}] =} transformPoint3d (@dots{}) ## Transform a point with a 3D affine transform ## ## PT2 = transformPoint3d(PT1, TRANS); ## PT2 = transformPoint3d(X1, Y1, Z1, TRANS); ## where PT1 has the form [xp yp zp], and TRANS is a [3x3], [3x4], [4x4] ## matrix, return the point transformed according to the affine transform ## specified by TRANS. ## ## Format of TRANS is a 4-by-4 matrix. ## ## The function accepts transforms given using the following formats: ## [a b c] , [a b c j] , or [a b c j] ## [d e f] [d e f k] [d e f k] ## [g h i] [g h i l] [g h i l] ## [0 0 0 1] ## ## PT2 = transformPoint3d(PT1, TRANS) ## also work when PT1 is a [Nx3xMxPxETC] array of double. In this case, ## PT2 has the same size as PT1. ## ## PT2 = transformPoint3d(X1, Y1, Z1, TRANS); ## also work when X1, Y1 and Z1 are 3 arrays with the same size. In this ## case, PT2 will be a 1-by-3 cell containing @{X Y Z@} outputs of size(X1). ## ## [X2 Y2 Z2] = transformPoint3d(@dots{}); ## returns the result in 3 different arrays the same size as the input. ## This form can be useful when used with functions like meshgrid or warp. ## ## @seealso{points3d, transforms3d, translation3d,meshgrid} ## @end deftypefn function varargout = transformPoint3d(varargin) # process input arguments if length(varargin) == 2 # Point coordinates are given in a single N-by-3-by-M-by-etc argument. # Preallocate x, y, and z to size N-by-1-by-M-by-etc, then fill them in dim = size(varargin{1}); dim(2) = 1; [x,y,z] = deal(zeros(dim,class(varargin{1}))); x(:) = varargin{1}(:,1,:); y(:) = varargin{1}(:,2,:); z(:) = varargin{1}(:,3,:); trans = varargin{2}; elseif length(varargin) == 4 # Point coordinates are given in 3 different arrays x = varargin{1}; y = varargin{2}; z = varargin{3}; dim = size(x); trans = varargin{4}; end # eventually add null translation if size(trans, 2) == 3 trans = [trans zeros(size(trans, 1), 1)]; end # eventually add normalization if size(trans, 1) == 3 trans = [trans;0 0 0 1]; end # convert coordinates NP = numel(x); try # vectorial processing, if there is enough memory #res = (trans*[x(:) y(:) z(:) ones(NP, 1)]')'; #res = [x(:) y(:) z(:) ones(NP, 1)]*trans'; res = [x(:) y(:) z(:) ones(NP,1,class(x))] * trans'; # Back-fill x,y,z with new result (saves calling costly reshape()) x(:) = res(:,1); y(:) = res(:,2); z(:) = res(:,3); catch ME disp(ME.message) # process each point one by one, writing in existing array for i = 1:NP res = [x(i) y(i) z(i) 1] * trans'; x(i) = res(1); y(i) = res(2); z(i) = res(3); end end # process output arguments if nargout <= 1 # results are stored in a unique array if length(dim) > 2 && dim(2) > 1 warning('geom3d:shapeMismatch',... 'Shape mismatch: Non-vector xyz input should have multiple x,y,z output arguments. Cell {x,y,z} returned instead.') varargout{1} = {x,y,z}; else varargout{1} = [x y z]; end elseif nargout == 3 varargout{1} = x; varargout{2} = y; varargout{3} = z; end endfunction geometry/inst/geom3d/drawTorus.m0000644000175000017500000000545712130275153016564 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} drawTorus (@var{torus}) ## Draw a torus (3D ring) ## ## drawTorus(TORUS) ## Draws the torus on the current axis. TORUS is given by ## [XC YC ZY R1 R2 THETA PHI] ## where (XC YZ ZC) is the center of the torus, R1 is the main radius, R2 ## is the radius of the torus section, and (THETA PHI) is the angle of the ## torus normal vector (both in degrees). ## ## Example ## @example ## figure; ## drawTorus([50 50 50 30 10 30 45]); ## axis equal; ## @end example ## ## @seealso{drawEllipsoid, revolutionSurface} ## @end deftypefn function varargout = drawTorus(torus, varargin) center = torus(1:3); r1 = torus(4); r2 = torus(5); if size(torus, 2) >= 7 normal = torus(6:7); end # default drawing options varargin = [{'FaceColor', 'g'}, varargin]; # create base torus circle = circleAsPolygon ([r1 0 r2], 60); [x y z] = revolutionSurface (circle, linspace(0, 2*pi, 60)); # transform torus trans = localToGlobal3d ([center normal]); [x y z] = transformPoint3d (x, y, z, trans); # draw the surface hs = surf(x, y, z, varargin{:}); if nargout > 0 varargout = {hs}; end endfunction %!demo %! figure; %! drawTorus([50 50 50 30 10 30 45]); %! axis square equal; %! view(45,40); geometry/inst/geom3d/drawPolyline3d.m0000644000175000017500000001055212035660370017465 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawPolyline3d (@var{poly}) ## @deftypefnx {Function File} {@var{h} =} drawPolyline3d (@var{px},@var{py},@var{pz}) ## @deftypefnx {Function File} {@var{h} =} drawPolyline3d (@dots{},@var{closed}) ## @deftypefnx {Function File} {@var{h} =} drawPolyline3d (@dots{},@var{param},@var{value}) ## Draw a 3D polyline specified by a list of vertices ## ## drawPolyline3d(POLY); ## packs coordinates in a single N-by-3 array. ## ## drawPolyline3d(PX, PY, PZ); ## specify coordinates in separate arrays. ## ## drawPolyline3d(..., CLOSED); ## Specifies if the polyline is closed or open. CLOSED can be one of: ## - 'closed' ## - 'open' (the default) ## - a boolean variable with value TRUE for closed polylines. ## ## drawPolyline3d(..., PARAM, VALUE); ## Specifies style options to draw the polyline, see plot for details. ## ## H = drawPolyline3d(...); ## also return a handle to the list of line objects. ## ## @seealso{polygons3d, drawPolygon3d, fillPolygon3d} ## @end deftypefn function varargout = drawPolyline3d(varargin) ## Process input arguments # check case we want to draw several curves, stored in a cell array var = varargin{1}; if iscell(var) hold on; h = []; for i = 1:length(var(:)) h = [h; drawPolyline3d(var{i}, varargin{2:end})]; ##ok end if nargout > 0 varargout = {h}; end return; end # extract curve coordinates if size(var, 2) == 1 # first argument contains x coord, second argument contains y coord # and third one the z coord px = var; if length(varargin) < 3 error('Wrong number of arguments in drawPolyline3d'); end py = varargin{2}; pz = varargin{3}; varargin = varargin(4:end); else # all coordinates are grouped in the first argument px = var(:, 1); py = var(:, 2); pz = var(:, 3); varargin = varargin(2:end); end # check if curve is closed or open (default is open) closed = false; if ~isempty(varargin) var = varargin{1}; if islogical(var) # check boolean flag closed = var; varargin = varargin(2:end); elseif ischar(var) # check string indicating close or open if strncmpi(var, 'close', 5) closed = true; varargin = varargin(2:end); elseif strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); end end end ## draw the curve # for closed curve, add the first point at the end to close curve if closed px = [px; px(1)]; py = [py; py(1)]; pz = [pz; pz(1)]; end h = plot3(px, py, pz, varargin{:}); if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom3d/cart2sph2d.m0000644000175000017500000000641012035504503016532 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{theta} @var{phi} @var{rho}] =} cart2sph2d (@var{coord}) ## @deftypefnx {Function File} {[@dots{}] =} cart2sph2d (@var{x},@var{y},@var{z}) ## Convert cartesian coordinates to spherical coordinates in degrees ## ## The following convention is used: ## THETA is the colatitude, in degrees, 0 for north pole, 180 degrees for ## south pole, 90 degrees for points with z=0. ## PHI is the azimuth, in degrees, defined as matlab cart2sph: angle from ## Ox axis, counted counter-clockwise. ## RHO is the distance of the point to the origin. ## Discussion on choice for convention can be found at: ## @url{http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf} ## ## Example: ## @example ## cart2sph2d([1 0 0]) ## ans = ## 90 0 1 ## ## cart2sph2d([1 1 0]) ## ans = ## 90 45 1.4142 ## ## cart2sph2d([0 0 1]) ## ans = ## 0 0 1 ## @end example ## ## @seealso{angles3d, sph2cart2d, cart2sph, cart2sph2} ## @end deftypefn function varargout = cart2sph2d(x, y, z) # if data are grouped, extract each coordinate if nargin == 1 y = x(:, 2); z = x(:, 3); x = x(:, 1); end # cartesian to spherical conversion hxy = hypot(x, y); rho = hypot(hxy, z); theta = 90 - atan2(z, hxy) * 180 / pi; phi = atan2(y, x) * 180 / pi; # # convert to degrees and theta to colatitude # theta = 90 - rad2deg(theta); # phi = rad2deg(phi); # format output if nargout <= 1 varargout{1} = [theta phi rho]; elseif nargout == 2 varargout{1} = theta; varargout{2} = phi; else varargout{1} = theta; varargout{2} = phi; varargout{3} = rho; end endfunction geometry/inst/geom3d/points3d.m0000644000175000017500000000405412035504503016323 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} points3d () ##POINTS3D Description of functions operating on 3D points ## ## Points are represented by their 3 Cartesian coordinates: ## P = [X Y Z]; ## ## Arrays of points consist in N*3 arrays, each row being a point. ## ## @seealso{isCoplanar, distancePoints, anglePoints3d, angleSort3d, sphericalAngle, ## sph2cart2, cart2sph2, cart2cyl, cyl2cart, transformPoint3d, clipPoints3d} ## @end deftypefn function points3d() help points3d endfunction geometry/inst/geom3d/box3dVolume.m0000644000175000017500000000407112041271112016760 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{v} =} box3dVolume (@var{box}) ## Volume of a 3-dimensional box ## ## A box is represented as a set of limits in each direction: ## BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. ## ## Example ## @example ## [n e f] = createCubeOctahedron; ## box = boundingBox3d(n); ## vol = box3dVolume(box) ## vol = ## 8 ## @end example ## ## @seealso{boxes3d, boundingBox3d} ## @end deftypefn function vol = box3dVolume(box) vol = prod(box(:, 2:2:end) - box(:, 1:2:end), 2); endfunction geometry/inst/geom3d/angleSort3d.m0000644000175000017500000000742712035504503016754 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pts2} =} angleSort3d (@var{pts}) ## @deftypefnx {Function File} {@var{pts2} =} angleSort3d (@var{pts},@var{pts0}) ## @deftypefnx {Function File} {@var{pts2} =} angleSort3d (@var{pts},@var{pts0},@var{pts1}) ## @deftypefnx {Function File} {[@var{pts2} @var{i}]=} angleSort3d (@dots{}) ## Sort 3D coplanar points according to their angles in plane ## ## @var{pts2} = angleSort3d(@var{pts}); ## Considers all points are located on the same plane, and sort them ## according to the angle on plane. @var{pts} is a [Nx2] array. Note that the ## result depend on plane orientation: points can be in reverse order ## compared to expected. The reference plane is computed besed on the 3 ## first points. ## ## @var{pts2} = angleSort3d(@var{pts}, @var{pts0}); ## Computes angles between each point of @var{pts} and PT0. By default, uses ## centroid of points. ## ## @var{pts2} = angleSort3d(@var{pts}, @var{pts0}, @var{pts1}); ## Specifies the point which will be used as a start. ## ## [@var{pts2}, @var{i}] = angleSort3d(...); ## Also return in @var{i} the indices of @var{pts}, such that @var{pts2} = @var{pts}(I, :); ## ## @seealso{points3d, angles3d, angleSort} ## @end deftypefn function varargout = angleSort3d(pts, varargin) # default values pt0 = mean (pts, 1); pt1 = pts(1,:); if length (varargin)==1 pt0 = varargin{1}; elseif length (varargin)==2 pt0 = varargin{1}; pt1 = varargin{2}; end # create support plane plane = createPlane (pts(1:3, :)); # project points onto the plane pts2d = planePosition (pts, plane); pt0 = planePosition (pt0, plane); pt1 = planePosition (pt1, plane); # compute origin angle theta0 = atan2 (pt1(2)-pt0(2), pt1(1)-pt0(1)); theta0 = mod (theta0 + 2*pi, 2*pi); # translate to reference point n = size (pts, 1); pts2d = pts2d - repmat (pt0, [n 1]); # compute angles angle = atan2 (pts2d(:,2), pts2d(:,1)); angle = mod (angle - theta0 + 4*pi, 2*pi); # sort points according to angles [angle, I] = sort (angle); ##ok # format output if nargout<2 varargout{1} = pts(I, :); elseif nargout==2 varargout{1} = pts(I, :); varargout{2} = I; end endfunction geometry/inst/geom3d/createScaling3d.m0000644000175000017500000000657512041277752017577 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{trans} =} createScaling3d (@var{s}) ## @deftypefnx {Function File} {@var{trans} =} createScaling3d (@var{sx}, @var{sy}, @var{sz}) ## Create the 4x4 matrix of a 3D scaling ## ## TRANS = createScaling3d(S); ## returns the scaling transform corresponding to a scaling factor S in ## each direction. S can be a scalar, or a 1x3 vector containing the ## scaling factor in each direction. ## ## TRANS = createScaling3d(SX, SY, SZ); ## returns the scaling transform corresponding to a different scaling ## factor in each direction. ## ## The returned matrix has the form : ## @group ## [SX 0 0 0] ## [ 0 SY 0 0] ## [ 0 0 SZ 0] ## [ 0 0 0 0] ## @end group ## ## @seealso{transforms3d, transformPoint3d, transformVector3d, createTranslation3d, ## createRotationOx, createRotationOy, createRotationOz} ## @end deftypefn function trans = createScaling3d(varargin) # process input parameters if isempty(varargin) # assert uniform scaling in each direction sx = 1; sy = 1; sz = 1; elseif length(varargin)==1 # only one argument var = varargin{1}; if length(var)==1 # same scaling factor in each direction sx = var; sy = var; sz = var; elseif length(var)==3 # scaling is a vector, giving different scaling in each direction sx = var(1); sy = var(2); sz = var(3); else error('wrong size for first parameter of "createScaling3d"'); end elseif length(varargin)==3 # 3 arguments, giving scaling in each direction sx = varargin{1}; sy = varargin{2}; sz = varargin{3}; else error('wrong number of arguments for "createScaling3d"'); end # create the scaling matrix trans = [sx 0 0 0;0 sy 0 0;0 0 sz 0;0 0 0 1]; endfunction geometry/inst/geom3d/drawEdge3d.m0000644000175000017500000000535012035504503016531 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawEdge (@var{edge}) ## Draw 3D edge in the current Window ## ## draw the edge EDGE on the current axis. EDGE has the form: ## [x1 y1 z1 x2 y2 z2]. ## No clipping is performed. ## ## @end deftypefn function varargout = drawEdge3d(varargin) # extract edges from input arguments nCol = size(varargin{1}, 2); if nCol==6 # all parameters in a single array edges = varargin{1}; options = varargin(2:end); elseif nCol==3 # parameters are two points, or two arrays of points, of size N*3. edges = [varargin{1} varargin{2}]; options = varargin(3:end); elseif nCol==6 # parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2 edges = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}]; options = varargin(7:end); end # draw edges h = line( [edges(:, 1) edges(:, 4)]', ... [edges(:, 2) edges(:, 5)]', ... [edges(:, 3) edges(:, 6)]', 'color', 'b'); # apply optional drawing style if ~isempty(options) set(h, options{:}); end # return handle to created Edges if nargout>0 varargout{1}=h; end endfunction geometry/inst/geom3d/cart2sph2.m0000644000175000017500000000604512035666045016404 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{theta} @var{phi} @var{rho}] =} cart2sph2([@var{x} @var{y} @var{z}]) ## @deftypefnx {Function File} {[@var{theta} @var{phi} @var{rho}] =} cart2sph2(@var{x}, @var{y}, @var{z}) ## Convert cartesian coordinates to spherical coordinates ## ## The following convention is used: ## @var{theta} is the colatitude, in radians, 0 for north pole, +pi for south ## pole, pi/2 for points with z=0. ## @var{phi} is the azimuth, in radians, defined as matlab cart2sph: angle from ## Ox axis, counted counter-clockwise. ## @var{rho} is the distance of the point to the origin. ## Discussion on choice for convention can be found at: ## @url{http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf} ## ## Example: ## @example ## cart2sph2([1 0 0]) returns [pi/2 0 1]; ## cart2sph2([1 1 0]) returns [pi/2 pi/4 sqrt(2)]; ## cart2sph2([0 0 1]) returns [0 0 1]; ## @end example ## ## @seealso{angles3d, sph2cart2, cart2sph, cart2sph2d} ## @end deftypefn function varargout = cart2sph2(varargin) if length(varargin)==1 var = varargin{1}; elseif length(varargin)==3 var = [varargin{1} varargin{2} varargin{3}]; end if size(var, 2)==2 var(:,3)=1; end [p t r] = cart2sph(var(:,1), var(:,2), var(:,3)); if nargout == 1 || nargout == 0 varargout{1} = [pi/2-t p r]; elseif nargout==2 varargout{1} = pi/2-t; varargout{2} = p; else varargout{1} = pi/2-t; varargout{2} = p; varargout{3} = r; end endfunction geometry/inst/geom3d/circle3dPoint.m0000644000175000017500000000632612041275510017266 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} =} circle3dPoint (@var{circle},@var{pos}) ## Coordinates of a point on a 3D circle from its position ## ## ## Example ## @example ## circle = [0 0 0 1 45 45 0]; ## # Draw some points on a 3D circle ## figure; hold on; ## # origin point ## pos1 = 0; ## drawPoint3d(circle3dPoint(circle, pos1), 'ro') ## # few points regularly spaced ## for i = 10:10:40 ## drawPoint3d(circle3dPoint(circle, i)) ## end ## # Draw point opposite to origin ## drawPoint3d(circle3dPoint(circle, 180), 'k*') ## @end example ## ## @seealso{circles3d, circle3dPosition} ## @end deftypefn function point = circle3dPoint(circle, pos) # extract circle coordinates xc = circle(1); yc = circle(2); zc = circle(3); r = circle(4); theta = circle(5); phi = circle(6); psi = circle(7); # convert position to angle t = pos * pi / 180; # compute position on base circle x = r * cos(t); y = r * sin(t); z = 0; pt0 = [x y z]; # compute transformation from local basis to world basis trans = localToGlobal3d (xc, yc, zc, theta, phi, psi); # compute points of transformed circle point = transformPoint3d (pt0, trans); endfunction %!demo %! # Draw some points on a 3D circle %! circle = [0 0 0 1 45 45 0]; %! figure; %! %! drawCircle3d(circle); %! hold on; %! %! # origin point %! pos1 = 0; %! drawPoint3d(circle3dPoint(circle, pos1), 'go') %! # few points regularly spaced %! for i = 10:10:90 %! drawPoint3d(circle3dPoint(circle, i)) %! end %! # Draw point opposite to origin %! drawPoint3d(circle3dPoint(circle, 180), 'k*') %! axis square equal; %! view(70,30) geometry/inst/geom3d/projPointOnPlane.m0000644000175000017500000000515112035504503020020 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pt2} =} projPointOnPlane (@var{pt1}, @var{plane}) ## Return the orthogonal projection of a point on a plane ## ## PT2 = projPointOnPlane(PT1, PLANE); ## Compute the (orthogonal) projection of point PT1 onto the line PLANE. ## ## Function works also for multiple points and planes. In this case, it ## returns multiple points. ## Point PT1 is a [N*3] array, and PLANE is a [N*9] array (see createPlane ## for details). Result PT2 is a [N*3] array, containing coordinates of ## orthogonal projections of PT1 onto planes PLANE. ## ## @seealso{planes3d, points3d, planePosition, intersectLinePlane} ## @end deftypefn function point = projPointOnPlane (point, plane) if size (point, 1)==1 point = repmat (point, [size(plane, 1) 1]); elseif size (plane, 1)==1 plane = repmat (plane, [size(point, 1) 1]); elseif size (plane, 1) ~= size (point, 1) error ('projPointOnPlane: size of inputs differ'); end n = planeNormal (plane); line = [point n]; point = intersectLinePlane (line, plane); endfunction geometry/inst/geom3d/circle3dPosition.m0000644000175000017500000000546512035660370020011 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pos} =} circle3dPosition(@var{point}, @var{circle}) ## Return the angular position of a point on a 3D circle ## ## Returns angular position of point on the circle, in degrees, between 0 ## and 360. ## with @var{point}: [xp yp zp] ## and @var{circle}: [X0 Y0 Z0 R THETA PHI] or [X0 Y0 Z0 R THETA PHI PSI] ## (THETA being the colatitude, and PHI the azimut) ## ## @seealso{circles3d, circle3dOrigin, circle3dPoint} ## @end deftypefn function theta = circle3dPosition(point, circle) # get center and radius xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); # get angle of normal theta = circle(:,5); phi = circle(:,6); # find origin of the circle ori = circle3dOrigin(circle); # normal vector of the supporting plane (cartesian coords) vn = sph2cart2d([theta phi]); # create plane containing the circle plane = createPlane([xc yc zc], vn); # find position of point on the circle plane pp0 = planePosition(ori, plane); pp = planePosition(point, plane); # compute angles in the planes theta0 = mod(atan2(pp0(:,2), pp0(:,1)) + 2*pi, 2*pi); theta = mod(atan2(pp(:,2), pp(:,1)) + 2*pi - theta0, 2*pi); # convert to degrees theta = theta * 180 / pi; endfunction geometry/inst/geom3d/distancePoints.m0000644000175000017500000001365112035666045017564 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{d} =} distancePoints(@var{p1}, @var{p2}) ## @deftypefnx {Function File} {@var{d} =} distancePoints(@var{p1}, @var{p2},@var{norm}) ## @deftypefnx {Function File} {@var{d} = } distancePoints (@dots{}, @asis{'diag'}) ## Compute euclidean distance between pairs of points in any dimension ## ## Return distance @var{d} between points @var{p1} and ## @var{p2}, given as [X Y Z @dots{} Wdim]. ## ## If @var{p1} and @var{p2} are two arrays of points, result is a N1-by-N2 array ## containing distance between each point of @var{p1} and each point of @var{p2}. ## ## ## @var{d} = distancePoints(@var{p1}, @var{p2}, @var{norm}) ## with @var{norm} being 1, 2, or Inf, corresponfing to the norm used. Default is ## 2 (euclidean norm). 1 correspond to manhattan (or taxi driver) distance ## and Inf to maximum difference in each coordinate. ## ## When 'diag' is given, computes only distances between @code{@var{p1}(i,:)} and @code{@var{p2}(i,:)}. ## In this case the numer of points in each array must be the same. ## ## @seealso{points3d, minDistancePoints} ## @end deftypefn function dist = distancePoints(p1, p2, varargin) norm = 2; diagonal = false; switch numel(varargin) case 0 1; case 1 if isnumeric (varargin{1}) norm = varargin{1}; else diagonal = true; end case 2 norm = varargin{1}; diagonal = true; otherwise print_usage; end # compute difference of coordinate for each all points [n1 dim] = size(p1); [n2 dim] = size(p2); if diagonal if n1 ~= n2 error ("geometry:InvalidArgument",... "When option diag is given the number of points must be equal.\n"); end ptsDiff = p2 - p1; else ptsDiff = zeros (n1,n2,dim); for i =1:dim ptsDiff(:,:,i) = p2(:,i)' - p1(:,i); end end # Return dist based on the type of measurement requested along_dim = length(size(ptsDiff)); switch(norm) case 1 dist = sum(abs(ptsDiff), along_dim); case 2 if ~diagonal dist = reshape(vectorNorm (reshape(ptsDiff,n1*n2,dim)),n1,n2); else dist = vectorNorm (ptsDiff); end case Inf dist = max(abs(ptsDiff), [], along_dim); otherwise dist = sum(ptsDiff.^norm, along_dim).^(1/norm); end endfunction %!shared pt1,pt2,pt3,pt4 %! pt1 = [10 10]; %! pt2 = [10 20]; %! pt3 = [20 20]; %! pt4 = [20 10]; %!assert (distancePoints(pt1, pt2), 10, 1e-6); %!assert (distancePoints(pt2, pt3), 10, 1e-6); %!assert (distancePoints(pt1, pt3), 10*sqrt(2), 1e-6); %!assert (distancePoints(pt1, pt2, 1), 10, 1e-6); %!assert (distancePoints(pt2, pt3, 1), 10, 1e-6); %!assert (distancePoints(pt1, pt3, 1), 20, 1e-6); %!assert (distancePoints(pt1, pt2, inf), 10, 1e-6); %!assert (distancePoints(pt2, pt3, inf), 10, 1e-6); %!assert (distancePoints(pt1, pt3, inf), 10, 1e-6); %!assert (distancePoints(pt1, [pt1; pt2; pt3]), [0 10 10*sqrt(2)], 1e-6); %!test %! array1 = [pt1;pt2;pt3]; %! array2 = [pt1;pt2;pt3;pt4]; %! res = [0 10 10*sqrt(2) 10; 10 0 10 10*sqrt(2); 10*sqrt(2) 10 0 10]; %! assert (distancePoints(array1, array2), res, 1e-6); %! assert (distancePoints(array2, array2, 'diag'), [0;0;0;0], 1e-6); %!test %! array1 = [pt1;pt2;pt3]; %! array2 = [pt2;pt3;pt1]; %! assert (distancePoints(array1, array2, inf, 'diag'), [10;10;10], 1e-6); %!shared pt1,pt2,pt3,pt4 %! pt1 = [10 10 10]; %! pt2 = [10 20 10]; %! pt3 = [20 20 10]; %! pt4 = [20 20 20]; %!assert (distancePoints(pt1, pt2), 10, 1e-6); %!assert (distancePoints(pt2, pt3), 10, 1e-6); %!assert (distancePoints(pt1, pt3), 10*sqrt(2), 1e-6); %!assert (distancePoints(pt1, pt4), 10*sqrt(3), 1e-6); %!assert (distancePoints(pt1, pt2, inf), 10, 1e-6); %!assert (distancePoints(pt2, pt3, inf), 10, 1e-6); %!assert (distancePoints(pt1, pt3, inf), 10, 1e-6); %!assert (distancePoints(pt1, pt4, inf), 10, 1e-6); %!shared pt1,pt2,pt3,pt4 %! pt1 = [10 10 30]; %! pt2 = [10 20 30]; %! pt3 = [20 20 30]; %! pt4 = [20 20 40]; %!assert (distancePoints(pt1, pt2, 1), 10, 1e-6); %!assert (distancePoints(pt2, pt3, 1), 10, 1e-6); %!assert (distancePoints(pt1, pt3, 1), 20, 1e-6); %!assert (distancePoints(pt1, pt4, 1), 30, 1e-6); %!test %! array1 = [pt1;pt2;pt3]; %! array2 = [pt2;pt3;pt1]; %! assert (distancePoints(array1, array2, 'diag'), [10;10;10*sqrt(2)], 1e-6); %! assert (distancePoints(array1, array2, 1, 'diag'), [10;10;20], 1e-6); geometry/inst/geom3d/private/0000755000175000017500000000000012130276034016052 5ustar juanpijuanpigeometry/inst/geom3d/private/localToGlobal3d.m0000644000175000017500000001027312035504503021177 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{} =} localToGlobal3d (@var{center}, @var{theta},@var{phi},@var{psi}) ## Transformation matrix from local to global coordinate system ## ## TRANS = localToGlobal3d(CENTER, THETA, PHI, PSI) ## Compute the transformation matrix from a local (or modelling) ## coordinate system to the global (or world) coordinate system. ## This is a low-level function, used by several drawing functions. ## ## The transform is defined by: ## - CENTER: the position of the local origin into the World coordinate ## system ## - THETA: colatitude, defined as the angle with the Oz axis (between 0 ## and 180 degrees), positive in the direction of the of Oy axis. ## - PHI: azimut, defined as the angle of the normal with the Ox axis, ## between 0 and 360 degrees ## - PSI: intrinsic rotation, corresponding to the rotation of the object ## around the direction vector, between 0 and 360 degrees ## ## The resulting transform is obtained by applying (in that order): ## - Rotation by PSI around he Z-axis ## - Rotation by THETA around the Y-axis ## - Rotation by PHI around the Z-axis ## - Translation by vector CENTER ## This corresponds to Euler ZYZ rotation, using angles PHI, THETA and ## PSI. ## ## The 'createEulerAnglesRotation' function may better suit your needs as ## it is more 'natural'. ## ## @seealso{transforms3d, createEulerAnglesRotation} ## @end deftypefn function trans = localToGlobal3d(varargin) ## extract the components of the transform if nargin == 1 ## all components are bundled in the first argument var = varargin{1}; center = var(1:3); theta = var(4); phi = var(5); psi = 0; if length(var) > 5 psi = var(6); end elseif nargin == 4 ## arguments = center, then the 3 angles center = varargin{1}; theta = varargin{2}; phi = varargin{3}; psi = varargin{4}; elseif nargin > 4 ## center is given in 3 arguments, then 3 angles center = [varargin{1} varargin{2} varargin{3}]; theta = varargin{4}; phi = varargin{5}; psi = 0; if nargin > 5 psi = varargin{6}; end end ## conversion from degrees to radians k = pi / 180; ## rotation around normal vector axis rot1 = createRotationOz(psi * k); ## colatitude rot2 = createRotationOy(theta * k); ## longitude rot3 = createRotationOz(phi * k); ## shift center tr = createTranslation3d(center); ## create final transform by concatenating transforms trans = tr * rot3 * rot2 * rot1; endfunction geometry/inst/geom3d/drawBox3d.m0000644000175000017500000000767512035701351016431 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawBox3d (@var{box}) ## @deftypefnx {Function File} drawBox3d (@dots{},@var{opt}) ## Draw a 3D box defined by coordinate extents ## ## Draw a box defined by its coordinate extents: ## BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. ## The function draws only the outline edges of the box. ## Extra options @var{opt} are passed to the function @code{drawEdges3d}. ## ## Example ## @example ## # Draw bounding box of a cubeoctehedron ## [v e f] = createCubeOctahedron; ## box3d = boundingBox3d(v); ## figure; hold on; ## drawMesh(v, f); ## drawBox3d(box3d); ## axis([-2 2 -2 2 -2 2]); ## view(3) ## @end example ## ## @seealso{boxes3d, boundingBox3d} ## @end deftypefn function drawBox3d(box, varargin) # default values xmin = box(:,1); xmax = box(:,2); ymin = box(:,3); ymax = box(:,4); zmin = box(:,5); zmax = box(:,6); nBoxes = size(box, 1); for i=1:length(nBoxes) # lower face (z=zmin) drawEdge3d([xmin(i) ymin(i) zmin(i) xmax(i) ymin(i) zmin(i)], varargin{:}); drawEdge3d([xmin(i) ymin(i) zmin(i) xmin(i) ymax(i) zmin(i)], varargin{:}); drawEdge3d([xmax(i) ymin(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); drawEdge3d([xmin(i) ymax(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); # front face (y=ymin) drawEdge3d([xmin(i) ymin(i) zmin(i) xmin(i) ymin(i) zmax(i)], varargin{:}); drawEdge3d([xmax(i) ymin(i) zmin(i) xmax(i) ymin(i) zmax(i)], varargin{:}); drawEdge3d([xmin(i) ymin(i) zmax(i) xmax(i) ymin(i) zmax(i)], varargin{:}); # left face (x=xmin) drawEdge3d([xmin(i) ymax(i) zmin(i) xmin(i) ymax(i) zmax(i)], varargin{:}); drawEdge3d([xmin(i) ymin(i) zmax(i) xmin(i) ymax(i) zmax(i)], varargin{:}); # the last 3 remaining edges drawEdge3d([xmin(i) ymax(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); drawEdge3d([xmax(i) ymax(i) zmin(i) xmax(i) ymax(i) zmax(i)], varargin{:}); drawEdge3d([xmax(i) ymin(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); end endfunction %!demo %! close all %! graphics_toolkit("fltk") %! # Draw bounding box of a cubeoctehedron %! [v e f] = createCubeOctahedron; %! box3d = boundingBox3d(v); %! figure; %! hold on; %! drawMesh(v, f); %! drawBox3d(box3d); %! axis([-2 2 -2 2 -2 2]); %! view(3) %!demo %! close all %! graphics_toolkit("gnuplot") geometry/inst/geom3d/distancePointLine3d.m0000644000175000017500000000765112035504503020431 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{d} =} distancePointLine3d (@var{point}, @var{line}) ## Euclidean distance between 3D point and line ## ## Returns the distance between point POINT and the line LINE, given as: ## POINT : [x0 y0 z0] ## LINE : [x0 y0 z0 dx dy dz] ## D : (positive) scalar ## ## Run @command{demo distancePointLine3d} to see examples. ## ## References ## http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html ## ## @seealso{lines3d, distancePointLine, distancePointEdge3d, projPointOnLine3d} ## @end deftypefn function d = distancePointLine3d(point, lin) [np nd] = size (point); [nl ndl] = size (lin); if ndl < 4 error("geometry:InvalidInput","second argument must be a line. See lines3d."); end # Compare everything to everything if np != nl # Order the lines such that all points are compared against 1st line, then # secoind and so on. --JPi idx = reshape (1:np*nl,nl,np)'(:); lin = repmat (lin, np, 1)(idx,:); point = repmat (point, nl, 1); end d = vectorNorm ( cross ( lin(:,4:6), lin(:,1:3)-point, 2)) ./ ... vectorNorm (lin(:,4:6)); endfunction %!demo %! point = [0 0 1]; %! lin = [0 0 0 1 1 1]; %! d = distancePointLine3d (point,lin); %! %! # Orthogonal and Parallel projectors %! dl = normalizeVector (lin(4:end))'; %! V = dl*dl'; %! P = eye(3) - dl*dl'; %! pv = P*point'; %! vv = V*point'; %! %! # Compare %! disp([d vectorNorm(pv)]) %! %! figure(1); %! clf %! plot3 (point(1),point(2),point(3),'.k'); %! line ([0 point(1)],[0 point(2)],[0 point(3)],'color','k'); %! line (dl(1)*[-2 2],dl(2)*[-2 2],dl(3)*[-2 2],'color','r'); %! line ([0 vv(1)],[0 vv(2)],[0 vv(3)],'color','g'); %! line (vv(1)+[0 pv(1)],vv(2)+[0 pv(2)],vv(3)+[0 pv(3)],'color','b'); %! axis square equal %! %! # ------------------------------------------------------------------------- %! # Distance between a line and a point, the distance is verified against the %! # vector form the point to the line, orthogonal to the line. %!demo %! point = 2*rand(4,3)-1; %! lin = [0 0 0 1 1 1; 0 0 0 1 1 0]; %! d = distancePointLine3d (point,lin) %! %! # Organize as matrix point vs lines %! reshape (d,4,2) %! %! # ------------------------------------------------------------------------- %! # Distance between 4 points and two lines. The result can be arrange as a %! # distance matrix. geometry/inst/geom3d/drawSphericalEdge.m0000644000175000017500000000555612035660370020152 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawSphericalEdge (@var{sphere}, @var{edge}) ## Draw an edge on the surface of a sphere ## ## @var{edge} is given as a couple of 3D corodinates corresponding to edge ## extremities. The shortest spherical edge joining the two extremities is ## drawn on the current axes. ## ## @seealso{drawSphericalPolygon} ## @end deftypefn function varargout = drawSphericalEdge(sphere, edge, varargin) # extract data of the sphere origin = sphere(:, 1:3); # extremities of current edge point1 = edge(1:3); point2 = edge(4:6); # compute plane containing current edge plane = createPlane(origin, point1, point2); # intersection of the plane with unit sphere circle = intersectPlaneSphere(plane, sphere); # find the position (in degrees) of the 2 vertices on the circle angle1 = circle3dPosition(point1, circle); angle2 = circle3dPosition(point2, circle); # ensure angles are in right direction if mod(angle2 - angle1 + 360, 360) > 180 tmp = angle1; angle1 = angle2; angle2 = tmp; end # compute angle extent of the circle arc angleExtent = mod(angle2 - angle1 + 360, 360); # create circle arc arc = [circle angle1 angleExtent]; # draw the arc h = drawCircleArc3d(arc, varargin{:}); if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom3d/drawSphere.m0000644000175000017500000001322712035504503016666 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{} =} function_name (@var{}, @var{}) ## Draw a sphere as a mesh ## ## drawSphere(SPHERE) ## Where SPHERE = [XC YC ZC R], draw the sphere centered on the point with ## coordinates [XC YC ZC] and with radius R, using a quad mesh. ## ## drawSphere(CENTER, R) ## Where CENTER = [XC YC ZC], specifies the center and the radius with two ## arguments. ## ## drawSphere(XC, YC, ZC, R) ## Specifiy sphere center and radius as four arguments. ## ## drawSphere(..., NAME, VALUE); ## Specifies one or several options using parameter name-value pairs. ## Available options are usual drawing options, as well as: ## 'nPhi' the number of arcs used for drawing the meridians ## 'nTheta' the number of circles used for drawing the parallels ## ## H = drawSphere(...) ## Return a handle to the graphical object created by the function. ## ## [X Y Z] = drawSphere(...) ## Return the coordinates of the vertices used by the sphere. In this ## case, the sphere is not drawn. ## ## Run @code{demo drawSphere} to see several examples. ## ## @seealso{spheres, circles3d, sphere, drawEllipsoid} ## @end deftypefn function varargout = drawSphere(varargin) # process input options: when a string is found, assumes this is the # beginning of options options = {'FaceColor', 'g', 'linestyle', 'none'}; for i=1:length(varargin) if ischar(varargin{i}) options = [options(1:end) varargin(i:end)]; varargin = varargin(1:i-1); break; end end # Parse the input (try to extract center coordinates and radius) if isempty(varargin) # no input: assumes unit sphere xc = 0; yc = 0; zc = 0; r = 1; elseif length(varargin) == 1 # one argument: concatenates center and radius sphere = varargin{1}; xc = sphere(:,1); yc = sphere(:,2); zc = sphere(:,3); r = sphere(:,4); elseif length(varargin) == 2 # two arguments, corresponding to center and radius center = varargin{1}; xc = center(1); yc = center(2); zc = center(3); r = varargin{2}; elseif length(varargin) == 4 # four arguments, corresponding to XC, YX, ZC and R xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; else error('drawSphere: please specify center and radius'); end # number of meridians nPhi = 32; ind = strmatch('nphi', lower(options(1:2:end))); if ~isempty(ind) ind = ind(1); nPhi = options{2*ind}; options(2*ind-1:2*ind) = []; end # number of parallels nTheta = 16; ind = strmatch('ntheta', lower(options(1:2:end))); if ~isempty(ind) ind = ind(1); nTheta = options{2*ind}; options(2*ind-1:2*ind) = []; end # compute spherical coordinates theta = linspace(0, pi, nTheta+1); phi = linspace(0, 2*pi, nPhi+1); # convert to cartesian coordinates sintheta = sin(theta); x = xc + cos(phi')*sintheta*r; y = yc + sin(phi')*sintheta*r; z = zc + ones(length(phi),1)*cos(theta)*r; # Process output if nargout == 0 # no output: draw the sphere surf(x, y, z, options{:}); elseif nargout == 1 # one output: compute varargout{1} = surf(x, y, z, options{:}); elseif nargout == 3 varargout{1} = x; varargout{2} = y; varargout{3} = z; end endfunction %!demo %! # Draw four spheres with different centers %! figure(1); clf; hold on; %! drawSphere([10 10 30 5]); %! drawSphere([20 30 10 5]); %! drawSphere([30 30 30 5]); %! drawSphere([30 20 10 5]); %! view([-30 20]); %! axis tight %! axis equal; %!demo %! # Draw sphere with different settings %! figure(1); clf; %! drawSphere([10 20 30 10], 'linestyle', ':', 'facecolor', 'r'); %! axis tight %! axis equal; %!demo %! # Draw sphere with different settings, but changes style using graphic handle %! figure(1); clf; %! h = drawSphere([10 20 30 10]); %! set(h, 'edgecolor', 'none'); %! set(h, 'facecolor', 'r'); %! axis tight %! axis equal; %!demo %! # Draw a sphere with high resolution %! figure(1); clf; %! h = drawSphere([10 20 30 10], 'nPhi', 360, 'nTheta', 180); %! view(3); %! axis equal; geometry/inst/geom3d/drawPoint3d.m0000644000175000017500000000606612041275510016763 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawPoint3d (@var{x}, @var{y}, @var{z}) ## @deftypefnx {Function File} {@var{h} =} drawPoint3d (@var{coord}) ## @deftypefnx {Function File} {@var{h} =} drawPoint3d (@dots{}) ## Draw 3D point on the current axis. ## ## drawPoint3d(X, Y, Z) ## will draw points defined by coordinates X and Y. ## X and Y are N*1 array, with N being number of points to be drawn. ## ## drawPoint3d(COORD) ## packs coordinates in a single [N*3] array. ## ## drawPoint3d(..., OPT) ## will draw each point with given option. OPT is a string compatible with ## 'plot' model. ## ## H = drawPoint3d(...) ## Also return a handle to each of the drawn points. ## ## @seealso{points3d, clipPoints3d} ## @end deftypefn function varargout = drawPoint3d(varargin) var = varargin{1}; if size(var, 2)==3 # points are given as one single array with 3 columns px = var(:, 1); py = var(:, 2); pz = var(:, 3); varargin = varargin(2:end); elseif length(varargin)<3 error('wrong number of arguments in drawPoint3d'); else # points are given as 3 columns with equal length px = varargin{1}; py = varargin{2}; pz = varargin{3}; varargin = varargin(4:end); end # default draw style: no line, marker is 'o' if length(varargin)~=1 varargin = ['linestyle', 'none', 'marker', 'o', varargin]; end # plot only points inside the axis. h = plot3(px, py, pz, varargin{:}); if nargout>0 varargout{1} = h; end endfunction geometry/inst/geom3d/geom3d_Contents.m0000644000175000017500000003154412035673610017625 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} geom3d_Contents () ## GEOM3D Geometry 3D Toolbox ## Version 1.0 21-Mar-2011 . ## ## Creation, transformations, algorithms and visualization of geometrical ## 3D primitives, such as points, lines, planes, polyhedra, circles and ## spheres. ## ## Euler Angles are defined as follow: ## PHI is the azimut, i.e. the angle of the projection on horizontal plane ## with the Ox axis, with value beween 0 and 180 degrees. ## THETA is the latitude, i.e. the angle with the Oz axis, with value ## between -90 and +90 degrees. ## PSI is the 'roll', i.e. the rotation around the (PHI, THETA) direction, ## with value in degrees ## See also the 'angles3d' page. ## ## Base format for primitives: ## Point: [x0 y0 z0] ## Vector: [dx dy dz] ## Line: [x0 y0 z0 dx dy dz] ## Edge: [x1 y1 z1 x2 y2 z2] ## Plane: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] ## Sphere: [x0 y0 z0 R] ## Circle: [x0 y0 z0 R PHI THETA PSI] (origin+center+normal+'roll'). ## Cylinder: [X1 Y1 Z1 X2 Y2 Z2 R] ## Box: [xmin xmax ymin ymax zmin zmax]. Used for clipping shapes. ## ## Polygons are represented by N-by-3 array of points, the last point is ## not necessarily the same as the first one. Points must be coplanar. ## ## Meshes and Polyhedra are represented by a couple of variables @{V, F@}: ## V: N-by-3 array of vetrtices: [x1 y1 z1; ... ;xn yn zn]; ## F: is either a [Nf*3] or [Nf*4] array containing reference for vertices ## of each face, or a [Nf*1] cell array, where each cell is an array ## containing a variable number of node indices. ## For some functions, the array E of edges is needed. It consists in a ## Ne-by-2 array containing indices of source and target vertices. ## ## ## 3D Points ## points3d - Description of functions operating on 3D points ## midPoint3d - Middle point of two 3D points or of a 3D edge ## isCoplanar - Tests input points for coplanarity in 3-space. ## transformPoint3d - Transform a point with a 3D affine transform ## distancePoints - Compute euclidean distance between pairs of 3D Points ## clipPoints3d - Clip a set of points by a box ## drawPoint3d - Draw 3D point on the current axis. ## ## 3D Vectors ## vectors3d - Description of functions operating on 3D vectors ## transformVector3d - Transform a vector with a 3D affine transform ## normalizeVector3d - Normalize a 3D vector to have norm equal to 1 ## vectorNorm3d - Norm of a 3D vector or of set of 3D vectors ## vectorAngle3d - Angle between two 3D vectors ## isParallel3d - Check parallelism of two 3D vectors ## isPerpendicular3d - Check orthogonality of two 3D vectors ## ## Angles ## angles3d - Conventions for manipulating angles in 3D ## anglePoints3d - Compute angle between three 3D points ## sphericalAngle - Compute angle between points on the sphere ## angleSort3d - Sort 3D coplanar points according to their angles in plane ## randomAngle3d - Return a 3D angle uniformly distributed on unit sphere ## ## Coordinate transforms ## sph2cart2 - Convert spherical coordinates to cartesian coordinates ## cart2sph2 - Convert cartesian coordinates to spherical coordinates ## cart2sph2d - Convert cartesian coordinates to spherical coordinates in degrees ## sph2cart2d - Convert spherical coordinates to cartesian coordinates in degrees ## cart2cyl - Convert cartesian to cylindrical coordinates ## cyl2cart - Convert cylindrical to cartesian coordinates ## ## 3D Lines and Edges ## lines3d - Description of functions operating on 3D lines ## createLine3d - Create a line with various inputs. ## transformLine3d - Transform a 3D line with a 3D affine transform ## clipLine3d - Clip a line with a box and return an edge ## midPoint3d - Middle point of two 3D points or of a 3D edge ## distancePointLine3d - Euclidean distance between 3D point and line ## distanceLines3d - Minimal distance between two 3D lines ## linePosition3d - Return the position of a 3D point on a 3D line ## drawEdge3d - Draw 3D edge in the current Window ## drawLine3d - Draw a 3D line on the current axis ## ## Planes ## planes3d - Description of functions operating on 3D planes ## createPlane - Create a plane in parametrized form ## normalizePlane - Normalize parametric representation of a plane ## intersectPlanes - Return intersection line between 2 planes in space ## intersectLinePlane - Return intersection point between a plane and a line ## intersectEdgePlane - Return intersection point between a plane and a edge ## distancePointPlane - Signed distance betwen 3D point and plane ## projPointOnPlane - Return the orthogonal projection of a point on a plane ## isBelowPlane - Test whether a point is below or above a plane ## medianPlane - Create a plane in the middle of 2 points ## planeNormal - Compute the normal to a plane ## planePosition - Compute position of a point on a plane ## planePoint - Compute 3D position of a point in a plane ## dihedralAngle - Compute dihedral angle between 2 planes ## drawPlane3d - Draw a plane clipped in the current window ## ## 3D Polygons and curves ## polygons3d - Description of functions operating on 3D polygons ## polygonCentroid3d - Centroid (or center of mass) of a polygon ## triangleArea3d - Area of a 3D triangle ## polygon3dNormalAngle - Normal angle at a vertex of the 3D polygon ## intersectLinePolygon3d - Intersection point of a 3D line and a 3D polygon ## intersectLineTriangle3d - Intersection point of a 3D line and a 3D triangle ## intersectRayPolygon3d - Intersection point of a 3D ray and a 3D polygon ## clipConvexPolygon3dHP - Clip a convex 3D polygon with Half-space ## drawPolygon3d - Draw a 3D polygon specified by a list of vertices ## drawPolyline3d - Draw a 3D polyline specified by a list of vertices ## fillPolygon3d - Fill a 3D polygon specified by a list of points ## ## 3D circles and ellipses ## circles3d - Description of functions operating on 3D circles ## circle3dPosition - Return the angular position of a point on a 3D circle ## circle3dPoint - Coordinates of a point on a 3D circle from its position ## circle3dOrigin - Return the first point of a 3D circle ## drawCircle3d - Draw a 3D circle ## drawCircleArc3d - Draw a 3D circle arc ## drawEllipse3d - Draw a 3D ellipse ## ## Spheres ## spheres - Description of functions operating on 3D spheres ## createSphere - Create a sphere containing 4 points ## intersectLineSphere - Return intersection points between a line and a sphere ## intersectPlaneSphere - Return intersection circle between a plane and a sphere ## drawSphere - Draw a sphere as a mesh ## drawSphericalTriangle - Draw a triangle on a sphere ## ## Smooth surfaces ## inertiaEllipsoid - Inertia ellipsoid of a set of 3D points ## intersectLineCylinder - Compute intersection points between a line and a cylinder ## revolutionSurface - Create a surface of revolution from a planar curve ## surfaceCurvature - Curvature on a surface from angle and principal curvatures ## drawEllipsoid - Draw a 3D ellipsoid ## drawTorus - Draw a torus (3D ring) ## drawCylinder - Draw a cylinder ## drawSurfPatch - Draw a 3D surface patch, with 2 parametrized surfaces ## ## Bounding boxes management ## boxes3d - Description of functions operating on 3D boxes ## point3dBounds - Bounding box of a set of 3D points ## intersectBoxes3d - Intersection of two 3D bounding boxes ## mergeBoxes3d - Merge 3D boxes, by computing their greatest extent ## box3dVolume - Volume of a 3-dimensional box ## randomPointInBox3d - Generate random point(s) within a 3D box ## drawBox3d - Draw a 3D box defined by coordinate extents ## ## Geometric transforms ## transforms3d - Conventions for manipulating 3D affine transforms ## createTranslation3d - Create the 4x4 matrix of a 3D translation ## createScaling3d - Create the 4x4 matrix of a 3D scaling ## createRotationOx - Create the 4x4 matrix of a 3D rotation around x-axis ## createRotationOy - Create the 4x4 matrix of a 3D rotation around y-axis ## createRotationOz - Create the 4x4 matrix of a 3D rotation around z-axis ## createBasisTransform3d - Compute matrix for transforming a basis into another basis ## eulerAnglesToRotation3d - Convert 3D Euler angles to 3D rotation matrix ## rotation3dToEulerAngles - Extract Euler angles from a rotation matrix ## createRotation3dLineAngle - Create rotation around a line by an angle theta ## rotation3dAxisAndAngle - Determine axis and angle of a 3D rotation matrix ## recenterTransform3d - Change the fixed point of an affine 3D transform ## composeTransforms3d - Concatenate several space transformations ## ## Various drawing Functions ## drawGrid3d - Draw a 3D grid on the current axis ## drawAxis3d - Draw a coordinate system and an origin ## drawAxisCube - Draw a colored cube representing axis orientation ## drawCube - Draw a 3D centered cube, eventually rotated ## drawCuboid - Draw a 3D cuboid, eventually rotated ## ## ## Credits: ## * function isCoplanar was originally written by Brett Shoelson. ## * Songbai Ji enhanced file intersectPlaneLine (6/23/2006). ## ## @end deftypefn function geom3d_Contents () help('geom3d_Contents'); ## In development: ## clipPolygon3dHP - clip a 3D polygon with Half-space ## drawPartialPatch - draw surface patch, with 2 parametrized surfaces ## Deprecated: ## intersectPlaneLine - return intersection between a plane and a line ## translation3d - return 4x4 matrix of a 3D translation ## scale3d - return 4x4 matrix of a 3D scaling ## rotationOx - return 4x4 matrix of a rotation around x-axis ## rotationOy - return 4x4 matrix of a rotation around y-axis ## rotationOz - return 4x4 matrix of a rotation around z-axis ## scaling3d - return 4x4 matrix of a 3D scaling ## vecnorm3d - compute norm of vector or of set of 3D vectors ## normalize3d - normalize a 3D vector ## drawCurve3d - draw a 3D curve specified by a list of points ## createEulerAnglesRotation - Create a rotation matrix from 3 euler angles endfunction geometry/inst/geom3d/drawCylinder.m0000644000175000017500000001451612035701351017213 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawCylinder (@var{cyl}) ## @deftypefnx {Function File} {@var{h} =} drawCylinder (@var{cyl},@var{n}) ## @deftypefnx {Function File} {@var{h} =} drawCylinder (@dots{}, @var{opt}) ## @deftypefnx {Function File} {@var{h} =} drawCylinder (@dots{}, @asis{"Facecolor"},@var{color}) ## @deftypefnx {Function File} {@var{h} =} drawCylinder (@dots{}) ## Draw a cylinder ## ## drawCylinder(@var{cyl}) ## where @var{cyl} is a cylinder defined by [x1 y1 z1 x2 y2 z2 r]: ## [x1 y2 z1] are coordinates of starting point, [x2 y2 z2] are ## coordinates of ending point, and R is the radius of the cylinder, ## draws the corresponding cylinder on the current axis. ## ## drawCylinder(@var{cyl}, @var{N}) ## uses @var{N} points for discretisation of angle. Default value is 32. ## ## drawCylinder(..., @var{opt}) ## with @var{opt} = 'open' (default) or 'closed', specify if bases of the ## cylinder should be drawn. ## ## drawCylinder(..., @asis{"FaceColor"}, @var{color}) ## Specifies the color of the cylinder. Any couple of parameters name and ## value can be given as argument, and will be transfered to the 'surf' ## matlab function ## ## @var{h} = drawCylinder(...) ## returns a handle to the patch representing the cylinder. ## ## Run @code{demo drawCylinder} to see several examples. ## ## WARNING: This function doesn't work in gnuplot (as of version 4.2). ## ## @seealso{drawSphere, drawLine3d, surf} ## @end deftypefn function varargout = drawCylinder(cyl, varargin) if strcmpi (graphics_toolkit(),"gnuplot") error ("geometry:Incompatibility", ... ["This function doesn't work with gnuplot (as of version 4.1)." ... "Use graphics_toolkit('fltk').\n"]); end ## Input argument processing if iscell(cyl) res = zeros(length(cyl), 1); for i=1:length(cyl) res(i) = drawCylinder(cyl{i}, varargin{:}); end if nargout>0 varargout{1} = res; end return; end # default values N = 32; closed = true; # check number of discretization steps if ~isempty(varargin) var = varargin{1}; if isnumeric(var) N = var; varargin = varargin(2:end); end end # check if cylinder must be closed or open if ~isempty(varargin) var = varargin{1}; if ischar(var) if strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); elseif strncmpi(var, 'closed', 5) closed = true; varargin = varargin(2:end); end end end ## Computation of mesh coordinates # extreme points of cylinder p1 = cyl(1:3); p2 = cyl(4:6); # radius of cylinder r = cyl(7); # compute orientation angle of cylinder [theta phi rho] = cart2sph2d(p2 - p1); dphi = linspace(0, 2*pi, N+1); # generate a cylinder oriented upwards x = repmat(cos(dphi) * r, [2 1]); y = repmat(sin(dphi) * r, [2 1]); z = repmat([0 ; rho], [1 length(dphi)]); # transform points trans = localToGlobal3d(p1, theta, phi, 0); pts = transformPoint3d([x(:) y(:) z(:)], trans); # reshape transformed points x2 = reshape(pts(:,1), size(x)); y2 = reshape(pts(:,2), size(x)); z2 = reshape(pts(:,3), size(x)); ## Display cylinder mesh # add default drawing options varargin = [{'FaceColor', 'g', 'edgeColor', 'none'} varargin]; # plot the cylinder as a surface hSurf = surf(x2, y2, z2, varargin{:}); # eventually plot the ends of the cylinder if closed ind = find(strcmpi(varargin, 'facecolor'), 1, 'last'); if isempty(ind) color = 'k'; else color = varargin{ind+1}; end patch(x2(1,:)', y2(1,:)', z2(1,:)', color, 'edgeColor', 'none'); patch(x2(2,:)', y2(2,:)', z2(2,:)', color, 'edgeColor', 'none'); end # format ouptut if nargout == 1 varargout{1} = hSurf; end endfunction %!demo %! close all %! graphics_toolkit ("fltk") %! %! figure; %! h = drawCylinder([0 0 0 10 20 30 5],'FaceColor', 'r'); %! set(h, 'facecolor', 'g'); %! axis equal %! view([60 30]) %! %! figure; %! drawCylinder([0 0 0 10 20 30 5], 'open'); %! axis equal %! view([60 30]) %! %! figure; %! drawCylinder([0 0 0 10 20 30 5], 'FaceColor', 'r'); %! axis equal %! view([60 30]) %! %! figure; %! h = drawCylinder([0 0 0 10 20 30 5]); %! set(h, 'facecolor', 'b'); %! axis equal %! view([60 30]) %!demo %! close all %! graphics_toolkit ("fltk") %! %! # Draw three mutually intersecting cylinders %! p0 = [30 30 30]; %! p1 = [90 30 30]; %! p2 = [30 90 30]; %! p3 = [30 30 90]; %! %! figure; %! drawCylinder([p0 p1 25], 'FaceColor', 'r'); %! hold on %! drawCylinder([p0 p2 25], 'FaceColor', 'g'); %! drawCylinder([p0 p3 25], 'FaceColor', 'b'); %! axis equal %! view([60 30]) %!demo %! close all %! graphics_toolkit ("gnuplot") geometry/inst/geom3d/createRotationOx.m0000644000175000017500000000672612035504503020062 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{trans} =} createRotationOx (@var{theta}) ## @deftypefnx {Function File} {@var{trans} =} createRotationOx (@var{origin},@var{theta}) ## @deftypefnx {Function File} {@var{trans} =} createRotationOx (@var{x0},@var{y0},@var{z0},@var{theta}) ## Create the 4x4 matrix of a 3D rotation around x-axis ## ## TRANS = createRotationOx(THETA); ## Returns the transform matrix corresponding to a rotation by the angle ## THETA (in radians) around the Ox axis. A rotation by an angle of PI/2 ## would transform the vector [0 1 0] into the vector [0 0 1]. ## ## The returned matrix has the form: ## [1 0 0 0] ## [0 cos(THETA) -sin(THETA) 0] ## [0 sin(THETA) cos(THETA) 0] ## [0 0 0 1] ## ## TRANS = createRotationOx(ORIGIN, THETA); ## TRANS = createRotationOx(X0, Y0, Z0, THETA); ## Also specifies origin of rotation. The result is similar as performing ## translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). ## ## @seealso{transforms3d, transformPoint3d, createRotationOy, createRotationOz} ## @end deftypefn function trans = createRotationOx(varargin) # default values dx = 0; dy = 0; dz = 0; theta = 0; # get input values if length(varargin)==1 # only angle theta = varargin{1}; elseif length(varargin)==2 # origin point (as array) and angle var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); theta = varargin{2}; elseif length(varargin)==3 # origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; theta = varargin{3}; end # compute coefs cot = cos(theta); sit = sin(theta); # create transformation trans = [... 1 0 0 0;... 0 cot -sit 0;... 0 sit cot 0;... 0 0 0 1]; # add the translation part t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; trans = t*trans/t; endfunction geometry/inst/geom3d/drawPolygon3d.m0000644000175000017500000000737012035660370017325 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawPolygon3d (@var{poly}) ## @deftypefnx {Function File} {@var{h} =} drawPolygon3d (@var{px},@var{py},@var{pz}) ## @deftypefnx {Function File} {@var{h} =} drawPolygon3d (@dots{},@var{param},@var{value}) ## Draw a 3D polygon specified by a list of vertices ## ## drawPolygon3d(POLY); ## packs coordinates in a single N-by-3 array. ## ## drawPolygon3d(PX, PY, PZ); ## specifies coordinates in separate arrays. ## ## drawPolygon3d(..., PARAM, VALUE); ## Specifies style options to draw the polyline, see plot for details. ## ## H = drawPolygon3d(...); ## also return a handle to the list of line objects. ## ## @seealso{polygons3d, fillPolygon3d, drawPolyline3d} ## @end deftypefn function varargout = drawPolygon3d(varargin) # check case we want to draw several curves, stored in a cell array var = varargin{1}; if iscell(var) hold on; h = []; for i = 1:length(var(:)) h = [h; drawPolygon3d(var{i}, varargin{2:end})]; ##ok end if nargout > 0 varargout{1} = h; end return; end # extract curve coordinate if size(var, 2) == 1 # first argument contains x coord, second argument contains y coord # and third one the z coord px = var; if length(varargin) < 3 error('Wrong number of arguments in drawPolygon3d'); end py = varargin{2}; pz = varargin{3}; varargin = varargin(4:end); else # first argument contains both coordinate px = var(:, 1); py = var(:, 2); pz = var(:, 3); varargin = varargin(2:end); end ## draw the polygon # check that the polygon is closed if px(1) ~= px(end) || py(1) ~= py(end) || pz(1) ~= pz(end) px = [px; px(1)]; py = [py; py(1)]; pz = [pz; pz(1)]; end # draw the closed curve h = plot3(px, py, pz, varargin{:}); if nargout > 0 varargout = {h}; end endfunction %!demo %! l=0.25; %! # Corner Triangle with a wedge %! poly2 = [1 0 0; ... %! ([1 0 0]+l*[-1 1 0]); ... %! mean(eye(3)); ... %! ([1 0 0]+(1-l)*[-1 1 0]); ... %! 0 1 0; ... %! 0 0 1]; %! drawPolygon3d(poly2) %! axis square %! axis equal %! view([74 26]) geometry/inst/geom3d/planes3d.m0000644000175000017500000000421712035504503016272 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} planes3d () ##PLANES3D Description of functions operating on 3D planes ## ## Planes are represented by a 3D point (the plane origin) and 2 direction ## vectors, which should not be colinear. ## PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2]; ## ## @seealso{createPlane, medianPlane, normalizePlane, ## planeNormal, planePosition, dihedralAngle, ## intersectPlanes, projPointOnPlane, isBelowPlane, ## intersectLinePlane, intersectEdgePlane, distancePointPlane, drawPlane3d} ## @end deftypefn function planes3d(varargin) help planes3d endfunction geometry/inst/geom3d/boxes3d.m0000644000175000017500000000416412035504503016131 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} boxes3d () ## BOXES3D Description of functions operating on 3D boxes ## ## A box defined by its coordinate extents: ## BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. ## ## Example ## # Draw a polyhedron together with its bounding box ## [n e f]= createIcosahedron; ## drawPolyhedron(n, f); ## hold on; ## drawBox3d(point3dBounds(n)) ## ## ## @seealso{point3dBounds, box3dVolume, drawBox3d ## intersectBoxes3d, mergeBoxes3d, randomPointInBox3d} ## @end deftypefn function boxes3d() help boxes3d endfunction geometry/inst/geom3d/anglePoints3d.m0000644000175000017500000000664112035504503017276 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{alpha} =} anglePoints3d (@var{p1}, @var{p2}) ## @deftypefnx {Function File} {@var{alpha} =} anglePoints3d (@var{p1}, @var{p2},@var{p3}) ## @deftypefnx {Function File} {@var{alpha} =} anglePoints3d (@var{pts}) ## Compute angle between three 3D points ## ## @var{alpha} = anglePoints3d(P1, P2) ## Computes angle (P1, O, P2), in radians, between 0 and PI. ## ## @var{alpha} = anglePoints3d(P1, P2, P3) ## Computes angle (P1, P2, P3), in radians, between 0 and PI. ## ## @var{alpha} = anglePoints3d(PTS) ## PTS is a 3x3 or 2x3 array containing coordinate of points. ## ## @seealso{points3d, angles3d} ## @end deftypefn function alpha = anglePoints3d(varargin) p2 = [0 0 0]; if length(varargin)==1 pts = varargin{1}; if size(pts, 1)==2 p1 = pts(1,:); p0 = [0 0 0]; p2 = pts(2,:); else p1 = pts(1,:); p0 = pts(2,:); p2 = pts(3,:); end elseif length(varargin)==2 p1 = varargin{1}; p0 = [0 0 0]; p2 = varargin{2}; elseif length(varargin)==3 p1 = varargin{1}; p0 = varargin{2}; p2 = varargin{3}; end # ensure all data have same size n1 = size(p1, 1); n2 = size(p2, 1); n0 = size(p0, 1); if n1~=n2 if n1==1 p1 = repmat(p1, [n2 1]); elseif n2==1 p2 = repmat(p2, [n1 1]); else error('Arguments P1 and P2 must have the same size'); end end if n1~=n0 if n1==1 p1 = repmat(p1, [n0 1]); elseif n0==1 p0 = repmat(p0, [n1 1]); else error('Arguments P1 and P0 must have the same size'); end end # normalized vectors p1 = normalizeVector(p1-p0); p2 = normalizeVector(p2-p0); # compute angle alpha = acos(dot(p1, p2, 2)); endfunction geometry/inst/geom3d/lines3d.m0000644000175000017500000000377412035504503016131 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} lines3d () ##LINES3D Description of functions operating on 3D lines ## ## A 3D Line is represented by a 3D point (its origin) and a 3D vector ## (its direction): ## LINE = [X0 Y0 Z0 DX DY DZ]; ## ## @seealso{createLine3d, transformLine3d, distancePointLine3d, linePosition3d ## intersectLinePlane, distanceLines3d, clipLine3d, drawLine3d} ## @end deftypefn function lines3d() help lines3d endfunction geometry/inst/geom3d/drawSphericalTriangle.m0000644000175000017500000000463512041301453021037 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} function_name (@var{sphere}, @var{p1},@var{p2},@var{p3}) ## Draw a triangle on a sphere ## @seealso{drawSphere, fillSphericalTriangle, drawSphericalPolygon} ## @end deftypefn function varargout = drawSphericalTriangle(sphere, p1, p2, p3, varargin) # extract data of the sphere ori = sphere(:, 1:3); # extract direction vectors for each point v1 = normalizeVector (p1 - ori); v2 = normalizeVector (p2 - ori); v3 = normalizeVector (p3 - ori); hold on h1 = drawSphericalEdge (sphere, [v1 v2], varargin{:}); h2 = drawSphericalEdge (sphere, [v2 v3], varargin{:}); h3 = drawSphericalEdge (sphere, [v3 v1], varargin{:}); hold off if nargout > 0 varargout = {h1, h2, h3}; end endfunction %!demo %! p = full(eye(3)); %! s = [0 0 0 2]; %! drawSphericalTriangle (s,p(1,:),p(2,:),p(3,:),"r"); %! view(40,35) geometry/inst/geom3d/createPlane.m0000644000175000017500000001155412035504503017006 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{PLANE} =} createPlane (@var{pts}) ## @deftypefnx {Function File} {@var{PLANE} =} createPlane (@var{p0}, @var{n}) ## @deftypefnx {Function File} {@var{PLANE} =} createPlane (@var{p1}, @var{p2}, @var{p3}) ## Create a plane in parametrized form ## ## PLANE = createPlane(PTS) ## The 3 points are packed into a single 3x3 array. ## ## PLANE = createPlane(P0, N); ## Creates a plane from a point and from a normal to the plane. The ## parameter N is given either as a 3D vector (1-by-3 row vector), or as ## [THETA PHI], where THETA is the colatitute (angle with the vertical ## axis) and PHI is angle with Ox axis, counted counter-clockwise (both ## given in radians). ## ## PLANE = createPlane(P1, P2, P3) ## creates a plane containing the 3 points ## ## The created plane data has the following format: ## PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], with ## - (X0, Y0, Z0) is a point belonging to the plane ## - (DX1, DY1, DZ1) is a first direction vector ## - (DX2, DY2, DZ2) is a second direction vector ## The 2 direction vectors are normalized and orthogonal. ## ## @seealso{planes3d, medianPlane} ## @end deftypefn ## TODO: return closet plane when dim(PTS,1) > 3 function plane = createPlane(varargin) if length (varargin) == 1 var = varargin{1}; if iscell (var) plane = zeros ([length (var) 9]); for i=1:length (var) plane(i,:) = createPlane (var{i}); end elseif size (var, 1) >= 3 # 3 points in a single array p1 = var(1,:); p2 = var(2,:); p3 = var(3,:); # create direction vectors v1 = p2 - p1; v2 = p3 - p1; # create plane plane = normalizePlane ([p1 v1 v2]); return; end elseif length (varargin) == 2 # plane origin p0 = varargin{1}; # second parameter is either a 3D vector or a 3D angle (2 params) var = varargin{2}; if size (var, 2) == 2 # normal is given in spherical coordinates n = sph2cart2 ([var ones(size(var, 1))]); elseif size (var, 2)==3 # normal is given by a 3D vector n = normalizeVector (var); else error ('wrong number of parameters in createPlane'); end # ensure same dimension for parameters if size (p0, 1)==1 p0 = repmat (p0, [size(n, 1) 1]); end if size(n, 1)==1 n = repmat (n, [size(p0, 1) 1]); end # find a vector not colinear to the normal v0 = repmat ([1 0 0], [size(p0, 1) 1]); inds = vectorNorm (cross (n, v0, 2)) < 1e-14; v0(inds, :) = repmat ([0 1 0], [sum(inds) 1]); # if abs(cross(n, v0, 2))<1e-14 # v0 = repmat([0 1 0], [size(p0, 1) 1]); # end # create direction vectors v1 = normalizeVector (cross (n, v0, 2)); v2 = -normalizeVector (cross (v1, n, 2)); # concatenate result in the array representing the plane plane = [p0 v1 v2]; return; elseif length (varargin)==3 p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; # create direction vectors v1 = p2 - p1; v2 = p3 - p1; plane = normalizePlane ([p1 v1 v2]); return; else error ('Wrong number of arguments in "createPlane".'); end endfunction geometry/inst/geom3d/createTranslation3d.m0000644000175000017500000000543612035504503020476 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{} =} createTranslation3d (@var{dx}, @var{dy}, @var{dz}) ## @deftypefnx {Function File} {@var{} =} createTranslation3d (@var{vect}) ## Create the 4x4 matrix of a 3D translation ## ## usage: ## TRANS = createTranslation3d(DX, DY, DZ); ## return the translation corresponding to DX and DY. ## The returned matrix has the form : ## [1 0 0 DX] ## [0 1 0 DY] ## [0 0 1 DZ] ## [0 0 0 1] ## ## TRANS = createTranslation3d(VECT); ## return the translation corresponding to the given vector [x y z]. ## ## @seealso{transforms3d, transformPoint3d, transformVector3d, ## createRotationOx, createRotationOy, createRotationOz, createScaling3d} ## @end deftypefn function trans = createTranslation3d(varargin) if isempty(varargin) # assert translation with null vector dx = 0; dy = 0; dz = 0; elseif length(varargin)==1 # translation vector given in a single argument var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); else # translation vector given in 3 arguments dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; end # create the translation matrix trans = [1 0 0 dx ; 0 1 0 dy ; 0 0 1 dz; 0 0 0 1]; endfunction geometry/inst/geom3d/planeNormal.m0000644000175000017500000000366512035504503017037 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{n} =} planeNormal (@var{plane}) # Compute the normal to a plane # # N = planeNormal(PLANE) # compute the normal of the given plane # PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] # N : [dx dy dz] # ## @seealso{planes3d, createPlane} ## @end deftypefn function n = planeNormal(plane) n = cross (plane(:,4:6), plane(:, 7:9), 2); endfunction geometry/inst/geom3d/sph2cart2d.m0000644000175000017500000000651612035673610016547 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{c} =} sph2cart2d(@var{theta}, @var{phi}, @var{rho}) ## @deftypefnx {Function File} {@var{c} =} sph2cart2d(@var{theta}, @var{phi}) ## @deftypefnx {Function File} {@var{c} =} sph2cart2d(@var{s}) ## @deftypefnx {Function File} {[@var{x},@var{y},@var{z}] =} sph2cart2d(@var{theta}, @var{phi}, @var{rho}) ## Convert spherical coordinates to cartesian coordinates in degrees ## ## ## @var{c} = SPH2CART2(@var{theta}, @var{phi}) assumes @var{rho} = 1. ## ## @var{s} = [@var{theta}, @var{phi}, @var{rho}] (spherical coordinate). ## @var{c} = [@var{x},@var{y},@var{z}] (cartesian coordinate) ## ## The following convention is used: ## @var{theta} is the colatitude, in degrees, 0 for north pole, +180 degrees for ## south pole, +90 degrees for points with z=0. ## @var{phi} is the azimuth, in degrees, defined as matlab cart2sph: angle from ## Ox axis, counted counter-clockwise. ## @var{rho} is the distance of the point to the origin. ## Discussion on choice for convention can be found at: ## @url{http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf} ## ## @seealso{angles3d, cart2sph2d, sph2cart2} ## @end deftypefn function varargout = sph2cart2d(theta, phi, rho) # Process input arguments if nargin == 1 phi = theta(:, 2); if size(theta, 2) > 2 rho = theta(:, 3); else rho = ones(size(phi)); end theta = theta(:, 1); elseif nargin == 2 rho = ones(size(theta)); end # conversion rz = rho .* sind(theta); x = rz .* cosd(phi); y = rz .* sind(phi); z = rho .* cosd(theta); # Process output arguments if nargout == 1 || nargout == 0 varargout{1} = [x, y, z]; else varargout{1} = x; varargout{2} = y; varargout{3} = z; end endfunction geometry/inst/geom3d/createRotationOz.m0000644000175000017500000000672612035504503020064 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{trans} =} createRotationOz (@var{theta}) ## @deftypefnx {Function File} {@var{trans} =} createRotationOz (@var{origin},@var{theta}) ## @deftypefnx {Function File} {@var{trans} =} createRotationOz (@var{x0},@var{y0},@var{z0},@var{theta}) ## Create the 4x4 matrix of a 3D rotation around x-axis ## ## TRANS = createRotationOz(THETA); ## Returns the transform matrix corresponding to a rotation by the angle ## THETA (in radians) around the Oz axis. A rotation by an angle of PI/2 ## would transform the vector [0 1 0] into the vector [0 0 1]. ## ## The returned matrix has the form: ## [1 0 0 0] ## [0 cos(THETA) -sin(THETA) 0] ## [0 sin(THETA) cos(THETA) 0] ## [0 0 0 1] ## ## TRANS = createRotationOz(ORIGIN, THETA); ## TRANS = createRotationOz(X0, Y0, Z0, THETA); ## Also specifies origin of rotation. The result is similar as performing ## translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). ## ## @seealso{transforms3d, transformPoint3d, createRotationOx, createRotationOy} ## @end deftypefn function trans = createRotationOz(varargin) # default values dx = 0; dy = 0; dz = 0; theta = 0; # get input values if length(varargin)==1 # only angle theta = varargin{1}; elseif length(varargin)==2 # origin point (as array) and angle var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); theta = varargin{2}; elseif length(varargin)==3 # origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; theta = varargin{3}; end # compute coefs cot = cos(theta); sit = sin(theta); # create transformation trans = [... cot -sit 0 0;... sit cot 0 0;... 0 0 1 0;... 0 0 0 1]; # add the translation part t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; trans = t*trans/t; endfunction geometry/inst/geom3d/drawSphericalPolygon.m0000644000175000017500000000426512035666045020736 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{} =} drawSphericalPolygon (@var{sphere}, @var{poly}) ## Draw a spherical polygon ## ## @end deftypefn function varargout = drawSphericalPolygon(sphere, poly, varargin) nv = size(poly, 1); h = zeros(nv, 1); figure(gcf); for i = 1:nv v1 = poly(i, :); v2 = poly(mod(i, nv) + 1, :); h(i) = drawSphericalEdge(sphere, [v1 v2], varargin{:}); hold on end hold off if nargout > 0 varargout = {h}; end endfunction %!demo %! p = full(eye(3)); %! s = [0 0 0 1]; %! drawSphericalPolygon (s,p,"r"); %! hold on %! drawSphericalPolygon (2*s,p,"g"); %! hold off %! view(40,35) geometry/inst/geom3d/cyl2cart.m0000644000175000017500000000602412041271112016274 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{cart} =} cyl2cart (@var{cyl}) ## @deftypefnx {Function File} {@var{cart} =} cyl2cart (@var{theta},@var{r},@var{z}) ## Convert cylindrical to cartesian coordinates ## ## CART = cyl2cart(CYL) ## convert the 3D cylindrical coordinates of points CYL (given by ## [THETA R Z] where THETA, R, and Z have the same size) into cartesian ## coordinates CART, given by [X Y Z]. ## The transforms is the following : ## X = R*cos(THETA); ## Y = R*sin(THETA); ## Z remains inchanged. ## ## CART = cyl2cart(THETA, R, Z) ## provides coordinates as 3 different parameters ## ## Example ## @example ## cyl2cart([-1 0 2]) ## gives : 4.7124 1.0000 2.0000 ## @end example ## ## @seealso{angles3d, cart2pol, cart2sph2, cart2cyl} ## @end deftypefn function varargout = cyl2cart(varargin) # process input parameters if length(varargin)==1 var = varargin{1}; theta = var(:,1); r = var(:,2); z = var(:,3); elseif length(varargin)==3 theta = varargin{1}; r = varargin{2}; z = varargin{3}; end # convert coordinates dim = size(theta); x = reshape(r(:).*cos(theta(:)), dim); y = reshape(r(:).*sin(theta(:)), dim); # process output parameters if nargout==0 ||nargout==1 if length(dim)>2 || dim(2)>1 varargout{1} = {x y z}; else varargout{1} = [x y z]; end elseif nargout==3 varargout{1} = x; varargout{2} = y; varargout{3} = z; end endfunction geometry/inst/geom3d/polygonArea3d.m0000644000175000017500000000606112035504503017267 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{area} =} polygonArea3d(@var{poly}) ## Area of a 3D polygon ## ## @var{poly} is given as a N-by-3 array of vertex coordinates. The resulting ## area is positive. ## ## Example ## @example ## poly = [10 30 20;20 30 20;20 40 20;10 40 20]; ## polygonArea3d(poly) ## ans = ## 100 ## @end example ## ## @seealso{polygons3d, triangleArea3d, polygonArea, polygonCentroid3d} ## @end deftypefn function area = polygonArea3d(poly) # put the first vertex at origin (reducing computation errors for polygons # far from origin) v0 = poly (1, :); poly -= v0; # indices of next vertices N = size (poly, 1); iNext = [2:N 1]; # compute area (vectorized version) # need to compute the sign explicitely, as the norm of the cross product # does not keep orientation within supporting plane. cp = cross (poly, poly(iNext,:), 2); sign_i = sign (cp*cp(2,:)'); area_i = vectorNorm(cp) .* sign_i; # sum up individual triangles area area = sum(area_i) / 2; endfunction %!demo %! poly = [10 30 20;20 30 20;20 40 20;10 40 20]; %! polygonArea3d(poly) %!demo %! l=0.25; %! # Corner Triangle with a wedge %! poly = [1 0 0; ... %! ([1 0 0]+l*[-1 1 0]); ... %! mean(eye(3)); ... %! ([1 0 0]+(1-l)*[-1 1 0]); ... %! 0 1 0; ... %! 0 0 1]; %! %! polygonArea3d(poly) %! %! # Is the same as %! p1 = [1 0 0; 0 1 0; 0 0 1]; # Corner %! p2 = [([1 0 0]+l*[-1 1 0]); ([1 0 0]+(1-l)*[-1 1 0]); mean(eye(3))]; # Wedge %! %! polygonArea3d(p1)-polygonArea3d(p2) geometry/inst/geom3d/drawCube.m0000644000175000017500000001075412130275153016322 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawCube (@var{cube}) ## @deftypefnx {Function File} {[@var{x},@var{y},@var{z}] =} drawCube (@var{cube}) ## Draw a 3D centered cube, eventually rotated ## ## drawCube(CUBE) ## Displays a 3D cube on current axis. CUBE is given by: ## [XC YC ZC SIDE THETA PHI PSI] ## where (XC, YC, ZC) is the CUBE center, SIDE is the length of the cube ## main sides, and THETA PHI PSI are angles representing the cube ## orientation, in degrees. THETA is the colatitude of the cube, between 0 ## and 90 degrees, PHI is the longitude, and PSI is the rotation angle ## around the axis of the normal. ## ## CUBE can be axis aligned, in this case it should only contain center ## and side information: ## CUBE = [XC YC ZC SIDE] ## ## The function drawCuboid is closely related, but uses a different angle ## convention, and allows for different sizes along directions. ## ## Example ## @example ## # Draw a cube with small rotations ## figure; hold on; ## drawCube([10 20 30 50 10 20 30], 'FaceColor', 'g'); ## axis equal; ## view(3); ## @end example ## ## WARNING: This function doesn't work in gnuplot (as of version 4.2). ## ## @seealso{meshes3d, polyhedra, createCube, drawCuboid} ## @end deftypefn function varargout = drawCube(cube, varargin) # default values theta = 0; phi = 0; psi = 0; ## Parses the input if nargin == 0 # no input: assumes cube with default shape xc = 0; yc = 0; zc = 0; a = 1; else # one argument: parses elements xc = cube(:,1); yc = cube(:,2); zc = cube(:,3); a = cube(:,4); # parses orientation if present k = pi / 180; if size(cube, 2) >= 6 theta = cube(:,5) * k; phi = cube(:,6) * k; end if size(cube, 2) >= 7 psi = cube(:,7) * k; end end ## Compute cube coordinates # create unit centered cube [v f] = createCube; v = bsxfun(@minus, v, mean(v, 1)); # convert unit basis to cube basis sca = createScaling3d (a); rot1 = createRotationOz (psi); rot2 = createRotationOy (theta); rot3 = createRotationOz (phi); tra = createTranslation3d ([xc yc zc]); # concatenate transforms trans = tra * rot3 * rot2 * rot1 * sca; # transform mesh vertices [x y z] = transformPoint3d (v, trans); ## Process output if nargout == 0 # no output: draw the cube drawMesh ([x y z], f, varargin{:}); elseif nargout == 1 # one output: draw the cube and return handle varargout{1} = drawMesh ([x y z], f, varargin{:}); elseif nargout == 3 # 3 outputs: return computed coordinates varargout{1} = x; varargout{2} = y; varargout{3} = z; end endfunction %!demo %! # Draw a cube with small rotations %! close all %! graphics_toolkit fltk; %! figure; hold on; %! drawCube([10 20 30 50 10 20 30], 'FaceColor', 'g'); %! axis equal; %! view(3); geometry/inst/geom3d/planePosition.m0000644000175000017500000000543712035504503017412 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pt2} =} planePosition (@var{point}, @var{plane}) ## Compute position of a point on a plane ## ## PT2 = planePosition(POINT, PLANE) ## POINT has format [X Y Z], and plane has format ## [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], where : ## - (X0, Y0, Z0) is a point belonging to the plane ## - (DX1, DY1, DZ1) is a first direction vector ## - (DX2, DY2, DZ2) is a second direction vector ## ## Result PT2 has the form [XP YP], with [XP YP] coordinate of the point ## in the coordinate system of the plane. ## ## ## CAUTION: ## WORKS ONLY FOR PLANES WITH ORTHOGONAL DIRECTION VECTORS ## ## @seealso{planes3d, points3d, planePoint} ## @end deftypefn function pos = planePosition(point, plane) # unify size of data if size (point, 1) ~= size (plane, 1) if size (point, 1) == 1 point = repmat (point, [size(plane, 1) 1]); elseif size (plane, 1) == 1 plane = repmat (plane, [size(point, 1) 1]); else error ('point and plane do not have the same dimension'); end end p0 = plane(:, 1:3); d1 = plane(:, 4:6); d2 = plane(:, 7:9); s = dot (point-p0, d1, 2) ./ vectorNorm (d1); t = dot (point-p0, d2, 2) ./ vectorNorm (d2); pos = [s t]; endfunction geometry/inst/geom3d/intersectPlaneSphere.m0000644000175000017500000000725112035666045020723 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{circ} =} intersectPlaneSphere(@var{plane}, @var{sphere}) ## Return intersection circle between a plane and a sphere ## ## Returns the circle which is the intersection of the given plane ## and sphere. ## @var{plane} : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] ## @var{sphere} : [XS YS ZS RS] ## @var{circ} : [XC YC ZC RC THETA PHI PSI] ## [x0 y0 z0] is the origin of the plane, [dx1 dy1 dz1] and [dx2 dy2 dz2] ## are two direction vectors, ## [XS YS ZS] are coordinates of the sphere center, RS is the sphere ## radius, ## [XC YC ZC] are coordinates of the circle center, RC is the radius of ## the circle, [THETA PHI] is the normal of the plane containing the ## circle (THETA being the colatitude, and PHI the azimut), and PSI is a ## rotation angle around the normal (equal to zero in this function, but ## kept for compatibility with other functions). All angles are given in ## degrees. ## ## @seealso{planes3d, spheres, circles3d, intersectLinePlane, intersectLineSphere} ## @end deftypefn function circle = intersectPlaneSphere(plane, sphere) # number of inputs of each type Ns = size(sphere, 1); Np = size(plane, 1); # unify data dimension if Ns ~= Np if Ns == 1 sphere = sphere(ones(Np, 1), :); elseif Np == 1 plane = plane(ones(Ns, 1), :); else error('data should have same length, or one data should have length 1'); end end # center of the spheres center = sphere(:,1:3); # radius of spheres if size(sphere, 2) == 4 Rs = sphere(:,4); else # assume default radius equal to 1 Rs = ones(size(sphere, 1), 1); end # projection of sphere center on plane -> gives circle center circle0 = projPointOnPlane(center, plane); # radius of circles d = distancePoints (center, circle0); Rc = sqrt(Rs.*Rs - d.*d); # normal of planes = normal of circles nor = planeNormal(plane); # convert to angles [theta phi] = cart2sph2(nor(:,1), nor(:,2), nor(:,3)); psi = zeros(Np, 1); # create structure for circle k = 180 / pi; circle = [circle0 Rc [theta phi psi]*k]; endfunction geometry/inst/geom3d/drawCircle3d.m0000644000175000017500000002067712041275510017077 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawCircle3d (@var{circle2d}, @var{normal}) ## @deftypefnx {Function File} {@var{h} =} drawCircle3d (@var{xc}, @var{yc}, @var{zc}, @var{r}, @var{theta}, @var{phi}, @var{psi}) ## Draw a 3D circle ## ## Possible calls for the function: ## drawCircle3d([XC YC ZC R THETA PHI]) ## drawCircle3d([XC YC ZC R], [THETA PHI]) ## ## where XC, YC, ZY are coordinates of circle center, R is the circle ## radius, PHI and THETA are 3D angles in degrees of the normal to the ## plane containing the circle: ## * THETA between 0 and 180 degrees, corresponding to the colatitude ## (angle with Oz axis). ## * PHI between 0 and 360 degrees corresponding to the longitude (angle ## with Ox axis) ## ## drawCircle3d([XC YC ZC R THETA PHI PSI]) ## drawCircle3d([XC YC ZC R], [THETA PHI PSI]) ## drawCircle3d([XC YC ZC R], THETA, PHI) ## drawCircle3d([XC YC ZC], R, THETA, PHI) ## drawCircle3d([XC YC ZC R], THETA, PHI, PSI) ## drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) ## drawCircle3d(XC, YC, ZC, R, THETA, PHI) ## drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) ## Are other possible syntaxes for this function. ## ## H = drawCircle3d(...) ## return handle on the created LINE object ## ## Example ## @example ## # display 3 mutually orthogonal 3D circles ## figure; hold on; ## drawCircle3d([10 20 30 50 0 0], 'LineWidth', 2, 'Color', 'b'); ## drawCircle3d([10 20 30 50 90 0], 'LineWidth', 2, 'Color', 'r'); ## drawCircle3d([10 20 30 50 90 90], 'LineWidth', 2, 'Color', 'g'); ## axis equal; ## axis([-50 100 -50 100 -50 100]); ## view([-10 20]) ## ## # Draw several circles at once ## center = [10 20 30]; ## circ1 = [center 50 0 0]; ## circ2 = [center 50 90 0]; ## circ3 = [center 50 90 90]; ## figure; hold on; ## drawCircle3d([circ1 ; circ2 ; circ3]); ## axis equal; ## @end example # ## @seealso{circles3d, drawCircleArc3d, drawEllipse3d, drawSphere} ## @end deftypefn function varargout = drawCircle3d(varargin) # Possible calls for the function, with number of arguments : # drawCircle3d([XC YC ZC R THETA PHI]) 1 # drawCircle3d([XC YC ZC R THETA PHI PSI]) 1 # drawCircle3d([XC YC ZC R], [THETA PHI]) 2 # drawCircle3d([XC YC ZC R], [THETA PHI PSI]) 2 # drawCircle3d([XC YC ZC R], THETA, PHI) 3 # drawCircle3d([XC YC ZC], R, THETA, PHI) 4 # drawCircle3d([XC YC ZC R], THETA, PHI, PSI) 4 # drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) 5 # drawCircle3d(XC, YC, ZC, R, THETA, PHI) 6 # drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) 7 # extract drawing options ind = find(cellfun(@ischar, varargin), 1, 'first'); options = {}; if ~isempty(ind) options = varargin(ind:end); varargin(ind:end) = []; end # Extract circle data if length(varargin) == 1 # get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); # get colatitude of normal if size(circle, 2) >= 5 theta = circle(:,5); else theta = zeros(size(circle, 1), 1); end # get azimut of normal if size(circle, 2)>=6 phi = circle(:,6); else phi = zeros(size(circle, 1), 1); end # get roll if size(circle, 2)==7 psi = circle(:,7); else psi = zeros(size(circle, 1), 1); end elseif length(varargin) == 2 # get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); # get angle of normal angle = varargin{2}; theta = angle(:,1); phi = angle(:,2); # get roll if size(angle, 2)==3 psi = angle(:,3); else psi = zeros(size(angle, 1), 1); end elseif length(varargin) == 3 # get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); # get angle of normal and roll theta = varargin{2}; phi = varargin{3}; psi = zeros(size(phi, 1), 1); elseif length(varargin) == 4 # get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); if size(circle, 2)==4 r = circle(:,4); theta = varargin{2}; phi = varargin{3}; psi = varargin{4}; else r = varargin{2}; theta = varargin{3}; phi = varargin{4}; psi = zeros(size(phi, 1), 1); end elseif length(varargin) == 5 # get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = varargin{2}; theta = varargin{3}; phi = varargin{4}; psi = varargin{5}; elseif length(varargin) == 6 xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; theta = varargin{5}; phi = varargin{6}; psi = zeros(size(phi, 1), 1); elseif length(varargin) == 7 xc = varargin{1}; yc = varargin{2}; zc = varargin{3}; r = varargin{4}; theta = varargin{5}; phi = varargin{6}; psi = varargin{7}; else error('drawCircle3d: please specify center and radius'); end # circle parametrisation (by using N=60, some vertices are located at # special angles like 45, 30...) Nt = 60; t = linspace(0, 2*pi, Nt+1); nCircles = length(xc); h = zeros(nCircles, 1); for i = 1:nCircles # compute position of circle points x = r(i) * cos(t)'; y = r(i) * sin(t)'; z = zeros(length(t), 1); circle0 = [x y z]; # compute transformation from local basis to world basis trans = localToGlobal3d(xc(i), yc(i), zc(i), theta(i), phi(i), psi(i)); # compute points of transformed circle circle = transformPoint3d(circle0, trans); # draw the curve of circle points h(i) = drawPolyline3d(circle, options{:}); end if nargout > 0 varargout = {h}; end endfunction %!demo %! # display 3 mutually orthogonal 3D circles %! figure; hold on; %! drawCircle3d([10 20 30 50 0 0], 'LineWidth', 2, 'Color', 'b'); %! drawCircle3d([10 20 30 50 90 0], 'LineWidth', 2, 'Color', 'r'); %! drawCircle3d([10 20 30 50 90 90], 'LineWidth', 2, 'Color', 'g'); %! axis square equal; %! axis([-50 100 -50 100 -50 100]); %! view([-10 20]) %! %! # Draw several circles at once %! center = [10 20 30]; %! circ1 = [center 50 0 0]; %! circ2 = [center 50 90 0]; %! circ3 = [center 50 90 90]; %! figure; hold on; %! drawCircle3d([circ1 ; circ2 ; circ3]); %! axis square equal; geometry/inst/geom3d/vectorAngle3d.m0000644000175000017500000000501012035504503017251 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{theta} =} vectorAngle3d (@var{v1}, @var{v2}) ## Angle between two 3D vectors ## ## THETA = vectorAngle3d(V1, V2) ## Computes the angle between the 2 3D vectors V1 and V2. The result THETA ## is given in radians, between 0 and PI. ## ## ## Example ## # angle between 2 orthogonal vectors ## vectorAngle3d([1 0 0], [0 1 0]) ## ans = ## 1.5708 ## ## # angle between 2 parallel vectors ## v0 = [3 4 5]; ## vectorAngle3d(3*v0, 5*v0) ## ans = ## 0 ## ## @seealso{vectors3d, vectorNorm} ## @end deftypefn function theta = vectorAngle3d(v1, v2) # compute angle using arc-tangent to get better precision for angles near # zero, see the discussion in: # http://www.mathworks.com/matlabcentral/newsreader/view_thread/151925#381952 # equivalent to: # v1 = normalizeVector(v1); # v2 = normalizeVector(v2); # theta = acos(dot(v1, v2, 2)); theta = atan2(vectorNorm(cross (v1, v2)), sum(v1.*v2,2)); endfunction geometry/inst/geom3d/circles3d.m0000644000175000017500000000453712035504503016441 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} circles3d () ##CIRCLES3D Description of functions operating on 3D circles ## ## Circles are represented by a center, a radius and a 3D angle ## representing the normal of the plane containing the circle. ## C = [xc yc zc R theta phi psi]. ## THETA is the colatitude of the normal, in degrees, between 0 and 180 ## PHI is the azimut of the normal, in degrees, between 0 and 360 ## PSI is the proper rotation of the circle around the normal, between 0 ## and 360 degrees ## The parameter PSI is used to locate a point on the 3D circle. ## ## @seealso{circle3dOrigin, circle3dPosition, circle3dPoint, intersectPlaneSphere ## drawCircle3d, drawCircleArc3d, drawEllipse3d} ## @end deftypefn function circles3d () help circles3d endfunction geometry/inst/geom3d/drawCircleArc3d.m0000644000175000017500000000707512035660370017527 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawCircleArc3d([@var{xc} @var{yc} @var{zc} @var{r} @var{theta} @var{phi} @var{psi} @var{start} @var{extent}]) ## Draw a 3D circle arc ## ## [@var{xc} @var{yc} @var{zc}] : coordinate of arc center ## @var{r} : arc radius ## [@var{theta} @var{phi}] : orientation of arc normal, in degrees (theta: 0->180). ## @var{psi} : roll of arc (rotation of circle origin) ## @var{start} : starting angle of arc, from arc origin, in degrees ## @var{extent} : extent of circle arc, in degrees (can be negative) ## ## Drawing options can be specified, as for the plot command. ## ## @seealso{angles3, circles3d, drawCircle3d, drawCircleArc} ## @end deftypefn function varargout = drawCircleArc3d(arc, varargin) if iscell(arc) h = []; for i = 1:length(arc) h = [h drawCircleArc3d(arc{i}, varargin{:})]; ##ok end if nargout > 0 varargout = {h}; end return; end if size(arc, 1) > 1 h = []; for i = 1:size(arc, 1) h = [h drawCircleArc3d(arc(i,:), varargin{:})]; ##ok end if nargout > 0 varargout = {h}; end return; end # get center and radius xc = arc(:,1); yc = arc(:,2); zc = arc(:,3); r = arc(:,4); # get angle of normal theta = arc(:,5); phi = arc(:,6); psi = arc(:,7); # get starting angle and angle extent of arc start = arc(:,8); extent = arc(:,9); # positions on circle arc N = 60; t = linspace(start, start+extent, N+1) * pi / 180; # compute coordinate of points x = r*cos(t)'; y = r*sin(t)'; z = zeros(length(t), 1); curve = [x y z]; # compute transformation from local basis to world basis trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); # transform circle arc curve = transformPoint3d(curve, trans); # draw the curve with specified options h = drawPolyline3d(curve, varargin{:}); if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom3d/vectors3d.m0000644000175000017500000000407012035504503016472 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} vectors3d () ##VECTORS3D Description of functions operating on 3D vectors ## ## Vectors are represented by their 3 Cartesian coordinates: ## V = [VX VY VZ]; ## ## List of vectors are represented by N*3 arrays, with the coordinates of ## each vector on a row. ## ## ## @seealso{vectorNorm3d, normalizeVector3d, vectorAngle3d isParallel3d, ## isPerpendicular3d, createTranslation3d} ## @end deftypefn function vectors3d(varargin) help vectors3d endfunction geometry/inst/geom3d/spheres.m0000644000175000017500000000446212041304441016230 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} spheres () ## Description of functions operating on 3D spheres ## ## Spheres are represented by their center and their radius: ## S = [xc yc zc r]; ## ## An ellipsoid is defined by: ## ELL = [XC YC ZC A B C PHI THETA PSI] ## where [XC YC ZY] is the center, [A B C] are length of semi-axes (in ## decreasing order), and [PHI THETA PSI] are euler angles representing ## the ellipsoid orientation. ## @seealso{createSphere, inertiaEllipsoid, intersectLineSphere, ## intersectPlaneSphere, sphericalVoronoiDomain, drawSphere, drawEllipsoid, ## drawSphericalEdge, drawSphericalTriangle, drawSphericalPolygon, ## fillSphericalTriangle, fillSphericalPolygon} ## @end deftypefn function spheres(varargin) help spheres endfunction geometry/inst/geom3d/createRotationOy.m0000644000175000017500000000720212035504503020051 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{trans} =} createRotationOy (@var{theta}) ## @deftypefnx {Function File} {@var{trans} =} createRotationOy (@var{origin},@var{theta}) ## @deftypefnx {Function File} {@var{trans} =} createRotationOy (@var{x0},@var{y0},@var{z0},@var{theta}) ## Create the 4x4 matrix of a 3D rotation around x-axis ## ## TRANS = createRotationOy(THETA); ## Returns the transform matrix corresponding to a rotation by the angle ## THETA (in radians) around the Oy axis. A rotation by an angle of PI/2 ## would transform the vector [0 1 0] into the vector [0 0 1]. ## ## The returned matrix has the form: ## [1 0 0 0] ## [0 cos(THETA) -sin(THETA) 0] ## [0 sin(THETA) cos(THETA) 0] ## [0 0 0 1] ## ## TRANS = createRotationOy(ORIGIN, THETA); ## TRANS = createRotationOy(X0, Y0, Z0, THETA); ## Also specifies origin of rotation. The result is similar as performing ## translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). ## ## @seealso{transforms3d, transformPoint3d, createRotationOx, createRotationOz} ## @end deftypefn function trans = createRotationOy(varargin) # default values dx = 0; dy = 0; dz = 0; theta = 0; # get input values if length(varargin)==1 # only angle theta = varargin{1}; elseif length(varargin)==2 # origin point (as array) and angle var = varargin{1}; dx = var(1); dy = var(2); dz = var(3); theta = varargin{2}; elseif length(varargin)==3 # origin (x and y) and angle dx = varargin{1}; dy = 0; dz = varargin{2}; theta = varargin{3}; elseif length(varargin)==4 # origin (x and y) and angle dx = varargin{1}; dy = varargin{2}; dz = varargin{3}; theta = varargin{4}; end # compute coefs cot = cos(theta); sit = sin(theta); # create transformation trans = [... cot 0 sit 0;... 0 1 0 0;... -sit 0 cot 0;... 0 0 0 1]; # add the translation part t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; trans = t*trans/t; endfunction geometry/inst/geom3d/polygons3d.m0000644000175000017500000000431712035504503016663 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} polygons3d () ## POLYGONS3D Description of functions operating on 3D polygons ## ## A 3D polygon is simply a set of 3D points (called vertices) which are ## assumed to be located in the same plane. ## Several functions are provided for computing basic geometrical ## parameters (centroid, angles), or intersections with lines or planes. ## ## @seealso{polygon3dNormalAngle, polygonCentroid3d, clipConvexPolygon3dHP ## intersectLinePolygon3d, intersectLineTriangle3d, intersectRayPolygon3d ## drawPolygon3d, drawPolyline3d, fillPolygon3d} ## @end deftypefn function polygons3d() help polygons3d endfunction geometry/inst/geom3d/normalizePlane.m0000644000175000017500000000532712035504503017544 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{plane2} =} normalizePlane (@var{plane1}) ## Normalize parametric representation of a plane ## ## PLANE2 = normalizePlane(PLANE1); ## Transforms the plane PLANE1 in the following format: ## [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], where: ## - (X0, Y0, Z0) is a point belonging to the plane ## - (DX1, DY1, DZ1) is a first direction vector ## - (DX2, DY2, DZ2) is a second direction vector ## into another plane, with the same format, but with: ## - (x0 y0 z0) is the closest point of plane to the origin ## - (DX1 DY1 DZ1) has norm equal to 1 ## - (DX2 DY2 DZ2) has norm equal to 1 and is orthogonal to (DX1 DY1 DZ1) ## ## @seealso{planes3d, createPlane} ## @end deftypefn function plane2 = normalizePlane (plane1) # compute first direction vector d1 = normalizeVector (plane1(:,4:6)); # compute second direction vector n = normalizeVector (planeNormal (plane1)); d2 = -normalizeVector (cross (d1, n)); # compute origin point of the plane origins = repmat ([0 0 0], [size(plane1, 1) 1]); p0 = projPointOnPlane (origins, [plane1(:,1:3) d1 d2]); # create the resulting plane plane2 = [p0 d1 d2]; endfunction geometry/inst/geom3d/drawVector3d.m0000644000175000017500000000445412041304441017127 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} function_name (@var{pos}, @var{vect}) ## Draw vector at a given position ## ## Example ## @example ## figure; hold on; ## drawVector3d([2 3 4], [1 0 0]); ## drawVector3d([2 3 4], [0 1 0]); ## drawVector3d([2 3 4], [0 0 1]); ## view(3); ## @end example ## ## @seealso{quiver3} ## @end deftypefn function varargout = drawVector3d(pos, vect, varargin) h = quiver3 (pos(:, 1), pos(:, 2), pos(:, 3), ... vect(:, 1), vect(:, 2), vect(:, 3), varargin{:}); # format output if nargout > 0 varargout{1} = h; end endfunction %!demo %! figure; hold on; %! drawVector3d([2 3 4], [1 0 0]); %! drawVector3d([2 3 4], [0 1 0]); %! drawVector3d([2 3 4], [0 0 1]); %! view(3); geometry/inst/geom3d/circle3dOrigin.m0000644000175000017500000000511412035660370017423 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p} =} circle3dOrigin([@var{xc} @var{yc} @var{zc} @var{r} @var{theta} @var{phi}]) ## @deftypefnx {Function File} {@var{p} =} circle3dOrigin([@var{xc} @var{yc} @var{zc} @var{r} @var{theta} @var{phi} @var{psi}]) ## Return the first point of a 3D circle ## ## Returns the origin point of the circle, i.e. the first point used for ## drawing circle. ## ## @seealso{circles3d, points3d, circle3dPosition} ## @end deftypefn function ori = circle3dOrigin(varargin) # get center and radius circle = varargin{1}; xc = circle(:,1); yc = circle(:,2); zc = circle(:,3); r = circle(:,4); # get angle of normal theta = circle(:,5); phi = circle(:,6); # get roll if size(circle, 2)==7 psi = circle(:,7); else psi = zeros(size(circle, 1), 1); end # create origin point pt0 = [r 0 0]; # compute transformation from local basis to world basis trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); # transform the point ori = transformPoint3d(pt0, trans); endfunction geometry/inst/geom3d/cart2cyl.m0000644000175000017500000000620112041271112016271 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{cyl} =} cart2cyl (@var{point}) ## @deftypefnx {Function File} {@var{cyl} =} cart2cyl (@var{x}, @var{y}, @var{z}) ## Convert cartesian to cylindrical coordinates ## ## CYL = cart2cyl(POINT) ## convert the 3D cartesian coordinates of points POINT (given by [X Y Z] ## where X, Y, Z have the same size) into cylindrical coordinates CYL, ## given by [THETA R Z]. ## THETA is the arctangent of the ratio Y/X (between 0 and 2*PI) ## R can be computed using sqrt(X^2+Y^2) ## Z keeps the same value. ## The size of THETA, and R is the same as the size of X, Y and Z. ## ## CYL = cart2cyl(X, Y, Z) ## provides coordinates as 3 different parameters ## ## Example ## @example ## cart2cyl([-1 0 2]) ## gives : 4.7124 1.0000 2.0000 ## @end example ## ## @seealso{agles3d, cart2pol, cart2sph2} ## @end deftypefn function varargout = cart2cyl(varargin) # process input parameters if length(varargin)==1 var = varargin{1}; x = var(:,1); y = var(:,2); z = var(:,3); elseif length(varargin)==3 x = varargin{1}; y = varargin{2}; z = varargin{3}; end # convert coordinates dim = size(x); theta = reshape(mod(atan2(y(:), x(:))+2*pi, 2*pi), dim); r = reshape(sqrt(x(:).*x(:) + y(:).*y(:)), dim); # process output parameters if nargout==0 ||nargout==1 if length(dim)>2 || dim(2)>1 varargout{1} = {theta r z}; else varargout{1} = [theta r z]; end elseif nargout==3 varargout{1} = theta; varargout{2} = r; varargout{3} = z; end endfunction geometry/inst/geom3d/sph2cart2.m0000644000175000017500000000633212035504503016371 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{c} =} sph2cart2 (@var{s}) ## @deftypefnx {Function File} {@var{c} =} sph2cart2 (@var{theta}, @var{phi}) ## @deftypefnx {Function File} {@var{c} =} sph2cart2 (@var{theta}, @var{phi}, @var{rho}) ## @deftypefnx {Function File} {[@var{x} @var{y} @var{z}]=} sph2cart2 (@dots{}) ## Convert spherical coordinates to cartesian coordinates ## ## C = SPH2CART2(S) ## C = SPH2CART2(THETA, PHI) (assume rho = 1) ## C = SPH2CART2(THETA, PHI, RHO) ## [X, Y, Z] = SPH2CART2(THETA, PHI, RHO); ## ## S = [phi theta rho] (spherical coordinate). ## C = [X Y Z] (cartesian coordinate) ## ## The following convention is used: ## THETA is the colatitude, in radians, 0 for north pole, +pi for south ## pole, pi/2 for points with z=0. ## PHI is the azimuth, in radians, defined as matlab cart2sph: angle from ## Ox axis, counted counter-clockwise. ## RHO is the distance of the point to the origin. ## Discussion on choice for convention can be found at: ## http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf ## ## @seealso{angles3d, cart2sph2, sph2cart, sph2cart2d} ## @end deftypefn function varargout = sph2cart2(theta, phi, rho) # Process input arguments if nargin == 1 phi = theta(:, 2); if size (theta, 2) > 2 rho = theta(:, 3); else rho = ones (size (phi)); end theta = theta(:, 1); elseif nargin == 2 rho = ones (size (theta)); end # conversion rz = rho .* sin(theta); x = rz .* cos(phi); y = rz .* sin(phi); z = rho .* cos(theta); if nargout <= 1 varargout{1} = [x, y, z]; else varargout{1} = x; varargout{2} = y; varargout{3} = z; end endfunction geometry/inst/geom3d/revolutionSurface.m0000644000175000017500000001331212041303465020275 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{x}, @var{y}, @var{z}] =} revolutionSurface (@var{c1}, @var{c2}, @var{n}) ## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} revolutionSurface (@var{curve}, @var{n}) ## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} revolutionSurface (@dots{}, @var{theta}) ## @deftypefnx {Function File} {[@var{x}, @var{y}, @var{z}] =} revolutionSurface (@dots{}, @var{line}) ## Create a surface of revolution from a planar curve ## ## usage ## [X Y Z] = revolutionSurface(C1, C2, N); ## create the surface of revolution of parametrized function (xt, yt), ## with N+1 equally spaced slices, around the Oz axis. ## It assumed that C1 corresponds to the x coordinate, and that C2 ## corresponds to the Oz coordinate. ## ## [X Y Z] = revolutionSurface(CURVE, N); ## is the same, but generating curve is given in a single parameter CURVE, ## which is a [Nx2] array of 2D points. ## ## [X Y Z] = revolutionSurface(..., THETA) ## where THETA is a vector, uses values of THETA for computing revolution ## angles. ## ## [X Y Z] = revolutionSurface(..., LINE); ## where LINE is a 1x4 array, specifes the revolution axis in the ## coordinate system of the curve. LINE is a row vector of 4 parameters, ## containing [x0 y0 dx dy], where (x0,y0) is the origin of the line and ## (dx,dy) is a direction vector of the line. ## The resulting revolution surface still has Oz axis as symmetry axis. It ## can be transformed using transformPoint3d function. ## Surface can be displayed using : ## @code{H = surf(X, Y, Z);} ## H is a handle to the created patch. ## ## revolutionSurface(...); ## by itself, directly shows the created patch. ## ## Example ## @example ## # draws a piece of torus ## circle = circleAsPolygon([10 0 3], 50); ## [x y z] = revolutionSurface(circle, linspace(0, 4*pi/3, 50)); ## surf(x, y, z); ## axis square equal; ## @end example ## ## @seealso{surf, transformPoint3d, drawSphere, drawTorus, drawEllipsoid} ## @end deftypefn function varargout = revolutionSurface(varargin) ## Initialisations # default values # use revolution using the full unit circle, decomposed into 24 angular # segments (thus, some vertices correspond to particular angles 30, # 45...) theta = linspace(0, 2*pi, 25); # use planar vertical axis as default revolution axis revol = [0 0 0 1]; # extract the generating curve var = varargin{1}; if size(var, 2)==1 xt = var; yt = varargin{2}; varargin(1:2) = []; else xt = var(:,1); yt = var(:,2); varargin(1) = []; end # extract optional parameters: angles, axis of revolution # parameters are identified from their length while ~isempty(varargin) var = varargin{1}; if length(var) == 4 # axis of rotation in the base plane revol = var; elseif length(var) == 1 # number of points -> create row vector of angles theta = linspace(0, 2*pi, var); else # use all specified angle values theta = var(:)'; end varargin(1) = []; end ## Create revolution surface # ensure length is enough m = length(xt); if m==1 xt = [xt xt]; end # ensure x and y are vertical vectors xt = xt(:); yt = yt(:); # transform xt and yt to replace in the reference of the revolution axis tra = createTranslation(-revol(1:2)); rot = createRotation(pi/2 - lineAngle(revol)); [xt yt] = transformPoint(xt, yt, tra*rot); # compute surface vertices x = xt * cos(theta); y = xt * sin(theta); z = yt * ones(size(theta)); ## Process output arguments # format output depending on how many output parameters are required if nargout == 0 # draw the revolution surface surf(x, y, z); elseif nargout == 1 # draw the surface and return a handle to the shown structure h = surf(x, y, z); varargout{1} = h; elseif nargout == 3 # return computed mesh varargout = {x, y, z}; end endfunction %!demo %! # draws a piece of torus %! circle = circleAsPolygon ([10 0 3], 50); %! [x y z] = revolutionSurface (circle, linspace(0, 4*pi/3, 50)); %! surf (x, y, z); %! axis square equal; geometry/inst/shape2d/0000755000175000017500000000000012130276034014550 5ustar juanpijuanpigeometry/inst/shape2d/shapecentroid.m0000644000175000017500000001204212035504503017554 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} { @var{cm} =} shapecentroid (@var{pp}) ## Centroid of a simple plane shape defined with piecewise smooth polynomials. ## ## The shape is defined with piecewise smooth polynomials. @var{pp} is a ## cell where each elements is a 2-by-(poly_degree+1) matrix containing a pair ## of polynomials. ## @code{px(i,:) = pp@{i@}(1,:)} and @code{py(i,:) = pp@{i@}(2,:)}. ## ## The edges of the shape should not self-intersect. This function does not check for the ## sanity of the shape. ## ## @seealso{shapearea, shape2polygon} ## @end deftypefn function cm = shapecentroid (shape) cm = sum( cell2mat ( cellfun (@CMint, shape, 'UniformOutput', false)), 1); A = shapearea(shape); cm = cm / A; [~,id] = lastwarn ('',''); if strcmp (id ,'geom2d:shapearea:InvalidResult') lastwarn('Inverting centroid','geom2d:shapecentroid:InvalidResult'); cm = -cm; end endfunction function dcm = CMint (x) px = x(1,:); py = x(2,:); Px = polyint (conv(conv (-px , py) , polyder (px))); Py = polyint (conv(conv (px , py) , polyder (py))); dcm = zeros (1,2); dcm(1) = diff(polyval(Px,[0 1])); dcm(2) = diff(polyval(Py,[0 1])); endfunction %!demo # non-convex bezier shape %! boomerang = {[ 0 -2 1; ... %! -4 4 0]; ... %! [0.25 -1; ... %! 0 0]; ... %! [ 0 1.5 -0.75; ... %! -3 3 0]; %! [0.25 0.75; ... %! 0 0]}; %! CoM = shapecentroid (boomerang) %! Gcentroid = centroid(shape2polygon(boomerang)) %! figure(1); clf; %! shapeplot(boomerang,'-o'); %! hold on %! drawPoint(CoM,'xk;shape centroid;'); %! drawPoint(Gcentroid,'xr;point centroid;'); %! hold off %! axis equal %!demo %! Lshape = {[0.00000 0.76635; -0.67579 -0.24067]; ... %! [0.77976 0.76635; 0.00000 -0.91646]; ... %! [0.00000 1.54611; 0.38614 -0.91646]; ... %! [-0.43813 1.54611; 0.00000 -0.53032]; ... %! [0.00000 1.10798; 0.28965 -0.53032]; ... %! [-0.34163 1.10798; 0.00000 -0.24067]};... %! CoM = shapecentroid (Lshape) %! Gcentroid = centroid (shape2polygon (Lshape)) %! %! shapeplot(Lshape,'-o'); %! hold on %! drawPoint(CoM,'xk;shape centroid;'); %! drawPoint(Gcentroid,'xr;point centroid;'); %! hold off %! axis equal %!test %! square = {[1 -0.5; 0 -0.5]; [0 0.5; 1 -0.5]; [-1 0.5; 0 0.5]; [0 -0.5; -1 0.5]}; %! CoM = shapecentroid (square); %! assert (CoM, [0 0], sqrt(eps)); %!test %! square = {[1 -0.5; 0 -0.5]; [0 0.5; 1 -0.5]; [-1 0.5; 0 0.5]; [0 -0.5; -1 0.5]}; %! square_t = shapetransform (square,[1;1]); %! CoM = shapecentroid (square_t); %! assert (CoM, [1 1], sqrt(eps)); %!test %! circle = {[1.715729 -6.715729 0 5; ... %! -1.715729 -1.568542 8.284271 0]; ... %! [1.715729 1.568542 -8.284271 0; ... %! 1.715729 -6.715729 0 5]; ... %! [-1.715729 6.715729 0 -5; ... %! 1.715729 1.568542 -8.284271 0]; ... %! [-1.715729 -1.568542 8.284271 0; ... %! -1.715729 6.715729 0 -5]}; %! CoM = shapecentroid (circle); %! assert (CoM , [0 0], 5e-3); %!shared shape %! shape = {[-93.172 606.368 -476.054 291.429; ... %! -431.196 637.253 11.085 163.791]; ... %! [-75.3626 -253.2337 457.1678 328.5714; ... %! 438.7659 -653.6278 -7.9953 380.9336]; ... %! [-89.5841 344.9716 -275.3876 457.1429; ... %! -170.3613 237.8858 1.0469 158.0765];... %! [32.900 -298.704 145.804 437.143; ... %! -243.903 369.597 -34.265 226.648]; ... %! [-99.081 409.127 -352.903 317.143; ... %! 55.289 -114.223 -26.781 318.076]; ... %! [-342.231 191.266 168.108 274.286; ... %! 58.870 -38.083 -89.358 232.362]}; %!test # x-Reflection %! v = shapecentroid (shape)(:); %! T = createLineReflection([0 0 1 0]); %! nshape = shapetransform (shape, T); %! vn = shapecentroid (nshape)(:); %! assert(vn,T(1:2,1:2)*v); %!test # Rotation %! v = shapecentroid (shape)(:); %! T = createRotation(v.',pi/2); %! nshape = shapetransform (shape, T); %! vn = shapecentroid (nshape)(:); %! assert(vn,v,1e-2); %!test # Translation %! v = shapecentroid (shape)(:); %! nshape = shapetransform (shape, -v); %! vn = shapecentroid (nshape)(:); %! assert(vn,[0; 0],1e-2); geometry/inst/shape2d/curveval.m0000644000175000017500000000202012035504503016546 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p} = } curveval (@var{curve}, @var{t}) ## Evaluates parametric @var{curve} at @var{t}. ## ## @end deftypefn function p = curveval (curve, t) dim = size (curve,1); p = zeros (length(t), dim); for i = 1:dim p(:,i) = polyval (curve(i,:), t); end endfunction geometry/inst/shape2d/shapetransform.m0000644000175000017500000000623512035504503017767 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{nshape} = } shapetransform (@var{shape}, @var{T}) ## Applies transformation to a shape defined by piecewise smooth polynomials. ## ## @var{shape} is a cell where each elements is a 2-by-(poly_degree+1) matrix ## containing a pair of polynomials. ## ## Format of @var{T} can be one of : ## @example ## @group ## [c] , [a b] , [a b c] or [a b c] ## [f] [d e] [d e f] [d e f] ## [0 0 1] ## @end group ## @end example ## ## @seealso{shape2polygon, shapeplot} ## @end deftypefn function nshape = shapetransform (shape, Trans) if size(Trans,1) < 2 error("geometry:shapetransform:InvalidArgument", ... "Transformation can be 2x1, 2x2, 2x3 or 3x3. See help."); end if ~iscell(shape) error("geometry:shapetransform:InvalidArgument", "Shape must be a cell of 2D polynomials."); end A =[]; v = []; switch size(Trans,2) case 1 # Just translation v = Trans; case 2 # Just linear transformation A = Trans; case 3 # Affine transform A = Trans(1:2,1:2); v = Trans(1:2,3); end nshape = cellfun (@(x)polytransform (x,A,v), shape, 'UniformOutput',false); endfunction function np = polytransform(p,A,v) np = p; if ~isempty (A) np = A*np; end if ~isempty (v) np(:,end) = np(:,end) + v; end endfunction %!demo %! shape = {[-93.172 606.368 -476.054 291.429; ... %! -431.196 637.253 11.085 163.791]; ... %! [-75.3626 -253.2337 457.1678 328.5714; ... %! 438.7659 -653.6278 -7.9953 380.9336]; ... %! [-89.5841 344.9716 -275.3876 457.1429; ... %! -170.3613 237.8858 1.0469 158.0765];... %! [32.900 -298.704 145.804 437.143; ... %! -243.903 369.597 -34.265 226.648]; ... %! [-99.081 409.127 -352.903 317.143; ... %! 55.289 -114.223 -26.781 318.076]; ... %! [-342.231 191.266 168.108 274.286; ... %! 58.870 -38.083 -89.358 232.362]}; %! %! A = shapearea (shape); %! T = eye(2)/sqrt(A); %! shape = shapetransform (shape,T); %! T = shapecentroid (shape)(:); %! shape = shapetransform (shape,-T + [2; 0]); %! %! close %! shapeplot (shape,'-r','linewidth',2); %! hold on %! for i = 1:9 %! T = createRotation (i*pi/5)(1:2,1:2)/exp(0.3*i); %! shapeplot (shapetransform(shape, T), 'color',rand(1,3),'linewidth',2); %! end %! hold off %! axis tight %! axis square geometry/inst/shape2d/shapeplot.m0000644000175000017500000000314412035504503016726 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } shapeplot (@var{shape}) ## @deftypefnx {Function File} {@var{h} = } shapeplot (@var{shape}, @var{N}) ## @deftypefnx {Function File} {@var{h} = } shapeplot (@dots{}, @var{param}, @var{value}) ## Pots a 2D shape defined by piecewise smooth polynomials in the current axis. ## ## @var{pp} is a cell where each elements is a 2-by-(poly_degree+1) matrix ## containing a pair of polynomials. ## @var{N} is the number of points to be used in non-straight edges. ## Additional parameter value pairs are passed to @code{drawPolygon}. ## ## @seealso{drawPolygon, shape2polygon} ## @end deftypefn function h = shapeplot(shape, varargin) n = cell2mat(cellfun(@(x)curveval(x,rand(1,5)), shape, 'uniformoutput',false)); dr = (max(n(:,1))-min(n(:,1)))*(max(n(:,2))-min(n(:,2)))/100; p = shape2polygon(shape,'tol', dr); h = drawPolygon(p,varargin{:}); endfunction geometry/inst/shape2d/shape2polygon.m0000644000175000017500000000516512035504503017526 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{polygon} = } shape2polygon (@var{shape}) ## @deftypefnx {Function File} {@var{polygon} = } shape2polygon (@dots{},@var{property},@var{value},@dots{}) ## Transforms a 2D shape described by piecewise smooth polynomials into a polygon. ## ## @var{shape} is a n-by-1 cell where each element is a pair of polynomials ## compatible with polyval. ## @var{polygon} is a k-by-2 matrix, where each row represents a vertex. ## The property-value pairs are passed to @code{curve2polyline}. ## ## @seealso{polygon2shape, curve2poyline} ## @end deftypefn function polygon = shape2polygon (shape, varargin) polygon = cell2mat ( ... cellfun (@(x) curve2polyline(x,varargin{:}), shape,'UniformOutput',false) ); polygon = simplifypolygon(polygon); if size (polygon, 1) == 1 polygon(2,1) = polyval (shape{1}(1,:), 1); polygon(2,2) = polyval (shape{1}(2,:), 1); end endfunction %!demo %! shape = {[-93.172 606.368 -476.054 291.429; ... %! -431.196 637.253 11.085 163.791]; ... %! [-75.3626 -253.2337 457.1678 328.5714; ... %! 438.7659 -653.6278 -7.9953 380.9336]; ... %! [-89.5841 344.9716 -275.3876 457.1429; ... %! -170.3613 237.8858 1.0469 158.0765];... %! [32.900 -298.704 145.804 437.143; ... %! -243.903 369.597 -34.265 226.648]; ... %! [-99.081 409.127 -352.903 317.143; ... %! 55.289 -114.223 -26.781 318.076]; ... %! [-342.231 191.266 168.108 274.286; ... %! 58.870 -38.083 -89.358 232.362]}; %! %! # Estimate a good tolerance %! n = cell2mat(cellfun(@(x)curveval(x,rand(1,10)), shape, 'uniformoutput',false)); %! dr = (max(n(:,1))-min(n(:,1)))*(max(n(:,2))-min(n(:,2)))*40; %! p = shape2polygon (shape,'tol',dr); %! %! figure(1) %! shapeplot(shape,'-b'); %! hold on; %! drawPolygon (p,'-or'); %! hold off geometry/inst/shape2d/curve2polyline.m0000644000175000017500000001005512035504503017710 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{polyline} = } curve2polyline (@var{curve}) ## @deftypefnx {Function File} {@var{polyline} = } curve2polyline (@dots{},@var{property},@var{value},@dots{}) ## Adaptive sampling of a parametric curve. ## ## The @var{curve} is described as a 2-by-N matrix. Rows correspond to the ## polynomial (compatible with @code{polyval}) describing the respective component ## of the curve. The curve must be parametrized in the interval [0,1]. ## The vertices of the polyline are accumulated in regions of the curve where ## the curvature is higher. ## ## @strong{Parameters} ## @table @samp ## @item 'Nmax' ## Maximum number of vertices. Not used. ## @item 'Tol' ## Tolerance for the error criteria. Default value @code{1e-4}. ## @item 'MaxIter' ## Maximum number of iterations. Default value @code{10}. ## @item 'Method' ## Not implemented. ## @end table ## ## @seealso{shape2polygon, curveval} ## @end deftypefn ## This function is based on the algorithm described in ## L. H. de Figueiredo (1993). "Adaptive Sampling of Parametric Curves". Graphic Gems III. ## I had to remove the recursion so this version could be improved. ## Thursday, April 12 2012 -- JuanPi function [polyline t bump]= curve2polyline (curve, varargin) ## TODO make tolerance relative to the "diameter" of the curve. # --- Parse arguments --- # parser = inputParser (); parser.FunctionName = "curve2polyline"; parser = addParamValue (parser,'Nmax', 32, @(x)x>0); parser = addParamValue (parser,'Tol', 1e-4, @(x)x>0); parser = addParamValue (parser,'MaxIter', 10, @(x)x>0); parser = parse(parser,varargin{:}); Nmax = parser.Results.Nmax; tol = parser.Results.Tol; MaxIter = parser.Results.MaxIter; clear parser toldef # ------ # t = [0; 1]; tf = 1; points = 1; for iter = 1:MaxIter # Add parameter values where error is still bigger than tol. t = interleave(t, tf); nt = length(t); # Update error polyline = curveval (curve,t); bump = bumpyness(polyline); # Check which intervals must be subdivided idx = find(bump > tol); # The position of the bumps mpas into intervals # 1 -> 1 2 # 2 -> 3 4 # 3 -> 5 6 # and so on idx = [2*(idx-1)+1; 2*idx](:); tf = false (nt-1,1); tf(idx) = true; if all (!tf) break; end end endfunction function f = bumpyness (p) ## Check for co-linearity ## TODO implement various method for this ## -- Area of the triangle close to zero (used currently). ## -- Angle close to pi. ## -- abs(p0-pt) + abs(pt-p1) - abs(p0-p1) almost zero. ## -- Curve's tange at 0,t,1 are almost parallel. ## -- pt is in chord p0 -> p1. ## Do this in isParallel.m and remove this function PL = p(1:2:end-2,:); PC = p(2:2:end-1,:); PR = p(3:2:end,:); a = PL - PC; b = PR - PC; f = (a(:,1).*b(:,2) - a(:,2).*b(:,1)).^2; endfunction function tt = interleave (t,varargin) nt = length(t); ntt = 2 * nt -1; tt = zeros(ntt,1); tt(1:2:ntt) = t; beta = 0.4 + 0.2*rand(nt-1, 1); tt(2:2:ntt) = t(1:end-1) + beta.*(t(2:end)-t(1:end-1)); if nargin > 1 tf = true (ntt,1); tf(2:2:ntt) = varargin{1}; tt(!tf) = []; end endfunction %!demo %! curve = [0 0 1 0;1 -0.3-1 0.3 0]; %! polyline = curve2polyline(curve,'tol',1e-8); %! %! t = linspace(0,1,100)'; %! pc = curveval(curve,t); %! %! plot(polyline(:,1),polyline(:,2),'-o',pc(:,1),pc(:,2),'-r') geometry/inst/shape2d/shapearea.m0000644000175000017500000000473412035504503016666 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} { @var{a} =} shapearea (@var{pp}) ## Calculate the area of a 2D shape defined with piecewise smooth polynomials. ## ## Shape is defined with piecewise smooth polynomials. @var{pp} is a ## cell where each elements is a 2-by-(poly_degree+1) array containing a pair of ## polynomials. ## ## @code{px(i,:) = pp@{i@}(1,:)} and @code{py(i,:) = pp@{i@}(2,:)}. ## ## @seealso{shapecentroid, shape2polygon, shapeplot} ## @end deftypefn function [A ccw] = shapearea (shape) A = sum(cellfun (@Aint, shape)); if A < 0 warning ('geom2d:shapearea:InvalidResult', ... 'Shape has negative area. Assuming this is due to a clockwise parametrization of the boundary'); A = -A; end endfunction function dA = Aint (x) px = x(1,:); py = x(2,:); P = polyint (conv (px, polyder(py))); dA = diff(polyval(P,[0 1])); end %!demo # non-convex piece-wise polynomial shape %! boomerang = {[ 0 -2 1; ... %! -4 4 0]; ... %! [0.25 -1; ... %! 0 0]; ... %! [ 0 1.5 -0.75; ... %! -3 3 0]; %! [0.25 0.75; ... %! 0 0]}; %! A = shapearea (boomerang) %!test %! triangle = {[1 0; 0 0]; [-0.5 1; 1 0]; [-0.5 0.5; -1 1]}; %! A = shapearea (triangle); %! assert (0.5, A); %!test %! circle = {[1.715729 -6.715729 0 5; ... %! -1.715729 -1.568542 8.284271 0]; ... %! [1.715729 1.568542 -8.284271 0; ... %! 1.715729 -6.715729 0 5]; ... %! [-1.715729 6.715729 0 -5; ... %! 1.715729 1.568542 -8.284271 0]; ... %! [-1.715729 -1.568542 8.284271 0; ... %! -1.715729 6.715729 0 -5]}; %! A = shapearea (circle); %! assert (pi*5^2, A, 5e-2); geometry/inst/polynomialCurves2d/0000755000175000017500000000000012130276034017023 5ustar juanpijuanpigeometry/inst/polynomialCurves2d/polynomialCurveCentroid.m0000644000175000017500000000775112114701140024064 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{c} =} polynomialCurveCentroid (@var{t}, @var{xcoef}, @var{ycoef}) ## @deftypefnx {Function File} {@var{c} =} polynomialCurveCentroid (@var{t}, @var{coefs}) ## @deftypefnx {Function File} {@var{c} =} polynomialCurveCentroid (@dots{}, @var{tol}) ## Compute the centroid of a polynomial curve ## ## @var{xcoef} and @var{ycoef} are row vectors of coefficients, in the form: ## [a0 a1 a2 ... an] ## @var{t} is a 1x2 row vector, containing the bounds of the parametrization ## variable: @var{t} = [T0 T1], with @var{t} taking all values between T0 and T1. ## @var{c} contains coordinate of the polynomial curve centroid. ## ## @var{coefs} is either a 2xN matrix (one row for the coefficients of each ## coordinate), or a cell array. ## ## @var{tol} is the tolerance fo computation (absolute). ## ## @seealso{polynomialCurves2d, polynomialCurveLength} ## @end deftypefn function centroid = polynomialCurveCentroid(tBounds, varargin) ## Extract input parameters # parametrization bounds t0 = tBounds(1); t1 = tBounds(end); # polynomial coefficients for each coordinate var = varargin{1}; if iscell(var) cx = var{1}; cy = var{2}; varargin(1) = []; elseif size(var, 1)==1 cx = varargin{1}; cy = varargin{2}; varargin(1:2)=[]; else cx = var(1,:); cy = var(2,:); varargin(1)=[]; end # convert to Octave polyval format cx = cx(end:-1:1); cy = cy(end:-1:1); # tolerance tol = 1e-6; if ~isempty(varargin) tol = varargin{1}; end ## compute length by numerical integration # compute derivative of the polynomial dx = polyder (cx); dy = polyder (cy); # compute curve length by integrating the Jacobian L = quad(@(t)sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); # compute first coordinate of centroid xc = quad(@(t)polyval(cx, t).*sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); # compute first coordinate of centroid yc = quad(@(t)polyval(cy, t).*sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); # divide result of integration by total length of the curve centroid = [xc yc]/L; endfunction %!demo %! bounds = [-1 1]; %! coefs = [0 1 1; 0 -1 2]; %! c = polynomialCurveCentroid (bounds, coefs); %! %! drawPolynomialCurve (bounds, coefs(1,:), coefs(2,:)); %! hold on %! plot (c(1),c(2),'sr') %! hold off %! # ------------------------------------------------- %! # Centriod of a polynomial curve geometry/inst/polynomialCurves2d/polynomialCurveSetFit.m0000644000175000017500000001727312130270223023514 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{coefs}=} polynomialCurveSetFit (@var{img}) ## @deftypefnx {Function File} {@dots{} =} polynomalCurveSetFit (@var{img}, @var{deg}) ## @deftypefnx {Function File} {[@dots{} @var{lbl}] =} polynomalCurveSetFit (@dots{}) ## Fit a set of polynomial curves to a segmented image ## ## Result is a cell array of matrices. Each matrix is @var{deg}+1-by-2, and ## contains coefficients of polynomial curve for each coordinate. ## @var{bnds} contains the boundary of the parametrizations. ## @var{img} is first binarised, then skeletonized. ## ## Also returns an image of labels @var{lbl} for the segmented curves. The max label ## is the number of curves, and the length of @var{coefs}. ## ## Requires the toolboxes: ## - Optimization ## - Image Processing ## ## @seealso{polynomialCurves2d, polynomialCurveFit} ## @end deftypefn function [coefs lblBranches] = polynomialCurveSetFit(seg, varargin) # default degree for curves deg = 2; if ~isempty(varargin) deg = varargin{1}; end # ajoute un contour seg([1 end], :) = 1; seg(:, [1 end]) = 1; # skeletise le segmentat seg = bwmorph(seg, 'shrink', Inf); # compute image of multiple points (intersections between curves) imgNodes = imfilter(double(seg), ones([3 3])) .* seg > 3; # compute coordinate of nodes, as c entroids of the multiple points lblNodes = bwlabel(imgNodes, 8); struct = regionprops(lblNodes, 'Centroid'); nodes = zeros(length(struct), 2); for i=1:length(struct) nodes(i, [2 1]) = struct(i).Centroid; end figure(1) # subplot(1,2,1) # imshow(seg); # hold on # plot(nodes(:,1),nodes(:,2),'og') # subplot(1,2,2) imshow(imgNodes); hold on plot(nodes(:,1),nodes(:,2),'og') keyboard # enleve les bords de l'image seg([1 end], :) = 0; seg(:, [1 end]) = 0; # Isolate the branches imgBranches = seg & ~imgNodes; lblBranches = bwlabel(imgBranches, 8); # # donne une couleur a chaque branche, et affiche # map = colorcube(max(lblBranches(:))+1); # rgbBranches = label2rgb(lblBranches, map, 'w', 'shuffle'); # imshow(rgbBranches); # number of curves nBranches = max(lblBranches(:)); # allocate memory coefs = cell(nBranches, 1); bnds = cell(nBranches, 1); # For each curve, find interpolated polynomial curve for i = 1:nBranches # extract points corresponding to current curve imgBranch = lblBranches == i; points = chainPixels (imgBranch); # check number of points is sufficient if size(points, 1) < max(deg+1-2, 2) # find labels of nodes inds = unique(lblNodes(imdilate(imgBranch, true (3,3)))); inds = inds(inds ~= 0); if length(inds) < 2 warning ("geometry:poylnomialCurveSetFit", ... ['Could not find extremities of branch number ' num2str(i)]); continue; end # consider extremity nodes node0 = nodes(inds(1), :); node1 = nodes(inds(2), :); # use only a linear approximation xc = zeros(1, deg+1); yc = zeros(1, deg+1); xc(1) = node0(1); yc(1) = node0(2); xc(2) = node1(1)-node0(1); yc(2) = node1(2)-node0(2); # assigne au tableau de courbes coefs{i} = [xc;yc]; # next branch continue; end # find nodes closest to first and last points of the current curve [dist, ind0] = minDistancePoints(points(1, :), nodes); ##ok<*ASGLU> [dist, ind1] = minDistancePoints(points(end, :), nodes); # add nodes to the curve. points = [nodes(ind0,:); points; nodes(ind1,:)]; ##ok # parametrization of the polyline t = parametrize(points); t = t / max(t); # fit a polynomial curve to the set of points [xc yc] = polynomialCurveFit(... t, points, deg, ... 0, {points(1,1), points(1,2)},... 1, {points(end,1), points(end,2)}); plot(points(:,1),points(:,2),'or') hold on drawPolynomialCurve ([0 1], xc,yc); axis tight v = axis(); hold off imshow (~imgBranch) hold on plot(points(:,1),points(:,2),'or') drawPolynomialCurve ([0 1], xc,yc); axis xy axis (v); pause # stores result coefs{i} = [xc;yc]; end endfunction function points = chainPixels(img, varargin) #CHAINPIXELS return the list of points which constitute a curve on image # output = chainPixels(input) conn = 8; if ~isempty(varargin) conn = varargin{1}; end # matrice de voisinage if conn == 4 f = [0 1 0;1 1 1;0 1 0]; elseif conn == 8 f = ones([3 3]); end # find extremity points nb = imfilter(double(img), f) .* img; imgEnding = nb == 2 | nb == 1; [yi xi] = find(imgEnding); # extract coordinates of points [y x] = find(img); # index of first point if isempty(xi) # take arbitrary point ind = 1; else ind = find(x==xi(1) & y==yi(1)); end # allocate memory points = zeros(length(x), 2); if conn == 8 for i = 1:size(points, 1) # avoid multiple neighbors (can happen in loops) ind = ind(1); # add current point to chained curve points(i,:) = [x(ind) y(ind)]; # remove processed coordinate x(ind) = []; y(ind) = []; # find next candidate ind = find(abs(x-points(i,1))<=1 & abs(y-points(i,2))<=1); end else for i = 1:size(points, 1) # avoid multiple neighbors (can happen in loops) ind = ind(1); # add current point to chained curve points(i,:) = [x(ind) y(ind)]; # remove processed coordinate x(ind) = []; y(ind) = []; # find next candidate ind = find(abs(x-points(i,1)) + abs(y-points(i,2)) <=1 ); end end endfunction %!demo %! [m, cmap] = imread ("default.img"); %! m = ind2gray (m, cmap); %! mbw = im2bw(m, graythresh(m)*1.3); %! %! [c t] = polynomialCurveSetFit (mbw); %! %! figure(1) %! clf; %! imshow (m) %! hold on %! for i=1:numel(c) %! if !isempty (c{i}) %! drawPolynomialCurve ([0 1], c{i}); %! endif %! endfor %! %! hold off geometry/inst/polynomialCurves2d/polynomialCurvePoint.m0000644000175000017500000000574212114701140023404 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} =} polynomialCurvePoint (@var{t}, @var{xcoef},@var{ycoef}) ## @deftypefnx {Function File} {@var{point} =} polynomialCurvePoint (@var{t}, @var{coefs}) ## Compute point corresponding to a position ## ## @var{xcoef} and @var{ycoef} are row vectors of coefficients, in the form: ## [a0 a1 a2 ... an] ## @var{t} is a either a scalar, or a column vector, containing values of the ## parametrization variable. ## @var{point} is a 1x2 array containing coordinate of point corresponding to ## position given by @var{t}. If @var{t} is a vector, @var{point} has as many rows as @var{t}. ## ## @var{coefs} is either a 2xN matrix (one row for the coefficients of each ## coordinate), or a cell array. ## ## @seealso{polynomialCurves2d, polynomialCurveLength} ## @end deftypefn function point = polynomialCurvePoint (t, varargin) ## Extract input parameters # polynomial coefficients for each coordinate var = varargin{1}; if iscell (var) xCoef = var{1}; yCoef = var{2}; elseif size (var, 1)==1 xCoef = varargin{1}; yCoef = varargin{2}; else xCoef = var(1,:); yCoef = var(2,:); end ## compute length by numerical integration # convert polynomial coefficients to polyval convention cx = xCoef(end:-1:1); cy = yCoef(end:-1:1); # numerical integration of the Jacobian of parametrized curve point = [polyval(cx, t) polyval(cy, t)]; endfunction geometry/inst/polynomialCurves2d/polynomialCurveDerivative.m0000644000175000017500000000575512114701140024421 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{v} =} polynomialCurveDerivative (@var{t}, @var{xcoef},@var{ycoef}) ## @deftypefnx {Function File} {@var{v} =} polynomialCurveDerivative (@var{t}, @var{coefs}) ## Compute derivative vector of a polynomial curve ## ## @var{xcoef} and @var{ycoef} are row vectors of coefficients, in the form: ## [a0 a1 a2 ... an] ## @var{v} is a 1x2 array containing direction of derivative of polynomial ## curve, computed for position @var{t}. If @var{t} is a vector, @var{v} has as many rows ## as the length of @var{t}. ## ## @var{coefs} is either a 2xN matrix (one row for the coefficients of each ## coordinate), or a cell array. ## ## @seealso{polynomialCurves2d, polynomialCurveNormal, polynomialCurvePoint, ## polynomialCurveCurvature} ## @end deftypefn function v = polynomialCurveDerivative(t, varargin) ## Extract input parameters # polynomial coefficients for each coordinate var = varargin{1}; if iscell(var) xCoef = var{1}; yCoef = var{2}; elseif size(var, 1)==1 xCoef = varargin{1}; yCoef = varargin{2}; else xCoef = var(1,:); yCoef = var(2,:); end # convert to Octave polynomial convention xCoef = xCoef(end:-1:1); yCoef = yCoef(end:-1:1); # compute derivative of the polynomial dx = polyder (xCoef); dy = polyder (yCoef); # numerical integration of the Jacobian of parametrized curve v = [polyval(dx, t) polyval(dy, t)]; endfunction geometry/inst/polynomialCurves2d/drawPolynomialCurve.m0000644000175000017500000000535612130275153023221 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawPolynomialCurve (@var{bnd}, @var{xcoef}, @var{ycoef}) ## @deftypefnx {Function File} {@var{h} =} drawPolynomialCurve (@var{bnd}, @var{coefs}) ## @deftypefnx {Function File} {@var{h} =} drawPolynomialCurve (@dots{}, @var{npts}) ## Draw a polynomial curve approximation ## @end deftypefn function varargout = drawPolynomialCurve(tBounds, varargin) ## Extract input parameters % polynomial coefficients for each coordinate var = varargin{1}; if iscell(var) xCoef = var{1}; yCoef = var{2}; varargin(1) = []; elseif size(var, 1)==1 xCoef = varargin{1}; yCoef = varargin{2}; varargin(1:2) = []; else xCoef = var(1,:); yCoef = var(2,:); varargin(1) = []; end nPts = 120; if ~isempty(varargin) nPts = varargin{1}; end # parametrization bounds t0 = tBounds(1); t1 = tBounds(end); ## Drawing the polyline approximation # generate vector of absissa t = linspace (t0, t1, nPts+1)'; # compute corresponding positions pts = polynomialCurvePoint (t, xCoef, yCoef); # draw the resulting curve h = drawPolyline (pts); if nargout > 0 varargout{1} = h; end endfunction geometry/inst/polynomialCurves2d/polynomialCurveFit.m0000644000175000017500000002245312130275153023043 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{xc}, @var{yc}] =} polynomialCurveFit (@var{t}, @var{xt}, @var{yt}, @var{order}) ## @deftypefnx {Function File} {[@var{xc}, @var{yc}] =} polynomialCurveFit (@var{t}, @var{points}, @var{order}) ## @deftypefnx {Function File} {[@var{xc}, @var{yc}] =} polynomialCurveFit (@dots{}, @var{ti}, @var{condi}) ## Fit a polynomial curve to a series of points ## ## @var{t} is a Nx1 vector. ## ## @var{xt} and @var{yt} are coordinate for each parameter value (column vectors). ## @var{order} is the degree of the polynomial used for interpolation. ## @var{xc} and @var{yc} are polynomial coefficients, given in @var{order}+1 row vectors, ## starting from degree 0 and up to degree @var{order}. ## @var{points} specifies coordinate of points in a Nx2 array. ## ## Impose some specific conditions using @var{ti} and @var{condi}. ## ## @var{ti} is a value of the parametrization variable. @var{condi} is a cell ## array, with 2 columns, and as many rows as ## the derivatives specified for the given @var{ti}. Format for @var{condi} is: ## ## @var{condi} = @{X_I, Y_I; X_I', Y_I'; X_I", Y_I"; ...@}; ## ## with X_I and Y_I being the imposed coordinate at position @var{ti}, X_I' and ## Y_I' being the imposed first derivatives, X_I" and Y_I" the imposed ## second derivatives, and so on... ## To specify a derivative without specifying derivative with lower ## degree, value of lower derivative can be let empty, using '[]'. ## ## ## Requires the optimization Toolbox. ## ## Run @command{demo polynomialCurveFit} to see exaples of use. ## ## @seealso{polynomialCurves2d} ## @end deftypefn function varargout = polynomialCurveFit(t, varargin) ## extract input arguments # extract curve coordinate var = varargin{1}; if min(size(var))==1 # curve given as separate arguments xt = varargin{1}; yt = varargin{2}; varargin(1:2)=[]; else # curve coordinate bundled in a matrix if size(var, 1)1 Dx = var(1); Dy = var(2); else Dx = var; Dy = var; end varargin(1)=[]; ## Initialize local conditions # For a solution vector 'x', the following relation must hold: # Aeq * x == beq, # with: # Aeq Matrix M*N # beq column vector with length M # The coefficients of the Aeq matrix are initialized as follow: # First point and last point are considered successively. For each point, # k-th condition is the value of the (k-1)th derivative. This value is # computed using relation of the form: # value = sum_i ( fact(i) * t_j^pow(i) ) # with: # i indice of the (i-1) derivative. # fact row vector containing coefficient of each power of t, initialized # with a row vector equals to [1 1 ... 1], and updated for each # derivative by multiplying by corresponding power minus 1. # pow row vector of the powers of each monome. It is represented by a # row vector containing an increasing series of power, eventually # completed with zeros for lower degrees (for the k-th derivative, # the coefficients with power lower than k are not relevant). # Example for degree 5 polynom: # iter deriv pow fact # 1 0 [0 1 2 3 4 5] [1 1 1 1 1 1] # 2 1 [0 0 1 2 3 4] [0 1 2 3 4 5] # 3 2 [0 0 0 1 2 3] [0 0 1 2 3 4] # 4 3 [0 0 0 0 1 2] [0 0 0 1 2 3] # ... # The process is repeated for coordinate x and for coordinate y. # Initialize empty matrices Aeqx = zeros(0, Dx+1); beqx = zeros(0, 1); Aeqy = zeros(0, Dy+1); beqy = zeros(0, 1); # Process local conditions while ~isempty(varargin) if length(varargin)==1 warning('MatGeom:PolynomialCurveFit:ArgumentNumber', ... 'Wrong number of arguments in polynomialCurvefit'); end # extract parameter t, and cell array of local conditions ti = varargin{1}; cond = varargin{2}; # factors for coefficients of each polynomial. At the beginning, they # all equal 1. With successive derivatives, their value increase by the # corresponding powers. factX = ones(1, Dx+1); factY = ones(1, Dy+1); # start condition initialisations for i = 1:size(cond, 1) # degrees of each polynomial powX = [zeros(1, i) 1:Dx+1-i]; powY = [zeros(1, i) 1:Dy+1-i]; # update conditions for x coordinate if ~isempty(cond{i,1}) Aeqx = [Aeqx ; factY.*power(ti, powX)]; ##ok beqx = [beqx; cond{i,1}]; ##ok end # update conditions for y coordinate if ~isempty(cond{i,2}) Aeqy = [Aeqy ; factY.*power(ti, powY)]; ##ok beqy = [beqy; cond{i,2}]; ##ok end # update polynomial degrees for next derivative factX = factX.*powX; factY = factY.*powY; end varargin(1:2)=[]; end ## Initialisations # ensure column vectors t = t(:); xt = xt(:); yt = yt(:); # number of points to fit L = length(t); ## Compute coefficients of each polynomial # main matrix for x coordinate, size L*(degX+1) T = ones(L, Dx+1); for i = 1:Dx T(:, i+1) = power(t, i); end # compute interpolation # Octave compatibility - JPi 2013 xc = lsqlin (T, xt, zeros(1, Dx+1), 1, Aeqx, beqx)'; # main matrix for y coordinate, size L*(degY+1) T = ones(L, Dy+1); for i = 1:Dy T(:, i+1) = power(t, i); end # compute interpolation # Octave compatibility - JPi 2013 yc = lsqlin (T, yt, zeros(1, Dy+1), 1, Aeqy, beqy)'; ## Format output arguments if nargout <= 1 varargout{1} = {xc, yc}; else varargout{1} = xc; varargout{2} = yc; end endfunction function x = lsqlin (C, d, A, b, Aeq, beq) H = C'*C; q = -C'*d; x0 = zeros (size(C,2),size(d,2)); x = qp (x0, H, q, Aeq, beq, [], [],[], A, b); endfunction %!demo %! # defines a curve (circle arc) with small perturbations %! N = 50; %! t = linspace(0, 3*pi/4, N)'; %! xp = cos(t) + 5e-2*randn(size(t)); %! yp = sin(t) + 5e-2*randn(size(t)); %! %! [xc yc] = polynomialCurveFit(t, xp, yp, 3); %! %! figure(1); %! clf; %! drawPolynomialCurve(t([1 end]), xc, yc); %! hold on %! plot(xp,yp,'.g'); %! hold off %! axis tight %! axis equal %!demo %! # defines a curve (circle arc) with small perturbations %! N = 100; %! t = linspace(0, 3*pi/4, N)'; %! xp = cos(t) + 7e-2*randn(size(t)); %! yp = sin(t) + 7e-2*randn(size(t)); %! %! # plot the points %! figure (1); clf; hold on; %! axis ([-1.2 1.2 -.2 1.2]); axis equal; %! drawPoint (xp, yp, ".g"); %! %! # fit without knowledge on bounds %! [xc0 yc0] = polynomialCurveFit (t, xp, yp, 5); %! h = drawPolynomialCurve (t([1 end]), xc0, yc0); %! set(h, "color", "b") %! %! # fit by imposing coordinate on first point %! [xc1 yc1] = polynomialCurveFit (t, xp, yp, 5, 0, {1, 0}); %! h = drawPolynomialCurve (t([1 end]), xc1, yc1); %! set(h, "color", "r") %! %! # fit by imposing coordinate (1,0) and derivative (0,1) on first point %! [xc2 yc2] = polynomialCurveFit (t, xp, yp, 5, 0, {1, 0;0 1}); %! h = drawPolynomialCurve (t([1 end]), xc2, yc2); %! set(h, "color", "m") %! %! # fit by imposing several conditions on various points %! [xc3 yc3] = polynomialCurveFit (t, xp, yp, 5, ... %! 0, {1, 0;0 1}, ... # coord and first derivative of first point %! 3*pi/4, {-sqrt(2)/2, sqrt(2)/2}, ... # coord of last point %! pi/2, {[], [];-1, 0}); # derivative of point on the top of arc %! h = drawPolynomialCurve (t([1 end]), xc3, yc3); %! set(h, "color", "k") %! axis tight %! axis equal geometry/inst/geom2d/0000755000175000017500000000000012130276034014377 5ustar juanpijuanpigeometry/inst/geom2d/polarPoint.m0000644000175000017500000000614312035504503016707 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} = } polarPoint (@var{rho}, @var{theta}) ## @deftypefnx {Function File} {@var{point} = } polarPoint (@var{theta}) ## @deftypefnx {Function File} {@var{point} = } polarPoint (@var{point}, @var{rho}, @var{theta}) ## @deftypefnx {Function File} {@var{point} = } polarPoint (@var{x0}, @var{y0}, @var{rho}, @var{theta}) ##Create a point from polar coordinates (rho + theta) ## ## Creates a point using polar coordinate. @var{theta} is angle with horizontal ## (counted counter-clockwise, and in radians), and @var{rho} is the distance to ## origin. If only angle is given radius @var{rho} is assumed to be 1. ## ## If a point is given, adds the coordinate of the point to the coordinate of the specified ## point. For example, creating a point with : ## P = polarPoint([10 20], 30, pi/2); ## will give a result of [40 20]. ## ## @seealso{points2d} ## @end deftypefn function point = polarPoint(varargin) # default values x0 = 0; y0=0; rho = 1; theta =0; # process input parameters if length(varargin)==1 theta = varargin{1}; elseif length(varargin)==2 rho = varargin{1}; theta = varargin{2}; elseif length(varargin)==3 var = varargin{1}; x0 = var(:,1); y0 = var(:,2); rho = varargin{2}; theta = varargin{3}; elseif length(varargin)==4 x0 = varargin{1}; y0 = varargin{2}; rho = varargin{3}; theta = varargin{4}; end point = [x0 + rho.*cos(theta) , y0+rho.*sin(theta)]; endfunction geometry/inst/geom2d/hexagonalGrid.m0000644000175000017500000000772712035504503017345 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pts} = } hexagonalGrid (@var{bounds}, @var{origin}, @var{size}) ## Generate hexagonal grid of points in the plane. ## ## usage ## PTS = hexagonalGrid(BOUNDS, ORIGIN, SIZE) ## generate points, lying in the window defined by BOUNDS (=[xmin ymin ## xmax ymax]), starting from origin with a constant step equal to size. ## SIZE is constant and is equals to the length of the sides of each ## hexagon. ## ## TODO: add possibility to use rotated grid ## @end deftypefn function varargout = hexagonalGrid(bounds, origin, size, varargin) size = size(1); dx = 3*size; dy = size*sqrt(3); # consider two square grids with different centers pts1 = squareGrid(bounds, origin + [0 0], [dx dy], varargin{:}); pts2 = squareGrid(bounds, origin + [dx/3 0], [dx dy], varargin{:}); pts3 = squareGrid(bounds, origin + [dx/2 dy/2], [dx dy], varargin{:}); pts4 = squareGrid(bounds, origin + [-dx/6 dy/2], [dx dy], varargin{:}); # gather points pts = [pts1;pts2;pts3;pts4]; # eventually compute also edges, clipped by bounds # TODO : manage generation of edges if nargout>1 edges = zeros([0 4]); x0 = origin(1); y0 = origin(2); # find all x coordinate x1 = bounds(1) + mod(x0-bounds(1), dx); x2 = bounds(3) - mod(bounds(3)-x0, dx); lx = (x1:dx:x2)'; # horizontal edges : first find y's y1 = bounds(2) + mod(y0-bounds(2), dy); y2 = bounds(4) - mod(bounds(4)-y0, dy); ly = (y1:dy:y2)'; # number of points in each coord, and total number of points ny = length(ly); nx = length(lx); if bounds(1)-x1+dx0 varargout{1} = pts; if nargout>1 varargout{2} = edges; end end endfunction geometry/inst/geom2d/createDirectedCircle.m0000644000175000017500000000632312035504503020611 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{circle} = } createDirectedCircle (@var{p1}, @var{p2}, @var{p3}) ## @deftypefnx {Function File} {@var{circle} = } createDirectedCircle (@var{p1}, @var{p2}) ## Create a circle from 2 or 3 points. ## ## Creates the circle passing through the 3 given points. ## C is a 1x4 array of the form: [XC YX R INV]. ## ## When two points are given, creates the circle whith center @var{p1} and passing ## throuh the point @var{p2}. ## ## Works also when input are point arrays the same size, in this case the ## result has as many lines as the point arrays. ## ## Example ## ## ## @seealso{circles2d, createCircle} ## @end deftypefn function circle = createDirectedCircle(varargin) if nargin == 2 # inputs are the center and a point on the circle p1 = varargin{1}; p2 = varargin{2}; x0 = (p1(:,1) + p2(:,1))/2; y0 = (p1(:,2) + p2(:,2))/2; r = hypot((p2(:,1)-p1(:,1)), (p2(:,2)-p1(:,2)))/2; # circle is direct by default d = 0; elseif nargin == 3 # inputs are three points on the circle p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; # compute circle center line1 = medianLine(p1, p2); line2 = medianLine(p1, p3); center = intersectLines(line1, line2); x0 = center(:, 1); y0 = center(:, 2); # circle radius r = hypot((p1(:,1)-x0), (p1(:,2)-y0)); # compute circle orientation angle = angle3Points(p1, center, p2) + angle3Points(p2, center, p3); d = angle>2*pi; end circle = [x0 y0 r d]; endfunction geometry/inst/geom2d/reverseEdge.m0000644000175000017500000000377412035504503017027 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} = } reverseEdge (@var{edge}) ## Intervert the source and target vertices of edge ## ## REV = reverseEdge(EDGE); ## Returns the opposite edge of EDGE. ## EDGE has the format [X1 Y1 X2 Y2]. The resulting edge REV has value ## [X2 Y2 X1 Y1]; ## ## @seealso{edges2d, createEdge, reverseLine} ## @end deftypefn function res = reverseEdge(edge) res = [edge(:,3:4) edge(:,1:2)]; endfunction geometry/inst/geom2d/transforms2d.m0000644000175000017500000000451112035504503017201 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} transforms2d () ## Description of functions operating on transforms ## ## By 'transform' we mean an affine transform. A planar affine transform ## can be represented by a 3x3 matrix. ## ## Example ## ## @example ## # create a translation by the vector [10 20]: ## T = createTranslation([10 20]) ## T = ## 1 0 10 ## 0 1 20 ## 0 0 1 ##@end example ## ## @seealso{createTranslation, createRotation, createScaling, createBasisTransform, ## createHomothecy, createLineReflection, fitAffineTransform2d, ## transformPoint, transformVector, transformLine, transformEdge, ## rotateVector} ## @end deftypefn function transforms2d(varargin) help('transforms2d'); endfunction geometry/inst/geom2d/projPointOnLine.m0000644000175000017500000000547012035504503017653 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} = } projPointOnLine (@var{pt1}, @var{line}) ## Project of a point orthogonally onto a line ## ## Computes the (orthogonal) projection of point @var{pt1} onto the line @var{line}. ## ## Function works also for multiple points and lines. In this case, it ## returns multiple points. ## Point @var{pt1} is a [N*2] array, and @var{line} is a [N*4] array (see createLine ## for details). Result @var{point} is a [N*2] array, containing coordinates of ## orthogonal projections of @var{pt1} onto lines @var{line}. ## ## @seealso{lines2d, points2d, isPointOnLine, linePosition} ## @end deftypefn function point = projPointOnLine(point, line) # ensure input arguments have same size if size(line, 1)==1 && size(point, 1)>1 line = repmat(line, [size(point, 1) 1]); end if size(point, 1)==1 && size(line, 1)>1 point = repmat(point, [size(line, 1) 1]); end # slope of line dx = line(:, 3); dy = line(:, 4); # first find relative position of projection on the line, tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy); # convert position on line to cartesian coordinate point = line(:,1:2) + [tp tp].*[dx dy]; endfunction geometry/inst/geom2d/drawEdge.m0000644000175000017500000001233212035504503016277 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawEdge (@var{x1}, @var{y1}, @var{x2}, @var{y2}) ## @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1} @var{x2} @var{y2}]) ## @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1}], [@var{x2} @var{y2}]) ## @deftypefnx {Function File} {@var{h} = } drawEdge (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2}) ## @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1} @var{z1} @var{x2} @var{y2} @var{z2}]) ## @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1} @var{z1}], [@var{x2} @var{y2} @var{z2}]) ## @deftypefnx {Function File} {@var{h} = } drawEdge (@dots{}, @var{opt}) ## Draw an edge given by 2 points. ## ## Draw an edge between the points (x1 y1) and (x2 y2). Data can be bundled as an edge. ## The function supports 3D edges. ## Arguments can be single values or array of size [Nx1]. In this case, ## the function draws multiple edges. ## @var{opt}, being a set of pairwise options, can ## specify color, line width and so on. These are passed to function @code{line}. ## The function returns handle(s) to created edges(s). ## ## @seealso{edges2d, drawCenteredEdge, drawLine, line} ## @end deftypefn function varargout = drawEdge(varargin) # separate edge and optional arguments [edge options] = parseInputArguments(varargin{:}); # draw the edges if size(edge, 2)==4 h = drawEdge_2d(edge, options); else h = drawEdge_3d(edge, options); end # eventually return handle to created edges if nargout>0 varargout{1}=h; end endfunction function h = drawEdge_2d(edge, options) h = -1*ones(size(edge, 1), 1); for i=1:size(edge, 1) if isnan(edge(i,1)) continue; end h(i) = line(... [edge(i, 1) edge(i, 3)], ... [edge(i, 2) edge(i, 4)], options{:}); end endfunction function h = drawEdge_3d(edge, options) h = -1*ones(size(edge, 1), 1); for i=1:size(edge, 1) if isnan(edge(i,1)) continue; end h(i) = line( ... [edge(i, 1) edge(i, 4)], ... [edge(i, 2) edge(i, 5)], ... [edge(i, 3) edge(i, 6)], options{:}); end endfunction function [edge options] = parseInputArguments(varargin) # default values for parameters edge = []; # find the number of arguments defining edges nbVal=0; for i=1:nargin if isnumeric(varargin{i}) nbVal = nbVal+1; else # stop at the first non-numeric value break; end end # extract drawing options options = varargin(nbVal+1:end); # ensure drawing options have correct format if length(options)==1 options = [{'color'}, options]; end # extract edges characteristics if nbVal==1 # all parameters in a single array edge = varargin{1}; elseif nbVal==2 # parameters are two points, or two arrays of points, of size N*2. p1 = varargin{1}; p2 = varargin{2}; edge = [p1 p2]; elseif nbVal==4 # parameters are 4 parameters of the edge : x1 y1 x2 and y2 edge = [varargin{1} varargin{2} varargin{3} varargin{4}]; elseif nbVal==6 # parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2 edge = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}]; end endfunction %!demo %! close %! points = rand(4,4); %! colorstr = 'rgbm'; %! for i=1:4 %! drawEdge (points(i,:),'color',colorstr(i),'linewidth',2); %! end %! axis tight; %!demo %! close %! drawEdge (rand(10,4),'linewidth',2); %! axis tight; geometry/inst/geom2d/deg2rad.m0000644000175000017500000000401412035504503016063 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{rad} =} deg2rad(@var{deg}) ## Convert angle from degrees to radians ## ## Usage: ## R = deg2rad(D) ## convert an angle in degrees to an angle in radians. ## ## Example ## deg2rad(180) # gives pi ## ans = ## 3.1416 ## deg2rad(60) # gives pi/3 ## ans = ## 1.0472 ## ## @seealso{angles2d, rad2deg} ## @end deftypefn function rad = deg2rad(deg) rad = deg*pi/180; endfunction geometry/inst/geom2d/rad2deg.m0000644000175000017500000000372612035504503016074 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{deg} =} rad2deg(@var{rad}) # Convert angle from radians to degrees # # Usage: # R = rad2deg(D) # convert an angle in radians to angle in degrees # # Example: # rad2deg(pi) # ans = # 180 # rad2deg(pi/3) # ans = # 60 ## ## @seealso{angles2d, deg2rad} ## @end deftypefn function deg = rad2deg(rad) deg = rad*180/pi; endfunction geometry/inst/geom2d/reverseLine.m0000644000175000017500000000400612035504503017037 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line} = } reverseLine (@var{line}) ## Return same line but with opposite orientation ## ## INVLINE = reverseLine(LINE); ## Returns the opposite line of LINE. ## LINE has the format [x0 y0 dx dy], then INVLINE will have following ## parameters: [x0 y0 -dx -dy]. ## ## @seealso{lines2d, createLine} ## @end deftypefn function line = reverseLine(line) line(:, 3:4) = -line(:, 3:4); endfunction geometry/inst/geom2d/cbezier2poly.m0000644000175000017500000001242712035504503017173 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pp} =} cbezier2poly (@var{points}) ## @deftypefnx {Function File} {[@var{x} @var{y}] =} cbezier2poly (@var{points},@var{t}) ## Returns the polynomial representation of the cubic Bezier defined by the control points @var{points}. ## ## With only one input argument, calculates the polynomial @var{pp} of the cubic ## Bezier curve defined by the 4 control points stored in @var{points}. The first ## point is the inital point of the curve. The segment joining the first point ## with the second point (first center) defines the tangent of the curve at the initial point. ## The segment that joints the third point (second center) with the fourth defines the tanget at ## the end-point of the curve, which is defined in the fourth point. ## @var{points} is either a 4-by-2 array (vertical concatenation of point ## coordinates), or a 1-by-8 array (horizotnal concatenation of point ## coordinates). @var{pp} is a 2-by-3 array, 1st row is the polynomial for the ## x-coordinate and the 2nd row for the y-coordinate. Each row can be evaluated ## with @code{polyval}. The polynomial @var{pp}(t) is defined for t in [0,1]. ## ## When called with a second input argument @var{t}, it returns the coordinates ## @var{x} and @var{y} corresponding to the polynomial evaluated at @var{t} in ## [0,1]. ## ## @seealso{drawBezierCurve, polyval} ## @end deftypefn function varargout = cbezier2poly (points, ti=[]) # rename points if size(points, 2)==2 # case of points given as a 4-by-2 array p1 = points(1,:); c1 = points(2,:); c2 = points(3,:); p2 = points(4,:); elseif size(points,2) == 8 # case of points given as a 1-by-8 array, [X1 Y1 CX1 CX2..] p1 = points(1:2); c1 = points(3:4); c2 = points(5:6); p2 = points(7:8); else print_usage ; end # compute coefficients of Bezier Polynomial pp = zeros(2,4); pp(:,4) = [p1(1); ... p1(2)]; pp(:,3) = [3 * c1(1) - 3 * p1(1); ... 3 * c1(2) - 3 * p1(2)]; pp(:,2) = [3 * p1(1) - 6 * c1(1) + 3 * c2(1); ... 3 * p1(2) - 6 * c1(2) + 3 * c2(2)]; pp(:,1) = [p2(1) - 3 * c2(1) + 3 * c1(1) - p1(1); ... p2(2) - 3 * c2(2) + 3 * c1(2) - p1(2)]; if isempty (ti) varargout{1} = pp; else varargout{1} = polyval (pp(1,:), ti); varargout{2} = polyval (pp(2,:), ti); end endfunction %!demo %! points = [45.714286 483.79075; ... %! 241.65656 110.40445; ... %! 80.185847 741.77381; ... %! 537.14286 480.93361]; %! %! pp = cbezier2poly(points); %! t = linspace(0,1,64); %! x = polyval(pp(1,:),t); %! y = polyval(pp(2,:),t); %! plot (x,y,'b-',points([1 4],1),points([1 4],2),'s',... %! points([2 3],1),points([2 3],2),'o'); %! line(points([2 1],1),points([2 1],2),'color','r'); %! line(points([3 4],1),points([3 4],2),'color','r'); %!demo %! points = [0 0; ... %! 1 1; ... %! 1 1; ... %! 2 0]; %! %! t = linspace(0,1,64); %! [x y] = cbezier2poly(points,t); %! plot (x,y,'b-',points([1 4],1),points([1 4],2),'s',... %! points([2 3],1),points([2 3],2),'o'); %! line(points([2 1],1),points([2 1],2),'color','r'); %! line(points([3 4],1),points([3 4],2),'color','r'); %!test %! points = [0 0; ... %! 1 1; ... %! 1 1; ... %! 2 0]; %! t = linspace(0,1,64); %! %! [x y] = cbezier2poly(points,t); %! pp = cbezier2poly(points); %! x2 = polyval(pp(1,:),t); %! y2 = polyval(pp(2,:),t); %! assert(x,x2); %! assert(y,y2); %!test %! points = [0 0; ... %! 1 1; ... %! 1 1; ... %! 2 0]; %! t = linspace(0,1,64); %! %! p = reshape(points,1,8); %! [x y] = cbezier2poly(p,t); %! pp = cbezier2poly(p); %! x2 = polyval(pp(1,:),t); %! y2 = polyval(pp(2,:),t); %! assert(x,x2); %! assert(y,y2); geometry/inst/geom2d/enclosingCircle.m0000644000175000017500000000664712035504503017674 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{circle} = } enclosingCircle (@var{pts}) ## Find the minimum circle enclosing a set of points. ## ## CIRCLE = enclosingCircle(POINTS); ## compute cirlce CIRCLE=[xc yc r] which enclose all points POINTS given ## as an [Nx2] array. ## ## ## Rewritten from a file from ## Yazan Ahed ## which was rewritten from a Java applet by Shripad Thite : ## @url{http://heyoka.cs.uiuc.edu/~thite/mincircle/} ## ## @seealso{circles2d, points2d, boxes2d} ## @end deftypefn function circle = enclosingCircle(pts) # works on convex hull : it is faster pts = pts(convhull(pts(:,1), pts(:,2)), :); circle = recurseCircle(size(pts, 1), pts, 1, zeros(3, 2)); endfunction function circ = recurseCircle(n, p, m, b) # n: number of points given # m: an argument used by the function. Always use 1 for m. # bnry: an argument (3x2 array) used by the function to set the points that # determines the circle boundry. You have to be careful when choosing this # array's values. I think the values should be somewhere outside your points # boundary. For my case, for example, I know the (x,y) I have will be something # in between (-5,-5) and (5,5), so I use bnry as: # [-10 -10 # -10 -10 # -10 -10] if m==4 circ = createCircle(b(1,:), b(2,:), b(3,:)); return; end circ = [Inf Inf 0]; if m == 2 circ = [b(1,1:2) 0]; elseif m == 3 c = (b(1,:) + b(2,:))/2; circ = [c distancePoints(b(1,:), c)]; end for i = 1:n if distancePoints(p(i,:), circ(1:2)) > circ(3) if sum(b(:,1)==p(i,1) & b(:,2)==p(i,2)) == 0 b(m,:) = p(i,:); circ = recurseCircle(i, p, m+1, b); end end end endfunction geometry/inst/geom2d/createRotation.m0000644000175000017500000000731212035504503017542 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } createRotation (@var{theta}) ## @deftypefnx {Function File} {@var{T} = } createRotation (@var{point}, @var{theta}) ## @deftypefnx {Function File} {@var{T} = } createRotation (@var{x0}, @var{y0}, @var{theta}) ## Create the 3*3 matrix of a rotation. ## ## Returns the rotation corresponding to angle @var{theta} (in radians) ## The returned matrix has the form : ## [cos(theta) -sin(theta) 0] ## [sin(theta) cos(theta) 0] ## [0 0 1] ## ## @var{point} or (@var{x0},@var{y0}), specifies origin of rotation. The result is similar as performing ## translation(-@var{x0},-@var{y0}), rotation(@var{theta}), and translation(@var{x0},@var{y0}). ## ## ## @seealso{transforms2d, transformPoint, createTranslation, createScaling} ## @end deftypefn function trans = createRotation(varargin) # default values cx = 0; cy = 0; theta = 0; # get input values if length(varargin)==1 # only angle theta = varargin{1}; elseif length(varargin)==2 # origin point (as array) and angle var = varargin{1}; cx = var(1); cy = var(2); theta = varargin{2}; elseif length(varargin)==3 # origin (x and y) and angle cx = varargin{1}; cy = varargin{2}; theta = varargin{3}; end # compute coefs cot = cos(theta); sit = sin(theta); tx = cy*sit - cx*cot + cx; ty = -cy*cot - cx*sit + cy; # create transformation matrix trans = [cot -sit tx; sit cot ty; 0 0 1]; endfunction %!test %! trans = createRotation(0); %! assert (trans, [1 0 0;0 1 0;0 0 1], 1e-6); %!test %! trans = createRotation(pi/2); %! assert (trans, [0 -1 0; 1 0 0; 0 0 1], 1e-6); %!test %! trans = createRotation(pi); %! assert (trans, [-1 0 0;0 -1 0;0 0 1], 1e-6); %!test %! trans = createRotation(3*pi/2); %! assert (trans, [0 1 0; -1 0 0; 0 0 1], 1e-6); %!test %! p0 = [3 5]; %! theta = pi/3; %! trans1 = createRotation(p0, theta); %! t1 = createTranslation(-p0); %! rot = createRotation(theta); %! t2 = createTranslation(p0); %! trans2 = t2*rot*t1; %! assert (trans1, trans2, 1e-6); geometry/inst/geom2d/points2d.m0000644000175000017500000000436412035504503016325 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} points2d () ## Description of functions operating on points. ## ## A point is defined by its two cartesian coordinate, put into a row ## vector of 2 elements: ## P = [x y]; ## ## Several points are stores in a matrix with two columns, one for the ## x-coordinate, one for the y-coordinate. ## PTS = [x1 y1 ; x2 y2 ; x3 y3]; ## ## Example ## P = [5 6]; ## ## @seealso{centroid, midPoint, polarPoint, pointOnLine ## isCounterClockwise, angle2Points, angle3Points, angleSort ## distancePoints, minDistancePoints ## transformPoint, clipPoints, drawPoint} ## @end deftypefn function points2d help('points2d'); endfunction geometry/inst/geom2d/transformVector.m0000644000175000017500000000741512035504503017761 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{v2} = } transformVector (@var{v}, @var{T}) ## @deftypefnx {Function File} {[@var{x2} @var{y2}] = } transformVector (@var{x},@var{y}, @var{T}) ## Transform a vector with an affine transform ## ## @var{v} has the form [xv yv], and @var{T} is a [2x2], [2x3] or [3x3] ## matrix, returns the vector transformed with affine transform @var{T}. ## ## Format of @var{T} can be one of : ## @group ## [a b] , [a b c] , or [a b c] ## [d e] [d e f] [d e f] ## [0 0 1] ## @end group ## ## Also works when @var{v} is a [Nx2] array of double. In this case, @var{v2} has ## the same size as @var{v}. ## ## Also works when @var{x} and @var{y} are arrays the same size. The function ## transform each couple of (@var{x}, @var{y}), and return the result in ## (@var{x2}, @var{y2}), which is the same size as (@var{x}, @var{y}). ## ## @seealso{vectors2d, transforms2d, rotateVector, transformPoint} ## @end deftypefn function varargout = transformVector(varargin) if length(varargin)==2 var = varargin{1}; vx = var(:,1); vy = var(:,2); trans = varargin{2}; elseif length(varargin)==3 vx = varargin{1}; vy = varargin{2}; trans = varargin{3}; else error('wrong number of arguments in "transformVector"'); end # compute new position of vector vx2 = vx*trans(1,1) + vy*trans(1,2); vy2 = vx*trans(2,1) + vy*trans(2,2); if size(trans, 2) == 3 vx2 = vx2 + trans(1,3); vy2 = vy2 + trans(2,3); end # format output if nargout==0 || nargout==1 varargout{1} = [vx2 vy2]; elseif nargout==2 varargout{1} = vx2; varargout{2} = vy2; end endfunction %!demo %! t1 = [2 0 0; 0 2 0]; %! t2 = [1 0 1; 0 1 1]; %! t3 = [0.5 0 1; 0 0.5 1; 0 0 1]; %! %! triangle = [-0.5 -1/3; 0.5 -1/3; 0 2/3; -0.5 -1/3]; %! tr1 = transformVector(triangle,t1); %! tr2 = transformVector(triangle,t2); %! tr3 = transformVector(triangle,t3); %! %! plot(triangle(:,1),triangle(:,2),'k-', ... %! tr1(:,1),tr1(:,2),'g-;scaled up;', ... %! tr2(:,1),tr2(:,2),'m-;translated;', ... %! tr3(:,1),tr3(:,2),'b-;scaled down and translated;') geometry/inst/geom2d/drawArrow.m0000644000175000017500000001225612035504503016532 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawArrow (@var{x1}, @var{y1}, @var{x2}, @var{y2}) ## @deftypefnx {Function File} {@var{h} = } drawArrow ([@var{ @var{x1}} @var{ @var{y1}} @var{x2} @var{y2}]) ## @deftypefnx {Function File} {@var{h} = } drawArrow (@dots{}, @var{L}, @var{W}) ## @deftypefnx {Function File} {@var{h} = } drawArrow (@dots{}, @var{L}, @var{W},@var{TYPE}) ## Draw an arrow on the current axis. ## ## draw an arrow between the points (@var{x1} @var{y1}) and (@var{x2} @var{y2}). ## The points can be given as a single array. @var{L}, @var{W} specify length ## and width of the arrow. ## ## Also specify arrow type. @var{TYPE} can be one of the following : ## 0: draw only two strokes ## 1: fill a triangle ## .5: draw a half arrow (try it to see ...) ## ## Arguments can be single values or array of size [N*1]. In this case, ## the function draws multiple arrows. ## ## @end deftypefn function varargout = drawArrow(varargin) if isempty(varargin) error('should specify at least one argument'); end # parse arrow coordinate if size(varargin{1}, 2)==4 x1 = varargin{1}(:,1); y1 = varargin{1}(:,2); x2 = varargin{1}(:,3); y2 = varargin{1}(:,4); varargin = varargin(2:end); elseif length(varargin)>3 x1 = varargin{1}; y1 = varargin{2}; x2 = varargin{3}; y2 = varargin{4}; varargin = varargin(5:end); else error('wrong number of arguments, please read the doc'); end l = 10*size(size(x1)); w = 5*ones(size(x1)); h = zeros(size(x1)); # exctract length of arrow if ~isempty(varargin) l = varargin{1}; if length(x1)>length(l) l = l(1)*ones(size(x1)); end end # extract width of arrow if length(varargin)>1 w = varargin{2}; if length(x1)>length(w) w = w(1)*ones(size(x1)); end end # extract 'ratio' of arrow if length(varargin)>2 h = varargin{3}; if length(x1)>length(h) h = h(1)*ones(size(x1)); end end hold on; axis equal; # angle of the edge theta = atan2(y2-y1, x2-x1); # point on the 'left' xa1 = x2 - l.*cos(theta) - w.*sin(theta)/2; ya1 = y2 - l.*sin(theta) + w.*cos(theta)/2; # point on the 'right' xa2 = x2 - l.*cos(theta) + w.*sin(theta)/2; ya2 = y2 - l.*sin(theta) - w.*cos(theta)/2; # point on the middle of the arrow xa3 = x2 - l.*cos(theta).*h; ya3 = y2 - l.*sin(theta).*h; # draw main edge tmp = line([x1'; x2'], [y1'; y2'], 'color', [0 0 1]); handle.body = tmp; # draw only 2 wings ind = find(h==0); if !isempty (ind) tmp = line([xa1(ind)'; x2(ind)'], [ya1(ind)'; y2(ind)'], 'color', [0 0 1]); handle.wing(:,1) = tmp; tmp = line([xa2(ind)'; x2(ind)'], [ya2(ind)'; y2(ind)'], 'color', [0 0 1]); handle.wing(:,2) = tmp; end # draw a full arrow ind = find(h~=0); if !isempty (ind) tmp = patch([x2(ind) xa1(ind) xa3(ind) xa2(ind) x2(ind)]', ... [y2(ind) ya1(ind) ya3(ind) ya2(ind) y2(ind)]', [0 0 1]); handle.head = tmp; end if nargout>0 varargout{1} = handle; end endfunction %!demo %! # Orthogonal projection respect to vector b %! dim = 2; %! b = 2*rand(dim,1); %! P = eye(dim) - (b*b')/(b'*b); %! v = 2*rand(dim,1)-1; %! Pv = P*v; %! %! # Draw the vectors %! clf; %! h = drawArrow ([zeros(3,dim) [b'; v'; Pv']],0.1,0.1); %! %! # Color them %! arrayfun(@(x,y)set(x,'color',y), [h.body; h.wing(:)],repmat(['rgb']',3,1)); %! # Name them %! legend (h.body, {'b','v','Pv'},'location','northoutside','orientation','horizontal'); geometry/inst/geom2d/createVector.m0000644000175000017500000000436712035504503017214 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{vect} = } createVector (@var{p1}, @var{p2}) ## Create a vector from two points. ## ## V12 = createVector(P1, P2) ## Creates the vector V12, defined as the difference between coordinates ## of points P1 and P2. ## P1 and P2 are row vectors with ND elements, ND being the space ## dimension. ## ## If one of the inputs is a N-by-Nd array, the other input is ## automatically repeated, and the result is N-by-Nd. ## ## If both inputs have the same size, the result also have the same size. ## ## @seealso{vectors2d, vectors3d, points2d} ## @end deftypefn function vect = createVector(p1, p2) vect = bsxfun(@minus, p2, p1); endfunction geometry/inst/geom2d/normalizeAngle.m0000644000175000017500000000664212035504503017533 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{alpha2} =} normalizeAngle (@var{alpha}) ## @deftypefnx {Function File} {@var{alpha2} =} normalizeAngle (@var{alpha}, @var{center}) ## Normalize an angle value within a 2*PI interval ## ## ALPHA2 = normalizeAngle(ALPHA); ## ALPHA2 is the same as ALPHA modulo 2*PI and is positive. ## ## ALPHA2 = normalizeAngle(ALPHA, CENTER); ## Specifies the center of the angle interval. ## If CENTER==0, the interval is [-pi ; +pi] ## If CENTER==PI, the interval is [0 ; 2*pi] (default). ## ## Example: ## # normalization between 0 and 2*pi (default) ## normalizeAngle(5*pi) ## ans = ## 3.1416 ## ## # normalization between -pi and +pi ## normalizeAngle(7*pi/2, 0) ## ans = ## -1.5708 ## ## References ## Follows the same convention as apache commons library, see: ## http://commons.apache.org/math/api-2.2/org/apache/commons/math/util/MathUtils.html## ## ## @seealso{vectorAngle, lineAngle} ## @end deftypefn function alpha = normalizeAngle(alpha, varargin) center = pi; if ~isempty(varargin) center = varargin{1}; end alpha = mod(alpha-center+pi, 2*pi) + center-pi; endfunction %!assert (pi/2, normalizeAngle (pi/2), 1e-6); %!assert (pi, normalizeAngle (pi), 1e-6); %!assert (3*pi/2, normalizeAngle (3*pi/2), 1e-6); %!assert (pi/2, normalizeAngle (pi/2, pi), 1e-6); %!assert (pi, normalizeAngle (pi, pi), 1e-6); %!assert (3*pi/2, normalizeAngle (3*pi/2, pi), 1e-6); %!test %! theta = linspace(0, 2*pi-.1, 100); %! assert(theta, normalizeAngle (theta), 1e-6); %!assert (0, normalizeAngle (0, 0), 1e-6); %!assert (pi/2, normalizeAngle (pi/2, 0), 1e-6); %!assert (-pi, normalizeAngle (-pi, 0), 1e-6); %!assert (-pi/2, normalizeAngle (7*pi/2, 0), 1e-6); %!test %! theta = linspace(-pi+.1, pi-.1, 100); %! assert(theta, normalizeAngle (theta, 0), 1e-6); geometry/inst/geom2d/distancePointLine.m0000644000175000017500000000550512035504503020175 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dist} = } distancePointLine (@var{point}, @var{line}) ## Minimum distance between a point and a line ## ## D = distancePointLine(POINT, LINE) ## Return the euclidean distance between line LINE and point POINT. ## ## LINE has the form : [x0 y0 dx dy], and POINT is [x y]. ## ## If LINE is N-by-4 array, result is N-by-1 array computes for each line. ## ## If POINT is N-by-2, then result is computed for each point. ## ## If both POINT and LINE are array, result is N-by-1, computed for each ## corresponding point and line. ## ## ## @seealso{lines2d, points2d, distancePoints, distancePointEdge} ## @end deftypefn function dist = distancePointLine(point, line) if size(line, 1)==1 && size(point, 1)>1 line = repmat(line, [size(point, 1) 1]); end if size(point, 1)==1 && size(line, 1)>1 point = repmat(point, [size(line, 1) 1]); end dx = line(:, 3); dy = line(:, 4); # compute position of points projected on line tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy); p0 = line(:, 1:2) + [tp tp].*[dx dy]; # compute distances between points and their projections dx = point - p0; dist = sqrt(sum(dx.*dx, 2)); endfunction geometry/inst/geom2d/edgeLength.m0000644000175000017500000000446112035504503016627 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{len} = } edgeLength (@var{edge}) ## Return length of an edge ## ## L = edgeLength(EDGE); ## Returns the length of an edge, with parametric representation: ## [x1 y1 x2 y2]. ## ## The function also works for several edges, in this case input is a ## [N*4] array, containing parametric representation of each edge, and ## output is a [N*1] array containing length of each edge. ## ## @seealso{edges2d, edgeAngle} ## @end deftypefn function len = edgeLength(varargin) # TODO : specify norm (euclidian, taxi, ...). nargs = length(varargin); if nargs == 1 edge = varargin{1}; len = sqrt(power(edge(:,3)-edge(:,1), 2) + power(edge(:,4)-edge(:,2), 2)); end endfunction geometry/inst/geom2d/isParallel.m0000644000175000017500000000644212035504503016652 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isParallel (@var{v1}, @var{v2}) ## @deftypefnx {Function File} {@var{b} = } isParallel (@var{v1}, @var{v2},@var{tol}) ## Check parallelism of two vectors ## ## @var{v1} and @var{v2} are 2 row vectors of length Nd, Nd being the dimension, ## returns @code{true} if the vectors are parallel, and @code{false} otherwise. ## ## Also works when @var{v1} and @var{v2} are two [NxNd] arrays with same number of ## rows. In this case, return a [Nx1] array containing @code{true} at the positions ## of parallel vectors. ## ## @var{tol} specifies the accuracy of numerical computation. Default value is 1e-14. ## ## Example ## ## @example ## isParallel([1 2], [2 4]) ## ans = ## 1 ## isParallel([1 2], [1 3]) ## ans = ## 0 ## @end example ## ## @seealso{vectors2d, isPerpendicular, lines2d} ## @end deftypefn ## FIXME or erase me ## Also works when one of @var{v1} or @var{v2} is scalar and the other one is [NxNd] ## array, in this case return [Nx1] results. function b = isParallel(v1, v2, varargin) # default accuracy acc = 1e-14; if ~isempty(varargin) acc = abs(varargin{1}); end # adapt size of inputs if needed n1 = size(v1, 1); n2 = size(v2, 1); if n1 ~= n2 if n1 == 1 v1 = v1(ones(n2,1), :); elseif n2 == 1 v2 = v2(ones(n1,1), :); end end # performs computation if size(v1, 2) == 2 b = abs(v1(:, 1) .* v2(:, 2) - v1(:, 2) .* v2(:, 1)) < acc; else # computation in space b = vectorNorm(cross(v1, v2, 2)) < acc; end endfunction %!assert (isParallel ([1 2], [2 4])) %!assert (!isParallel ([1 2], [1 3])) %!error (isParallel (3, rand(4,2))) geometry/inst/geom2d/squareGrid.m0000644000175000017500000000553612035504503016673 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pts} = } squaregrid (@var{bounds}, @var{origin}, @var{size}) ## Generate equally spaces points in plane. ## ## usage ## PTS = squareGrid(BOUNDS, ORIGIN, SIZE) ## generate points, lying in the window defined by BOUNDS (=[xmin ymin ## xmax ymax]), starting from origin with a constant step equal to size. ## ## Example ## PTS = squareGrid([0 0 10 10], [3 3], [4 2]) ## will return points : ## [3 1;7 1;3 3;7 3;3 5;7 5;3 7;7 7;3 9;7 9]; ## ## TODO: add possibility to use rotated grid ## ## @end deftypefn function varargout = squareGrid(bounds, origin, size) # find all x coordinate x1 = bounds(1) + mod(origin(1)-bounds(1), size(1)); x2 = bounds(3) - mod(bounds(3)-origin(1), size(1)); lx = (x1:size(1):x2)'; # find all y coordinate y1 = bounds(2) + mod(origin(2)-bounds(2), size(2)); y2 = bounds(4) - mod(bounds(4)-origin(2), size(2)); ly = (y1:size(2):y2)'; # number of points in each coord, and total number of points ny = length(ly); nx = length(lx); np = nx*ny; # create points pts = zeros(np, 2); for i=1:ny pts( (1:nx)'+(i-1)*nx, 1) = lx; pts( (1:nx)'+(i-1)*nx, 2) = ly(i); end # process output if nargout>0 varargout{1} = pts; end endfunction geometry/inst/geom2d/angle3Points.m0000644000175000017500000000560312035504503017126 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{alpha} =} angle3Points (@var{p1}, @var{p2}, @var{p3}) ## Computes the angle between the points @var{p1}, @var{p2} and @var{p3}. ## ## @var{p1}, @var{p2} and @var{p3} are either [1x2] arrays, or [Nx2] arrays, in this case ## @var{alpha} is a [Nx1] array. The angle computed is the directed angle between line ## (@var{p2}@var{p1}) and line (@var{p2}@var{p3}). ## ## Result is always given in radians, between 0 and 2*pi. ## ## @seealso{points2d, angles2d, angle2points} ## @end deftypefn function theta = angle3Points(varargin) if length(varargin)==3 p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; elseif length(varargin)==1 var = varargin{1}; p1 = var(1,:); p2 = var(2,:); p3 = var(3,:); end # angle line (P2 P1) theta = lineAngle(createLine(p2, p1), createLine(p2, p3)); endfunction %!test %! # all points inside window, possibly touching edges %! p1 = [10 0]; %! p2 = [0 0]; %! p3 = [0 10]; %! angle_ = angle3Points(p1, p2, p3); %! assert(pi/2, angle_,1e-6); %! angle_ = angle3Points([p1; p2; p3]); %! assert(pi/2, angle_, 1e-6); %!test %! p1 = [10 0; 20 0]; %! p2 = [0 0;0 0]; %! p3 = [0 10; 0 20]; %! angle_ = angle3Points(p1, p2, p3); %! assert(2, size(angle_, 1)); %! assert([pi/2;pi/2], angle_, 1e-6); geometry/inst/geom2d/readme.txt0000644000175000017500000000647011650352340016405 0ustar juanpijuanpi%% Copyright (c) 2011, INRA %% 2007-2011, David Legland %% 2011 Adapted to Octave by Juan Pablo Carbajal %% %% All rights reserved. %% (simplified BSD License) %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions are met: %% %% 1. Redistributions of source code must retain the above copyright notice, this %% list of conditions and the following disclaimer. %% %% 2. 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. %% %% 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. %% %% The views and conclusions contained in the software and documentation are %% those of the authors and should not be interpreted as representing official %% policies, either expressed or implied, of copyright holder. Description of the geom2d library. The aim of geom2d library is to handle and visualize geometric primitives such as points, lines, circles and ellipses, polylines and polygons... It provides low-level functions for manipulating geometrical primitives, making easier the development of more complex geometric algorithms. Some features of the library are: - creation of various shapes (points, circles, lines, ellipses, polylines, polygons...) through an intuitive syntax. Ex: createCircle(p1, p2, p3) to create a circle through 3 points. - derivation of new shapes: intersection between 2 lines, between line and circle, between polylines... or point on a curve from its parametrisation - functions for polylines and polygons: compute centroid and area, expand, self-intersections, clipping with half-plane... - manipulation of planar transformation. Ex.: ROT = createRotation(CENTER, THETA); P2 = transformPoint(P1, ROT); - direct drawing of shapes with specialized functions. Clipping is performed automatically for infinite shapes such as lines or rays. Ex: drawCircle([50 50 25]); % draw circle with radius 25 and center [50 50] drawLine([X0 Y0 DX DY]); % clip and draw straight line - measure distances (between points, a point and a line, a point and a group of points), angle (of a line, between 3 points), or test geometry (point on a line, on a circle). Additional help is provided in geom/Contents.m file, as well as summary files like 'points2d.m' or 'lines2d.m'. geometry/inst/geom2d/boxes2d.m0000644000175000017500000000412112035504503016120 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} boxes2d () ## Description of functions operating on bounding boxes. ## ## A box is represented as a set of limits in each direction: ## @example ## BOX = [XMIN XMAX YMIN YMAX]. ## @end example ## @noindent ## Boxes are used as result of computation for bounding boxes, and to clip ## shapes. ## ## @seealso{clipPoints, clipLine, clipEdge, clipRay, mergeBoxes, ## intersectBoxes, randomPointInBox, drawBox} ## @end deftypefn function boxes2d(varargin) help('boxes2d'); endfunction geometry/inst/geom2d/isPointInCircle.m0000644000175000017500000000471112035504503017615 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPointInCircle (@var{point}, @var{circle}) ## Test if a point is located inside a given circle ## ## B = isPointInCircle(POINT, CIRCLE) ## Returns true if point is located inside the circle, i.e. if distance to ## circle center is lower than the circle radius. ## ## B = isPointInCircle(POINT, CIRCLE, TOL) ## Specifies the tolerance value ## ## Example: ## isPointInCircle([1 0], [0 0 1]) ## isPointInCircle([0 0], [0 0 1]) ## returns true, whereas ## isPointInCircle([1 1], [0 0 1]) ## return false ## ## @seealso{circles2d, isPointOnCircle} ## @end deftypefn function b = isPointInCircle(point, circle, varargin) # extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); b = d-circle(:,3)<=tol; endfunction geometry/inst/geom2d/vectors2d.m0000644000175000017500000000423012035504503016466 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} vectors2d () ## Description of functions operating on plane vectors ## ## A vector is defined by its two cartesian coordinates, put into a row ## vector of 2 elements: ## @code{V = [vx vy];} ## ## Several vectors are stored in a matrix with two columns, one for the ## x-coordinate, one for the y-coordinate. ## @code{VS = [vx1 vy1 ; vx2 vy2 ; vx3 vy3];} ## ## @seealso{vectorNorm, vectorAngle, isPerpendicular, isParallel, ## normalizeVector, transformVector, rotateVector} ## @end deftypefn function vectors2d help('vectors2d'); endfunction geometry/inst/geom2d/medianLine.m0000644000175000017500000001120612035504503016621 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line} = } medianLine (@var{p1}, @var{p2}) ## @deftypefnx {Function File} {@var{line} = } medianLine (@var{pts}) ## @deftypefnx {Function File} {@var{line} = } medianLine (@var{edge}) ## Create a median line between two points. ## ## Create the median line of points @var{p1} and @var{p2}, that is the line containing ## all points located at equal distance of @var{p1} and @var{p2}. ## ## Creates the median line of 2 points, given as a 2*2 array @var{pts}. Array has ## the form: ## [ [ x1 y1 ] ; [ x2 y2 ] ] ## ## Creates the median of the @var{edge}. @var{edge} is a 1*4 array, containing [X1 Y1] ## coordinates of first point, and [X2 Y2], the coordinates of the second ## point. ## ## Example ## ## @example ## # Draw the median line of two points ## P1 = [10 20]; ## P2 = [30 50]; ## med = medianLine(P1, P2); ## figure; axis square; axis([0 100 0 100]); ## drawEdge([P1 P2], 'linewidth', 2, 'color', 'k'); ## drawLine(med) ## ## # Draw the median line of an edge ## P1 = [50 60]; ## P2 = [80 30]; ## edge = createEdge(P1, P2); ## figure; axis square; axis([0 100 0 100]); ## drawEdge(edge, 'linewidth', 2) ## med = medianLine(edge); ## drawLine(med) ## @end example ## ## @seealso{lines2d, createLine, orthogonalLine} ## @end deftypefn function lin = medianLine(varargin) nargs = length(varargin); x0 = 0; y0 = 0; dx = 0; dy = 0; if nargs == 1 tab = varargin{1}; if size(tab, 2)==2 # input is an array of two points x0 = tab(1,1); y0 = tab(1,2); dx = tab(2,1)-x0; dy = tab(2,2)-y0; else # input is an edge x0 = tab(:, 1); y0 = tab(:, 2); dx = tab(:, 3) - tab(:, 1); dy = tab(:, 4) - tab(:, 2); end elseif nargs==2 # input is given as two points, or two point arrays p1 = varargin{1}; p2 = varargin{2}; x0 = p1(:, 1); y0 = p1(:, 2); dx = bsxfun(@minus, p2(:, 1), x0); dy = bsxfun(@minus, p2(:, 2), y0); else error('Too many input arguments'); end # compute median using middle point of the edge, and the direction vector # rotated by 90 degrees counter-clockwise lin = [bsxfun(@plus, x0, dx/2), bsxfun(@plus, y0, dy/2), -dy, dx]; endfunction %!shared privpath %! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private']; %!test %! addpath (privpath,'-end') %! p1 = [0 0]; %! p2 = [10 0]; %! exp = [5 0 0 10]; %! lin = medianLine(p1, p2); %! assertElementsAlmostEqual(exp, lin); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! p1 = [0 0]; %! p2 = [10 0]; %! exp = [5 0 0 10]; %! lin = medianLine([p1 p2]); %! assertElementsAlmostEqual(exp, lin); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! p1 = [0 0; 10 10]; %! p2 = [10 0;10 20]; %! exp = [5 0 0 10; 10 15 -10 0]; %! lin = medianLine(p1, p2); %! assertElementsAlmostEqual(exp, lin); %! rmpath (privpath); geometry/inst/geom2d/midPoint.m0000644000175000017500000001126012035504503016337 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{mid} = } midPoint (@var{p1}, @var{p2}) ## @deftypefnx {Function File} {@var{mid} = } midPoint (@var{edge}) ## @deftypefnx {Function File} {[@var{midx}, @var{midy}] = } midPoint (@var{edge}) ## Middle point of two points or of an edge ## ## Computes the middle point of the two points @var{p1} and @var{p2}. ## ## If an edge is given, computes the middle point of the edge given by @var{edge}. ## @var{edge} has the format: [X1 Y1 X2 Y2], and @var{mid} has the format [XMID YMID], ## with XMID = (X1+X2)/2, and YMID = (Y1+Y2)/2. ## ## If two output arguments are given, it returns the result as two separate variables or arrays. ## ## Works also when @var{edge} is a N-by-4 array, in this case the result is a ## N-by-2 array containing the midpoint of each edge. ## ## Example ## ## @example ## p1 = [10 20]; ## p2 = [30 40]; ## midPoint([p1 p2]) ## ans = ## 20 30 ## @end example ## ## @seealso{edges2d, points2d} ## @end deftypefn function varargout = midPoint(varargin) if nargin == 1 # input is an edge edge = varargin{1}; mid = [mean(edge(:, [1 3]), 2) mean(edge(:, [2 4]), 2)]; elseif nargin == 2 # input are two points p1 = varargin{1}; p2 = varargin{2}; # assert inputs are equal n1 = size(p1, 1); n2 = size(p2, 1); if n1 != n2 && min(n1, n2)>1 error('geom2d:midPoint', ... 'Inputs must have same size, or one must have length 1'); end # compute middle point mid = bsxfun(@plus, p1, p2) / 2; end # process output arguments if nargout<=1 varargout{1} = mid; else varargout = {mid(:,1), mid(:,2)}; end endfunction %!test %! p1 = [10 20]; %! p2 = [30 40]; %! exp = [20 30]; %! mid = midPoint(p1, p2); %! assert (mid, exp); %!test %! p1 = [ ... %! 10 20 ; ... %! 30 40 ; ... %! 50 60 ; ... %! ]; %! p2 = [ ... %! 30 40; ... %! 50 60; ... %! 70 80]; %! exp = [... %! 20 30; ... %! 40 50; ... %! 60 70]; %! mid = midPoint(p1, p2); %! assert (mid, exp); %!test %! p1 = [30 40]; %! p2 = [ ... %! 30 40; ... %! 50 60; ... %! 70 80]; %! exp = [... %! 30 40; ... %! 40 50; ... %! 50 60]; %! mid = midPoint(p1, p2); %! assert (mid, exp); %!test %! p1 = [ ... %! 10 20 ; ... %! 30 40 ; ... %! 50 60 ; ... %! ]; %! p2 = [30 40]; %! exp = [... %! 20 30; ... %! 30 40; ... %! 40 50]; %! mid = midPoint(p1, p2); %! assert (mid, exp); %!test %! p1 = [ ... %! 10 20 ; ... %! 30 40 ; ... %! 50 60 ; ... %! ]; %! p2 = [30 40]; %! expX = [20 ; 30 ; 40]; %! expY = [30 ; 40 ; 50]; %! [x y] = midPoint(p1, p2); %! assert (x, expX); %! assert (y, expY); %!test %! edge = [10 20 30 40]; %! exp = [20 30]; %! mid = midPoint(edge); %! assert (mid, exp); %! edge = [10 20 30 40; 30 40 50 60; 50 60 70 80]; %! exp = [20 30;40 50; 60 70]; %! mid = midPoint(edge); %! assert (mid, exp); geometry/inst/geom2d/intersectBoxes.m0000644000175000017500000000513412035504503017560 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{box} =} intersectBoxes (@var{box1}, @var{box2}) ## Intersection of two bounding boxes. ## ## Example ## ## @example ## box1 = [5 20 5 30]; ## box2 = [0 15 0 15]; ## intersectBoxes(box1, box2) ## ans = ## 5 15 5 15 ## @end example ## ## @seealso{boxes2d, drawBox, mergeBoxes} ## @end deftypefn function bb = intersectBoxes(box1, box2) # unify sizes of data if size(box1,1) == 1 box1 = repmat(box1, size(box2,1), 1); elseif size(box2, 1) == 1 box2 = repmat(box2, size(box1,1), 1); elseif size(box1,1) != size(box2,1) error('geom2d:Error',"Bad size for inputs.\n"); end # compute extreme coords mini = min(box1(:,[2 4]), box2(:,[2 4])); maxi = max(box1(:,[1 3]), box2(:,[1 3])); # concatenate result into a new box structure bb = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2)]; endfunction %!test %! box1 = [5 20 10 25]; %! box2 = [0 15 15 20]; %! res = [5 15 15 20]; %! bb = intersectBoxes(box1, box2); %! assert (res, bb, 1e-6); geometry/inst/geom2d/centroid.m0000644000175000017500000001024112035504503016361 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{c} = } centroid (@var{points}) ## @deftypefnx {Function File} {@var{c} = } centroid (@var{px}, @var{py}) ## @deftypefnx {Function File} {@var{c} = } centroid (@dots{}, @var{mass}) ## Compute centroid (center of mass) of a set of points. ## ## Computes the ND-dimensional centroid of a set of points. ## @var{points} is an array with as many rows as the number of points, and as ## many columns as the number of dimensions. ## @var{px} and @var{py} are two column vectors containing coordinates of the ## 2-dimensional points. ## The result @var{c} is a row vector with ND columns. ## ## If @var{mass} is given, computes center of mass of @var{points}, weighted by coefficient @var{mass}. ## @var{points} is a Np-by-Nd array, @var{mass} is Np-by-1 array, and @var{px} and @var{py} are ## also both Np-by-1 arrays. ## ## Example: ## ## @example ## pts = [2 2;6 1;6 5;2 4]; ## centroid(pts) ## ans = ## 4 3 ##@end example ## ## @seealso{points2d, polygonCentroid} ## @end deftypefn function center = centroid(varargin) ## extract input arguments # use empty mass by default mass = []; if nargin==1 # give only array of points pts = varargin{1}; elseif nargin==2 # either POINTS+MASS or PX+PY var = varargin{1}; if size(var, 2)>1 # arguments are POINTS, and MASS pts = var; mass = varargin{2}; else # arguments are PX and PY pts = [var varargin{2}]; end elseif nargin==3 # arguments are PX, PY, and MASS pts = [varargin{1} varargin{2}]; mass = varargin{3}; end ## compute centroid if isempty(mass) # no weight center = mean(pts); else # format mass to have sum equal to 1, and column format mass = mass(:)/sum(mass(:)); # compute weighted centroid center = sum(bsxfun(@times, pts, mass), 1); # equivalent to: # center = sum(pts .* mass(:, ones(1, size(pts, 2)))); end endfunction %!test %! points = [0 0;10 0;10 10;0 10]; %! centro = centroid(points); %! assert ([5 5], centro, 1e-6); %!test %! points = [0 0;10 0;10 10;0 10]; %! centro = centroid(points(:,1), points(:,2)); %! assert ([5 5], centro, 1e-6); %!test %! points = [0 0;30 0;30 30;0 30]; %! centro = centroid(points, [1;1;1;3]); %! assert ([10 20], centro, 1e-6); %!test %! points = [0 0;30 0;30 30;0 30]; %! centro = centroid(points(:,1), points(:,2), [1;1;1;3]); %! assert ([10 20], centro, 1e-6); geometry/inst/geom2d/createLineReflection.m0000644000175000017500000000475412035504503020654 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } function_name (@var{line}) ## Create the the 3x3 matrix of a line reflection. ## ## Where @var{line} is given as [x0 y0 dx dy], return the affine tansform ## corresponding to the desired line reflection. ## ## @seealso{lines2d, transforms2d, transformPoint, ## createTranslation, createHomothecy, createScaling} ## @end deftypefn function trans = createLineReflection(line) # extract line parameters x0 = line(:,1); y0 = line(:,2); dx = line(:,3); dy = line(:,4); # normalisation coefficient of line direction vector delta = dx*dx + dy*dy; # compute coefficients of transform m00 = (dx*dx - dy*dy)/delta; m01 = 2*dx*dy/delta; m02 = 2*dy*(dy*x0 - dx*y0)/delta; m10 = 2*dx*dy/delta; m11 = (dy*dy - dx*dx)/delta; m12 = 2*dx*(dx*y0 - dy*x0)/delta; # create transformation trans = [m00 m01 m02; m10 m11 m12; 0 0 1]; endfunction geometry/inst/geom2d/isPerpendicular.m0000644000175000017500000000642212035504503017711 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPerpendicular (@var{v1}, @var{v2}) ## @deftypefnx {Function File} {@var{b} = } isPerpendicula (@var{v1}, @var{v2},@var{tol}) ## heck orthogonality of two vectors. ## ## @var{v1} and @var{v2} are 2 row vectors of length Nd, Nd being the dimension, ## returns @code{true} if the vectors are perpendicular, and @code{false} otherwise. ## ## Also works when @var{v1} and @var{v2} are two [NxNd] arrays with same number of ## rows. In this case, return a [Nx1] array containing @code{true} at the positions ## of parallel vectors. ## ## @var{tol} specifies the accuracy of numerical computation. Default value is 1e-14. ## ## Example ## ## @example # isPerpendicular([1 2 0], [0 0 2]) ## ans = ## 1 # isPerpendicular([1 2 1], [1 3 2]) ## ans = ## 0 ## @end example ## ## @seealso{vectors2d, isParallel, lines2d} ## @end deftypefn ## FIXME or erase me ## Also works when one of @var{v1} or @var{v2} is scalar and the other one is [NxNd] ## array, in this case return [Nx1] results. function b = isPerpendicular(v1, v2, varargin) # default accuracy acc = 1e-14; if ~isempty (varargin) acc = abs (varargin{1}); end # adapt size of inputs n1 = size (v1, 1); n2 = size (v2, 1); if n1~=n2 if n1==1 v1 = v1(ones (n2, 1), :); elseif n2==1 v2 = v2(ones (n1, 1), :); else error('Inputs must either have same size, or one must be scalar'); end end # performs test b = abs (dot (v1, v2, 2)) < acc; endfunction %!assert (isPerpendicular ([1 2 0], [0 0 2])) %!assert (!isPerpendicular([1 2 1], [1 3 2])) %!error (isPerpendicular(1, rand(4,3))) geometry/inst/geom2d/clipRay.m0000644000175000017500000001346412035504503016167 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{edge} @var{inside}] =} clipRay (@var{ray}, @var{box}) ## Clip a ray with a box. ## ## @var{ray} is a straight ray given as a 4 element row vector: [x0 y0 dx dy], ## with (x0 y0) being the origin of the ray and (dx dy) its direction ## vector, @var{box} is the clipping box, given by its extreme coordinates: ## [xmin xmax ymin ymax]. ## The result is given as an edge, defined by the coordinates of its 2 ## extreme points: [x1 y1 x2 y2]. ## If the ray does not intersect the box, [NaN NaN NaN NaN] is returned. ## ## Function works also if @var{ray} is a Nx4 array, if @var{box} is a Nx4 array, or ## if both @var{ray} and @var{box} are Nx4 arrays. In these cases, @var{edge} is a Nx4 ## array. ## ## @seealso{rays2d, boxes2d, edges2d, clipLine, drawRay} ## @end deftypefn function [edge isInside] = clipRay(ray, bb) # adjust size of two input arguments if size(ray, 1)==1 ray = repmat(ray, size(bb, 1), 1); elseif size(bb, 1)==1 bb = repmat(bb, size(ray, 1), 1); elseif size(ray, 1) != size(bb, 1) error('bad sizes for input'); end # first compute clipping of supporting line edge = clipLine(ray, bb); # detectes valid edges (edges outside box are all NaN) inds = find(isfinite(edge(:, 1))); # compute position of edge extremities relative to the ray pos1 = linePosition(edge(inds,1:2), ray(inds,:)); pos2 = linePosition(edge(inds,3:4), ray(inds,:)); # if first point is before ray origin, replace by origin edge(inds(pos1<0), 1:2) = ray(inds(pos1<0), 1:2); # if last point of edge is before origin, set all edge to NaN edge(inds(pos2<0), :) = NaN; # eventually returns result about inside or outside if nargout>1 isInside = isfinite(edge(:,1)); end endfunction %!shared bb %! bb = [0 100 0 100]; %!test # inside %! origin = [30 40]; %! direction = [10 0]; %! ray = [origin direction]; %! expected = [30 40 100 40]; %! assert (expected, clipRay(ray, bb), 1e-6); %!test # outside %! origin = [30 140]; %! direction = [10 0]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # line inside, but ray outside %! origin = [130 40]; %! direction = [10 0]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # inside %! origin = [30 40]; %! direction = [-10 0]; %! ray = [origin direction]; %! expected = [30 40 0 40]; %! assert (expected, clipRay(ray, bb), 1e-6); %!test # outside %! origin = [30 140]; %! direction = [-10 0]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # line inside, but ray outside %! origin = [-30 40]; %! direction = [-10 0]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # inside %! origin = [30 40]; %! direction = [0 10]; %! ray = [origin direction]; %! expected = [30 40 30 100]; %! assert (expected, clipRay(ray, bb), 1e-6); %!test # outside %! origin = [130 40]; %! direction = [0 10]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # line inside, but ray outside %! origin = [30 140]; %! direction = [0 10]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # inside %! origin = [30 40]; %! direction = [0 -10]; %! ray = [origin direction]; %! expected = [30 40 30 0]; %! assert (expected, clipRay(ray, bb), 1e-6); %!test # outside %! origin = [130 40]; %! direction = [0 -10]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test # line inside, but ray outside %! origin = [30 -40]; %! direction = [0 -10]; %! ray = [origin direction]; %! assert (sum(isnan(clipRay(ray, bb)))==4); %!test %! origins = [30 40;30 40;30 140;130 40]; %! directions = [10 0;0 10;10 0;0 10]; %! rays = [origins directions]; %! expected = [30 40 100 40;30 40 30 100;NaN NaN NaN NaN;NaN NaN NaN NaN]; %! clipped = clipRay(rays, bb); %! assert (expected, clipped, 1e-6); geometry/inst/geom2d/clipEdge.m0000644000175000017500000001731112035504503016273 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{edge2} =} clipEdge (@var{edge}, @var{box}) ## Clip an edge with a rectangular box. ## ## @var{edge}: [x1 y1 x2 y2], ## @var{box} : [xmin xmax ; ymin ymax] or [xmin xmax ymin ymax]; ## return : ## @var{edge2} = [xc1 yc1 xc2 yc2]; ## ## If clipping is null, return [0 0 0 0]; ## ## if @var{edge} is a [nx4] array, return an [nx4] array, corresponding to each ## clipped edge. ## ## @seealso{edges2d, boxes2d, clipLine} ## @end deftypefn function edge2 = clipEdge(edge, bb) # process data input if size(bb, 1)==2 bb = bb'; end # get limits of window xmin = bb(1); xmax = bb(2); ymin = bb(3); ymax = bb(4); # convert window limits into lines lineX0 = [xmin ymin xmax-xmin 0]; lineX1 = [xmin ymax xmax-xmin 0]; lineY0 = [xmin ymin 0 ymax-ymin]; lineY1 = [xmax ymin 0 ymax-ymin]; # compute outcodes of each vertex p11 = edge(:,1)xmax; p22 = edge(:,3)>xmax; p13 = edge(:,2)ymax; p24 = edge(:,4)>ymax; out1 = [p11 p12 p13 p14]; out2 = [p21 p22 p23 p24]; # detect edges totally inside window -> no clip. inside = sum(out1 | out2, 2)==0; # detect edges totally outside window outside = sum(out1 & out2, 2)>0; # select edges not totally outside, and process separately edges totally # inside window ind = find(~(inside | outside)); edge2 = zeros(size(edge)); edge2(inside, :) = edge(inside, :); for i=1:length(ind) # current edge iedge = edge(ind(i), :); # compute intersection points with each line of bounding window px0 = intersectLineEdge(lineX0, iedge); px1 = intersectLineEdge(lineX1, iedge); py0 = intersectLineEdge(lineY0, iedge); py1 = intersectLineEdge(lineY1, iedge); # create array of points points = [px0; px1; py0; py1; iedge(1:2); iedge(3:4)]; # remove infinite points (edges parallel to box edges) points = points(all(isfinite(points), 2), :); # sort points by x then y points = sortrows(points); # get center positions between consecutive points centers = (points(2:end,:) + points(1:end-1,:))/2; # find the centers (if any) inside window inside = find( centers(:,1)>=xmin & centers(:,2)>=ymin & ... centers(:,1)<=xmax & centers(:,2)<=ymax); # if multiple segments are inside box, which can happen due to finite # resolution, only take the longest segment if length(inside)>1 # compute delta vectors of the segments dv = points(inside+1,:) - points(inside,:); # compute lengths of segments len = hypot(dv(:,1), dv(:,2)); # find index of longest segment [a, I] = max(len); ##ok inside = inside(I); end # if one of the center points is inside box, then the according edge # segment is indide box if length(inside)==1 # restore same direction of edge if iedge(1)>iedge(3) || (iedge(1)==iedge(3) && iedge(2)>iedge(4)) edge2(i, :) = [points(inside+1,:) points(inside,:)]; else edge2(i, :) = [points(inside,:) points(inside+1,:)]; end end end # end of loop of edges endfunction %!demo %! bb = [0 100 0 100]; %! edge = [-10 10 90 110]; %! ec = clipEdge (edge, bb); %! %! drawBox(bb,'color','k'); %! line(edge([1 3]),edge([2 4]),'color','b'); %! line(ec([1 3]),ec([2 4]),'color','r','linewidth',2); %! axis tight %! v = axis (); %! axis(v+[0 10 -10 0]) %!shared bb %! bb = [0 100 0 100]; %!assert (clipEdge([20 30 80 60], bb), [20 30 80 60],1e-6); %!assert (clipEdge([0 30 80 60], bb), [0 30 80 60],1e-6); %!assert (clipEdge([0 30 100 60], bb), [0 30 100 60],1e-6); %!assert (clipEdge([30 0 80 100], bb), [30 0 80 100],1e-6); %!assert (clipEdge([0 0 100 100], bb), [0 0 100 100],1e-6); %!assert (clipEdge([0 100 100 0], bb), [0 100 100 0],1e-6); %!assert (clipEdge([20 60 120 60], bb), [20 60 100 60],1e-6); %!assert (clipEdge([-20 60 80 60], bb), [0 60 80 60],1e-6); %!assert (clipEdge([20 60 20 160], bb), [20 60 20 100],1e-6); %!assert (clipEdge([20 -30 20 60], bb), [20 0 20 60],1e-6); %!assert (clipEdge([120 30 180 60], bb), [0 0 0 0],1e-6); %!assert (clipEdge([-20 30 -80 60], bb), [0 0 0 0],1e-6); %!assert (clipEdge([30 120 60 180], bb), [0 0 0 0],1e-6); %!assert (clipEdge([30 -20 60 -80], bb), [0 0 0 0],1e-6); %!assert (clipEdge([-120 110 190 150], bb), [0 0 0 0],1e-6); %!assert ([50 50 100 50], clipEdge([50 50 150 50], bb),1e-6); %!assert ([50 50 0 50], clipEdge([50 50 -50 50], bb),1e-6); %!assert ([50 50 50 100], clipEdge([50 50 50 150], bb),1e-6); %!assert ([50 50 50 0], clipEdge([50 50 50 -50], bb),1e-6); %!assert ([80 50 100 70], clipEdge([80 50 130 100], bb),1e-6); %!assert ([80 50 100 30], clipEdge([80 50 130 0], bb),1e-6); %!assert ([20 50 0 70], clipEdge([20 50 -30 100], bb),1e-6); %!assert ([20 50 0 30], clipEdge([20 50 -30 0], bb),1e-6); %!assert ([50 80 70 100], clipEdge([50 80 100 130], bb),1e-6); %!assert ([50 80 30 100], clipEdge([50 80 0 130], bb),1e-6); %!assert ([50 20 70 0], clipEdge([50 20 100 -30], bb),1e-6); %!assert ([50 20 30 0], clipEdge([50 20 0 -30], bb),1e-6); %!assert ([100 50 50 50], clipEdge([150 50 50 50], bb),1e-6); %!assert ([0 50 50 50], clipEdge([-50 50 50 50], bb),1e-6); %!assert ([50 100 50 50], clipEdge([50 150 50 50], bb),1e-6); %!assert ([50 0 50 50], clipEdge([50 -50 50 50], bb),1e-6); %!assert ([100 70 80 50], clipEdge([130 100 80 50], bb),1e-6); %!assert ([100 30 80 50], clipEdge([130 0 80 50], bb),1e-6); %!assert ([0 70 20 50], clipEdge([-30 100 20 50], bb),1e-6); %!assert ([0 30 20 50], clipEdge([-30 0 20 50], bb),1e-6); %!assert ([70 100 50 80], clipEdge([100 130 50 80], bb),1e-6); %!assert ([30 100 50 80], clipEdge([0 130 50 80], bb),1e-6); %!assert ([70 0 50 20], clipEdge([100 -30 50 20], bb),1e-6); %!assert ([30 0 50 20], clipEdge([0 -30 50 20], bb),1e-6); %!assert ([0 20 80 100], clipEdge([-10 10 90 110], bb),1e-6); geometry/inst/geom2d/rays2d.m0000644000175000017500000000460212035504503015762 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} rays2d () ## Description of functions operating on planar rays ## ## A ray is defined by a point (its origin), and a vector (its ## direction). The different parameters are bundled into a row vector: ## @code{RAY = [x0 y0 dx dy];} ## ## The ray contains all the points (x,y) such that: ## x = x0 + t*dx ## y = y0 + t*dy; ## for all t>0 ## ## Contrary to a (straight) line, the points located before the origin do ## not belong to the ray. ## However, as rays and lines have the same representation, some functions ## working on lines are also working on rays (like @code{transformLine}). ## ## @seealso{points2d, vectors2d, lines2d, createRay, bisector, isPointOnRay, ## clipRay, drawRay} ## @end deftypefn function rays2d(varargin) help('rays2d'); endfunction geometry/inst/geom2d/drawEllipseArc.m0000644000175000017500000001167412035504503017466 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawEllipseArc (@var{arc}) ## Draw an ellipse arc on the current axis. ## ## drawEllipseArc(ARC) ## draw ellipse arc specified by ARC. ARC has the format: ## ARC = [XC YC A B THETA T1 T2] ## or: ## ARC = [XC YC A B T1 T2] (isothetic ellipse) ## with center (XC, YC), main axis of half-length A, second axis of ## half-length B, and ellipse arc running from t1 to t2 (both in degrees, ## in Counter-Clockwise orientation). ## ## Parameters can also be arrays. In this case, all arrays are suposed to ## have the same size... ## ## @example ## # draw an ellipse arc: center = [10 20], radii = 50 and 30, theta = 45 ## arc = [10 20 50 30 45 -90 270]; ## figure; ## axis([-50 100 -50 100]); axis equal; ## hold on ## drawEllipseArc(arc, 'color', 'r') ## ## # draw another ellipse arc, between angles -60 and 70 ## arc = [10 20 50 30 45 -60 (60+70)]; ## figure; ## axis([-50 100 -50 100]); axis equal; ## hold on ## drawEllipseArc(arc, 'LineWidth', 2); ## ray1 = createRay([10 20], deg2rad(-60+45)); ## drawRay(ray1) ## ray2 = createRay([10 20], deg2rad(70+45)); ## drawRay(ray2) ## @end example ## ## @seealso{ellipses2d, drawEllipse, drawCircleArc} ## @end deftypefn function varargout = drawEllipseArc(varargin) ## Extract input arguments # extract dawing style strings styles = {}; for i = 1:length(varargin) if ischar(varargin{i}) styles = varargin(i:end); varargin(i:end) = []; break; end end if length(varargin)==1 ellipse = varargin{1}; x0 = ellipse(1); y0 = ellipse(2); a = ellipse(3); b = ellipse(4); if size(ellipse, 2)>6 theta = ellipse(5); start = ellipse(6); extent = ellipse(7); else theta = zeros(size(x0)); start = ellipse(5); extent = ellipse(6); end elseif length(varargin)>=6 x0 = varargin{1}; y0 = varargin{2}; a = varargin{3}; b = varargin{4}; if length(varargin)>6 theta = varargin{5}; start = varargin{6}; extent = varargin{7}; else theta = zeros(size(x0)); start = varargin{5}; extent = varargin{6}; end else error('drawellipse: please specify center x, center y and radii a and b'); end ## Drawing # allocate memory for handles h = zeros(size(x0)); for i = 1:length(x0) # start and end angles t1 = deg2rad(start); t2 = t1 + deg2rad(extent); # vertices of ellipse t = linspace(t1, t2, 60); # convert angles to ellipse parametrisation sup = cos(t) > 0; t(sup) = atan(a(i) / b(i) * tan(t(sup))); t(~sup) = atan2(a(i) / b(i) * tan(2*pi - t(~sup)), -1); t = mod(t, 2*pi); # precompute cos and sin of theta (given in degrees) cot = cosd(theta(i)); sit = sind(theta(i)); # compute position of points xt = x0(i) + a(i)*cos(t)*cot - b(i)*sin(t)*sit; yt = y0(i) + a(i)*cos(t)*sit + b(i)*sin(t)*cot; h(i) = plot(xt, yt, styles{:}); end ## Process output arguments if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom2d/createLine.m0000644000175000017500000001420712035504503016633 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line} =} createLine(varargin) ## Create a straight line from 2 points, or from other inputs ## ## Line is represented in a parametric form : [x0 y0 dx dy] ## x = x0 + t*dx ## y = y0 + t*dy; ## ## ## L = createLine(p1, p2); ## Returns the line going through the two given points. ## ## L = createLine(x0, y0, dx, dy); ## Returns the line going through point (x0, y0) and with direction ## vector(dx, dy). ## ## L = createLine(LINE); ## where LINE is an array of 4 values, creates the line going through the ## point (LINE(1) LINE(2)), and with direction given by vector (LINE(3) ## LINE(4)). ## ## L = createLine(THETA); ## Create a polar line originated at (0,0) and with angle THETA. ## ## L = createLine(RHO, THETA); ## Create a polar line with normal theta, and with min distance to origin ## equal to rho. rho can be negative, in this case, the line is the same ## as with CREATELINE(-rho, theta+pi), but the orientation is different. ## ## ## Note: in all cases, parameters can be vertical arrays of the same ## dimension. The result is then an array of lines, of dimensions [N*4]. ## ## NOTE : A line can also be represented with a 1*5 array : ## [x0 y0 dx dy t]. ## whith 't' being one of the following : ## - t=0 : line is a singleton (x0,y0) ## - t=1 : line is an edge segment, between points (x0,y0) and (x0+dx, ## y0+dy). ## - t=Inf : line is a Ray, originated from (x0,y0) and going to infinity ## in the direction(dx,dy). ## - t=-Inf : line is a Ray, originated from (x0,y0) and going to infinity ## in the direction(-dx,-dy). ## - t=NaN : line is a real straight line, and contains all points ## verifying the above equation. ## This seems us a convenient way to represent uniformly all kind of lines ## (including edges, rays, and even point). ## ## NOTE2 : Any line object can be represented using a 1x6 array : ## [x0 y0 dx dy t0 t1] ## the first 4 parameters define the supporting line, ## t0 represent the position of the first point on the line, ## and t1 the position of the last point. ## * for edges : t0 = 0, and t1=1 ## * for straight lines : t0 = -inf, t1=inf ## * for rays : t0=0, t1=inf (or t0=-inf,t1=0 for inverted ray). ## I propose to call these objects 'lineArc' ## ## @seealso{lines2d, createEdge, createRay} ## @end deftypefn function line = createLine(varargin) if length(varargin)==1 # Only one input parameter. It can be : # - line angle # - array of four parameters # TODO : add control for arrays of lines. var = varargin{1}; if size(var, 2)==4 # 4 parameters of the line in a single array. line = var; elseif size(var, 2)==1 # 1 parameter : angle of the line, going through origin. line = [zeros(size(var)) zeros(size(var)) cos(var) sin(var)]; else error('wrong number of dimension for arg1 : can be 1 or 4'); end elseif length(varargin)==2 # 2 input parameters. They can be : # - line angle and signed distance to origin. # - 2 points, then 2 arrays of 1*2 double. v1 = varargin{1}; v2 = varargin{2}; if size(v1, 2)==1 # first param is angle of line, and second param is signed distance # to origin. line = [v1.*cos(v2) v1.*sin(v2) -sin(v2) cos(v2)]; else # first input parameter is first point, and second input is the # second point. line = [v1(:,1), v1(:,2), v2(:,1)-v1(:,1), v2(:,2)-v1(:,2)]; end elseif length(varargin)==3 # 3 input parameters : # first one is a point belonging to the line, # second and third ones are direction vector of the line (dx and dy). p = varargin{1}; line = [p(:,1) p(:,2) varargin{2} varargin{3}]; elseif length(varargin)==4 # 4 input parameters : # they are x0, y0 (point belongng to line) and dx, dy (direction vector # of the line). # All parameters should have the same size. line = [varargin{1} varargin{2} varargin{3} varargin{4}]; else error('Wrong number of arguments in ''createLine'' '); end endfunction %!test %! p1 = [1 1]; %! p2 = [2 3]; %! lin = createLine(p1, p2); %! assert (p1, lin(1,1:2), 1e-6); %! assert (p2-p1, lin(1,3:4), 1e-6); %!test %! p1 = [1 1;1 1]; %! p2 = [2 3;2 4]; %! lin = createLine(p1, p2); %! assert (2, size(lin, 1)); %! assert (p1, lin(:,1:2), 1e-6); %! assert (p2-p1, lin(:,3:4), 1e-6); geometry/inst/geom2d/isPointOnRay.m0000644000175000017500000000666012035504503017162 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPointOnRay (@var{point}, @var{ray}) ## @deftypefnx {Function File} {@var{b} = } isPointOnRay (@var{point}, @var{ray}, @var{tol}) ## Test if a point belongs to a ray ## ## @var{b} = isPointOnRay(@var{point}, @var{ray}); ## Returns @code{true} if point @var{point} belongs to the ray @var{ray}. ## @var{point} is given by [x y] and RAY by [x0 y0 dx dy]. @var{tol} gives the ## tolerance for the calculations. ## ## @seealso{rays2d, points2d, isPointOnLine} ## @end deftypefn function b = isPointOnRay(point, ray, varargin) # extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end # number of rays and points Nr = size(ray, 1); Np = size(point, 1); # if several rays or several points, adapt sizes of arrays x0 = repmat(ray(:,1)', Np, 1); y0 = repmat(ray(:,2)', Np, 1); dx = repmat(ray(:,3)', Np, 1); dy = repmat(ray(:,4)', Np, 1); xp = repmat(point(:,1), 1, Nr); yp = repmat(point(:,2), 1, Nr); # test if points belongs to the supporting line b1 = abs ( (xp-x0).*dy - (yp-y0).*dx ) ./ hypot(dx, dy) < tol; # check if points lie the good direction on the rays ind = abs (dx) > abs (dy); t = zeros (size (b1)); t(ind) = (xp(ind)-x0(ind))./dx(ind); t(~ind) = (yp(~ind)-y0(~ind))./dy(~ind); # combine the two tests b = b1 & (t >= 0); endfunction %!shared ray %! p1 = [10 20]; %! p2 = [80 20]; %! ray = createRay (p1, p2); %!assert (isPointOnRay([10 20], ray)); %!assert (isPointOnRay([80 20], ray)); %!assert (isPointOnRay([50 20], ray)); %!assert (isPointOnRay([50 20+1e-3], ray,1e-2)); %!assert ( !isPointOnRay([50 20+1e-3], ray,1e-4)); %!assert ( !isPointOnRay([9.99 20], ray)); %!assert ( !isPointOnRay([80 20.01], ray)); %!assert ( !isPointOnRay([50 21], ray)); %!assert ( !isPointOnRay([79 19], ray)); geometry/inst/geom2d/drawRay.m0000644000175000017500000000467412035504503016200 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawRay (@var{ray}) ## @deftypefnx {Function File} {@var{h} = } drawRay (@var{ray}, @var{param}, @var{value}) ## Draw a ray on the current axis. ## ## With @var{ray} having the syntax: [x0 y0 dx dy], draws the ray starting from ## point (x0 y0) and going to direction (dx dy), clipped with the current ## window axis. @var{param}, @var{value} pairs are passed to function @code{line}. ## ## @seealso{rays2d, drawLine, line} ## @end deftypefn function varargout = drawRay(ray, varargin) # get bounding box limits bb = axis(gca); # compute clipped shapes [clipped isInside] = clipRay(ray, bb); # allocate memory for handle h = -ones(size(ray, 1), 1); # draw visible rays h(isInside) = drawEdge(clipped(isInside, :), varargin{:}); # process output if nargout>0 varargout = {h}; end endfunction geometry/inst/geom2d/intersectLineCircle.m0000644000175000017500000000655312035504503020517 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{points} = } intersectLineCircle (@var{line}, @var{circle}) ## Intersection point(s) of a line and a circle ## ## INTERS = intersectLineCircle(LINE, CIRCLE); ## Returns a 2-by-2 array, containing on each row the coordinates of an ## intersection point. If the line and circle do not intersect, the result ## is filled with NaN. ## ## Example ## # base point ## center = [10 0]; ## # create vertical line ## l1 = [center 0 1]; ## # circle ## c1 = [center 5]; ## pts = intersectLineCircle(l1, c1) ## pts = ## 10 -5 ## 10 5 ## # draw the result ## figure; clf; hold on; ## axis([0 20 -10 10]); ## drawLine(l1); ## drawCircle(c1); ## drawPoint(pts, 'rx'); ## axis equal; ## ## @seealso{lines2d, circles2d, intersectLines, intersectCircles} ## @end deftypefn function points = intersectLineCircle(line, circle) # local precision eps = 1e-14; # center parameters center = circle(:, 1:2); radius = circle(:, 3); # line parameters dp = line(:, 1:2) - center; vl = line(:, 3:4); # coefficient of second order equation a = sum(line(:, 3:4).^2, 2); b = 2*sum(dp .* vl, 2); c = sum(dp.^2, 2) - radius.^2; # discriminant delta = b .^ 2 - 4 * a .* c; if delta > eps # find two roots of second order equation u1 = (-b - sqrt(delta)) / 2 ./ a; u2 = (-b + sqrt(delta)) / 2 ./ a; # convert into 2D coordinate points = [line(1:2) + u1 * line(3:4) ; line(1:2) + u2 * line(3:4)]; elseif abs(delta) < eps # find unique root, and convert to 2D coord. u = -b / 2 ./ a; points = line(1:2) + u*line(3:4); else # fill with NaN points = NaN * ones(2, 2); return; end endfunction geometry/inst/geom2d/clipPoints.m0000644000175000017500000000652112035504503016704 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{points2} =} clipPoints (@var{points}, @var{box}) ## Clip a set of points by a box. ## ## Returns the set @var{points2} which are located inside of the box @var{box}. ## ## @seealso{points2d, boxes2d, clipLine, drawPoint} ## @end deftypefn function points = clipPoints(points, bb) # get bounding box limits xmin = bb(1); xmax = bb(2); ymin = bb(3); ymax = bb(4); # compute indices of points inside visible area xOk = points(:,1)>=xmin & points(:,1)<=xmax; yOk = points(:,2)>=ymin & points(:,2)<=ymax; # keep only points inside box points = points(xOk & yOk, :); endfunction %!demo %! points = 2*rand(100,2)-1; %! bb = [-0.5 0.5 -0.25 0.25]; %! cpo = clipPoints (points, bb); %! %! plot(points(:,1),points(:,2),'xr') %! hold on %! drawBox(bb,'color','k') %! plot(cpo(:,1),cpo(:,2),'*g') %! hold off %!shared bb %! bb = [0 10 0 20]; %!test %! corners = [0 0;10 0;0 20;10 20]; %! cornersClipped = clipPoints(corners, bb); %! assert (4, size(cornersClipped, 1)); %! assert (corners, cornersClipped, 1e-6); %!test %! borders = [0 5;10 5;5 0;5 20]; %! bordersClipped = clipPoints(borders, bb); %! assert (4, size(bordersClipped, 1)); %! assert (borders, bordersClipped, 1e-6); %!test %! inside = [5 5;5 10;5 15]; %! insideClipped = clipPoints(inside, bb); %! assert (size(inside, 1), size(insideClipped, 1)); %! assert (inside, insideClipped); %!test %! points = [-1 0;11 0;-1 20;11 20;0 -1;0 21;10 -1;10 21]; %! pointsClipped = clipPoints(points, bb); %! assert (0, size(pointsClipped, 1)); %!test %! points = [-5 10;0 10;5 10;10 10; 15 10]; %! pointsClipped = clipPoints(points, bb); %! assert (3, size(pointsClipped, 1)); %! assert (points(2:4,:), pointsClipped, 1e-6); geometry/inst/geom2d/drawShape.m0000644000175000017500000000703712035504503016501 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawShape (@var{type}, @var{param}) ## @deftypefnx {Function File} drawShape (@dots{}, @var{option}) ## Draw various types of shapes (circles, polygons...). ## ## drawShape(TYPE, PARAM) ## Draw the shape of type TYPE, specified by given parameter PARAM. TYPE ## can be one of 'circle', 'ellipse', 'rect', 'polygon', 'curve' ## PARAM depend on the type. For example, if TYPE is 'circle', PARAM will ## contain [x0 y0 R]. ## ## Examples : ## @example ## drawShape('circle', [20 10 30]); ## Draw circle centered on [20 10] with radius 10. ## drawShape('rect', [20 20 40 10 pi/3]); ## Draw rectangle centered on [20 20] with length 40 and width 10, and ## oriented pi/3 wrt axis Ox. ## @end example ## ## drawShape(..., OPTION) ## also specifies drawing options. OPTION can be 'draw' (default) or ## 'fill'. ## @end deftypefn function varargout = drawShape(type, param, varargin) if ~iscell(type) type = {type}; end if ~iscell(param) tmp = cell(1, size(param, 1)); for i=1:size(param, 1) tmp{i} = param(i,:); end param = tmp; end option = 'draw'; if ~isempty(varargin) var = varargin{1}; if strcmpi(var, 'fill') option = 'fill'; end end # transform each shape into a polygon shape = cell(1,length(type)); for i=1:length(type) if strcmpi(type{i}, 'circle') shape{i} = circleAsPolygon(param{i}, 128); elseif strcmpi(type{i}, 'rect') shape{i} = rectAsPolygon(param{i}); elseif strcmpi(type{i}, 'polygon') shape{i} = param{i}; end end hold on; h = zeros(length(shape), 1); if strcmp(option, 'draw') for i=1:length(shape) h(i) = drawPolygon(shape{i}); end else for i=1:length(shape) h(i) = fillPolygon(shape{i}); end end if nargout>0 varargout{1}=h; end endfunction geometry/inst/geom2d/drawLine.m0000644000175000017500000001520012035504503016317 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawLine (@var{line}) ## @deftypefnx {Function File} {@var{h} =} drawLine (@var{line}, @var{param},@var{value}) ## Draw the line on the current axis. ## ## Draws the line LINE on the current axis, by using current axis to clip ## the line. Extra @var{param},@var{value} pairs are passed to the @code{line} function. ## Returns a handle to the created line object. If clipped line is not ## contained in the axis, the function returns -1. ## ## Example ## ## @example ## figure; hold on; axis equal; ## axis([0 100 0 100]); ## drawLine([30 40 10 20]); ## drawLine([30 40 20 -10], 'color', 'm', 'linewidth', 2); ## @end example ## ## @seealso{lines2d, createLine, drawEdge} ## @end deftypefn function varargout = drawLine(lin, varargin) # default style for drawing lines varargin = [{'color', 'b'}, varargin]; # extract bounding box of the current axis xlim = get(gca, 'xlim'); ylim = get(gca, 'ylim'); # clip lines with current axis box clip = clipLine(lin, [xlim ylim]); ok = isfinite(clip(:,1)); # initialize result array to invalide handles h = -1*ones(size(lin, 1), 1); # draw valid lines h(ok) = line(clip(ok, [1 3])', clip(ok, [2 4])', varargin{:}); # return line handle if needed if nargout>0 varargout{1}=h; end endfunction %!demo %! figure; hold on; axis equal; %! axis([0 100 0 100]); %! drawLine([30 40 10 20]); %! drawLine([30 40 20 -10], 'color', 'm', 'linewidth', 2); %!shared privpath %! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private']; %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [30 40 10 0]; %! edge = [0 40 100 40]; %! hl = drawLine(line); %! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata')); %! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata')); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [30 40 -10 0]; %! edge = [100 40 0 40]; %! hl = drawLine(line); %! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata')); %! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata')); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [30 140 10 0]; %! hl = drawLine(line); %! assertEqual(-1, hl); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [30 40 0 10]; %! edge = [30 0 30 100]; %! hl = drawLine(line); %! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata')); %! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata')); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [30 40 0 -10]; %! edge = [30 100 30 0]; %! hl = drawLine(line); %! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata')); %! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata')); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [140 30 0 10]; %! hl = drawLine(line); %! assertEqual(-1, hl); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [80 30 10 10]; %! edge = [50 0 100 50]; %! hl = drawLine(line); %! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata')); %! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata')); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [20 70 10 10]; %! edge = [0 50 50 100]; %! hl = drawLine(line); %! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata')); %! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata')); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [140 -30 10 10]; %! hl = drawLine(line); %! assertEqual(-1, hl); %! line = [-40 130 10 10]; %! hl = drawLine(line); %! assertEqual(-1, hl); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! box = [0 100 0 100]; %! hf = figure('visible','off'); %! axis(box); %! line = [... %! 80 30 10 10; ... %! 20 70 10 10; ... %! 140 -30 10 10; ... %! -40 130 10 10]; %! edge = [... %! 50 0 100 50; ... %! 0 50 50 100]; %! hl = drawLine(line); %! assertEqual(4, length(hl)); %! assertElementsAlmostEqual(edge(1, [1 3]), get(hl(1), 'xdata')); %! assertElementsAlmostEqual(edge(1, [2 4]), get(hl(1), 'ydata')); %! assertElementsAlmostEqual(edge(2, [1 3]), get(hl(2), 'xdata')); %! assertElementsAlmostEqual(edge(2, [2 4]), get(hl(2), 'ydata')); %! assertEqual(-1, hl(3)); %! assertEqual(-1, hl(4)); %! rmpath (privpath); geometry/inst/geom2d/vectorAngle.m0000644000175000017500000001365512035504503017037 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{alpha} =} vectorAngle (@var{v1}) ## Angle of a vector, or between 2 vectors ## ## A = vectorAngle(V); ## Returns angle between Ox axis and vector direction, in Counter ## clockwise orientation. ## The result is normalised between 0 and 2*PI. ## ## A = vectorAngle(V1, V2); ## Returns the angle from vector V1 to vector V2, in counter-clockwise ## order, and in radians. ## ## A = vectorAngle(..., 'cutAngle', CUTANGLE); ## A = vectorAngle(..., CUTANGLE); # (deprecated syntax) ## Specifies convention for angle interval. CUTANGLE is the center of the ## 2*PI interval containing the result. See normalizeAngle for details. ## ## Example: ## rad2deg(vectorAngle([2 2])) ## ans = ## 45 ## rad2deg(vectorAngle([1 sqrt(3)])) ## ans = ## 60 ## rad2deg(vectorAngle([0 -1])) ## ans = ## 270 ## ## @seealso{vectors2d, angles2d, normalizeAngle} ## @end deftypefn function alpha = vectorAngle(v1, varargin) ## Initializations # default values v2 = []; cutAngle = pi; # process input arguments while ~isempty(varargin) var = varargin{1}; if isnumeric(var) && isscalar(var) # argument is normalization constant cutAngle = varargin{1}; varargin(1) = []; elseif isnumeric(var) && size(var, 2) == 2 # argument is second vector v2 = varargin{1}; varargin(1) = []; elseif ischar(var) && length(varargin) >= 2 # argument is option given as string + value if strcmpi(var, 'cutAngle') cutAngle = varargin{2}; varargin(1:2) = []; else error(['Unknown option: ' var]); end else error('Unable to parse inputs'); end end ## Case of one vector # If only one vector is provided, computes its angle if isempty(v2) # compute angle and format result in a 2*pi interval alpha = atan2(v1(:,2), v1(:,1)); # normalize within a 2*pi interval alpha = normalizeAngle(alpha + 2*pi, cutAngle); return; end ## Case of two vectors # compute angle of each vector alpha1 = atan2(v1(:,2), v1(:,1)); alpha2 = atan2(v2(:,2), v2(:,1)); # difference alpha = bsxfun(@minus, alpha2, alpha1); # normalize within a 2*pi interval alpha = normalizeAngle(alpha + 2*pi, cutAngle); endfunction %!test %! ang = vectorAngle([1 0]); %! assert(0, ang, 1e-6); %!test %! ang = vectorAngle([0 1]); %! assert(pi/2, ang, 1e-6); %!test %! ang = vectorAngle([-1 0]); %! assert(pi, ang, 1e-6); %!test %! ang = vectorAngle([0 -1]); %! assert(3*pi/2, ang, 1e-6); %!test %! ang = vectorAngle([-1 1]); %! assert(3*pi/4, ang, 1e-6); %!test %! ang = vectorAngle([1 0], pi); %! assert(0, ang, 1e-6); %!test %! ang = vectorAngle([0 1], pi); %! assert(pi/2, ang, 1e-6); %!test %! ang = vectorAngle([-1 0], pi); %! assert(pi, ang, 1e-6); %!test %! ang = vectorAngle([0 -1], pi); %! assert(3*pi/2, ang, 1e-6); %!test %! ang = vectorAngle([-1 1], pi); %! assert(3*pi/4, ang, 1e-6); %!test %! vecs = [1 0;0 1;-1 0;0 -1;1 1]; %! angs = [0;pi/2;pi;3*pi/2;pi/4]; %! assert(angs, vectorAngle(vecs)); %! assert(angs, vectorAngle(vecs, pi)); %!test %! ang = vectorAngle([1 0], 0); %! assert(0, ang, 1e-6); %!test %! ang = vectorAngle([0 1], 0); %! assert(pi/2, ang, 1e-6); %!test %! ang = vectorAngle([0 -1], 0); %! assert(-pi/2, ang, 1e-6); %!test %! ang = vectorAngle([-1 1], 0); %! assert(3*pi/4, ang, 1e-6); %!test %! vecs = [1 0;0 1;0 -1;1 1;1 -1]; %! angs = [0;pi/2;-pi/2;pi/4;-pi/4]; %! assert(angs, vectorAngle(vecs, 0), 1e-6); %!test %! v1 = [1 0]; %! v2 = [0 1]; %! ang = pi /2 ; %! assert(ang, vectorAngle(v1, v2), 1e-6); %!test %! v1 = [1 0]; %! v2 = [0 1; 0 1; 1 1; -1 1]; %! ang = [pi / 2 ;pi / 2 ;pi / 4 ; 3 * pi / 4]; %! assert(ang, vectorAngle(v1, v2), 1e-6); %!test %! v1 = [0 1; 0 1; 1 1; -1 1]; %! v2 = [-1 0]; %! ang = [pi / 2 ;pi / 2 ; 3 * pi / 4 ; pi / 4]; %! assert(ang, vectorAngle(v1, v2), 1e-6); %!test %! v1 = [1 0; 0 1; 1 1; -1 1]; %! v2 = [0 1; 1 0; -1 1; -1 0]; %! ang = [pi / 2 ;3 * pi / 2 ;pi / 2 ; pi / 4]; %! assert(ang, vectorAngle(v1, v2), 1e-6); geometry/inst/geom2d/ellipses2d.m0000644000175000017500000000403212035504503016621 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} ellipses2d () ## Description of functions operating on ellipses. ## ## Ellipses are represented by their center, the length of their 2 ## semi-axes length, and their angle from the Ox direction (in degrees). ## E = [XC YC A B THETA]; ## ## @seealso{circles2d, inertiaEllipse, isPointInEllipse, ellipseAsPolygon ## drawEllipse, drawEllipseArc} ## @end deftypefn function ellipses2d(varargin) help('ellipses2d'); endfunction geometry/inst/geom2d/clipLine.m0000644000175000017500000001570012035504503016316 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{edge} =} clipLine (@var{line}, @var{box}) ## Clip a line with a box. ## ## @var{line} is a straight line given as a 4 element row vector: [x0 y0 dx dy], ## with (x0 y0) being a point of the line and (dx dy) a direction vector, ## @var{box} is the clipping box, given by its extreme coordinates: ## [xmin xmax ymin ymax]. ## The result is given as an edge, defined by the coordinates of its 2 ## extreme points: [x1 y1 x2 y2]. ## If line does not intersect the box, [NaN NaN NaN NaN] is returned. ## ## Function works also if @var{line} is a Nx4 array, if @var{box} is a Nx4 array, or ## if both @var{line} and @var{box} are Nx4 arrays. In these cases, @var{edge} is a Nx4 ## array. ## ## Example: ## ## @example ## line = [30 40 10 0]; ## box = [0 100 0 100]; ## res = clipLine(line, box) ## res = ## 0 40 100 40 ## @end example ## ## @seealso{lines2d, boxes2d, edges2d, clipEdge, clipRay} ## @end deftypefn function edge = clipLine(lin, bb, varargin) # adjust size of two input arguments if size(lin, 1)==1 lin = repmat(lin, size(bb, 1), 1); elseif size(bb, 1)==1 bb = repmat(bb, size(lin, 1), 1); elseif size(lin, 1) ~= size(bb, 1) error('bad sizes for input'); end # allocate memory nbLines = size(lin, 1); edge = zeros(nbLines, 4); # main loop on lines for i=1:nbLines # extract limits of the box xmin = bb(i, 1); xmax = bb(i, 2); ymin = bb(i, 3); ymax = bb(i, 4); # use direction vector for box edges similar to direction vector of the # line in order to reduce computation errors delta = hypot(lin(i,3), lin(i,4)); # compute intersection with each edge of the box # lower edge px1 = intersectLines(lin(i,:), [xmin ymin delta 0]); # right edge px2 = intersectLines(lin(i,:), [xmax ymin 0 delta]); # upper edge py1 = intersectLines(lin(i,:), [xmax ymax -delta 0]); # left edge py2 = intersectLines(lin(i,:), [xmin ymax 0 -delta]); # remove undefined intersections (case of lines parallel to box edges) points = [px1 ; px2 ; py1 ; py2]; points = points(isfinite(points(:,1)), :); # sort points according to their position on the line pos = linePosition(points, lin(i,:)); [pos inds] = sort(pos); ##ok points = points(inds, :); # create clipped edge by using the two points in the middle ind = size(points, 1)/2; inter1 = points(ind,:); inter2 = points(ind+1,:); edge(i, 1:4) = [inter1 inter2]; # check that middle point of the edge is contained in the box midX = mean(edge(i, [1 3])); xOk = xmin <= midX && midX <= xmax; midY = mean(edge(i, [2 4])); yOk = ymin <= midY && midY <= ymax; # if one of the bounding condition is not met, set edge to NaN if ~(xOk && yOk) edge (i,:) = NaN; end end endfunction %!demo %! lin = [30 40 10 0]; %! bb = [0 100 0 100]; %! res = clipLine(lin, bb) %! %! drawBox(bb,'color','k'); %! line(lin([1 3]),lin([2 4]),'color','b'); %! line(res([1 3]),res([2 4]),'color','r','linewidth',2); %! axis tight %! v = axis (); %! axis(v+[0 10 -10 0]) %!test # inside, to the right # inside, to the left# outside %! bb = [0 100 0 100]; %! lin = [30 40 10 0]; %! edge = [0 40 100 40]; %! assert (edge, clipLine(lin, bb), 1e-6); %! lin = [30 40 -10 0]; %! edge = [100 40 0 40]; %! assert (edge, clipLine(lin, bb), 1e-6); %! lin = [30 140 10 0]; %! assert (sum(isnan(clipLine(lin, bb)))==4); %!test # inside, upward # inside, downward # outside %! bb = [0 100 0 100]; %! lin = [30 40 0 10]; %! edge = [30 0 30 100]; %! assert (edge, clipLine(lin, bb), 1e-6); %! lin = [30 40 0 -10]; %! edge = [30 100 30 0]; %! assert (edge, clipLine(lin, bb), 1e-6); %! lin = [140 30 0 10]; %! assert (sum(isnan(clipLine(lin, bb)))==4); %!test # inside, top right corner# inside, down right corner # outside %! bb = [0 100 0 100]; %! lin = [80 30 10 10]; %! edge = [50 0 100 50]; %! assert (edge, clipLine(lin, bb), 1e-6); %! lin = [20 70 10 10]; %! edge = [0 50 50 100]; %! assert (edge, clipLine(lin, bb), 1e-6); %! lin = [140 -30 10 10]; %! assert (sum(isnan(clipLine(lin, bb)))==4); %! lin = [-40 130 10 10]; %! assert (sum(isnan(clipLine(lin, bb)))==4); %!test #multilines # inside, top right corner %! bb = [0 100 0 100]; %! lin = [... %! 80 30 10 10; ... %! 20 70 10 10; ... %! 140 -30 10 10; ... %! -40 130 10 10]; %! edge = [... %! 50 0 100 50; ... %! 0 50 50 100; ... %! NaN NaN NaN NaN; ... %! NaN NaN NaN NaN; ... %! ]; %! clipped = clipLine(lin, bb); %! assert (4, size(clipped, 1)); %! assert (edge(1:2, :), clipped(1:2, :), 1e-6); %! assert (sum(isnan(clipped(3,:)))==4); %! assert (sum(isnan(clipped(4,:)))==4); %!test # test clipping of horizontal lines # inside, to the right %! bb = [-1 1 -1 1]*1e10; %! lin = [3 0 1 2]; %! D = 1e10; %! edge = [3-D/2 -D 3+D/2 D]; %! clipped = clipLine(lin, bb); %! assert (edge, clipped); %!test # inside, to the right %! bb = [-1 1 -1 1]*100; %! lin = [3 0 1*1e10 2*1e10]; %! D = 100; %! edge = [3-D/2 -D 3+D/2 D]; %! clipped = clipLine(lin, bb); %! assert (edge, clipped, 1e-6); geometry/inst/geom2d/intersectEdges.m0000644000175000017500000001345112035504503017530 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} = } intersectEdges (@var{edge1}, @var{edge2}) ## Return all intersections between two set of edges ## ## P = intersectEdges(E1, E2); ## returns the intersection point of lines L1 and L2. E1 and E2 are 1-by-4 ## arrays, containing parametric representation of each edge (in the form ## [x1 y1 x2 y2], see 'createEdge' for details). ## ## In case of colinear edges, returns [Inf Inf]. ## In case of parallel but not colinear edges, returns [NaN NaN]. ## ## If each input is [N*4] array, the result is a [N*2] array containing ## intersections of each couple of edges. ## If one of the input has N rows and the other 1 row, the result is a ## [N*2] array. ## ## @seealso{edges2d, intersectLines} ## @end deftypefn function point = intersectEdges(edge1, edge2) ## Initialisations # ensure input arrays are same size N1 = size(edge1, 1); N2 = size(edge2, 1); # ensure input have same size if N1~=N2 if N1==1 edge1 = repmat(edge1, [N2 1]); N1 = N2; elseif N2==1 edge2 = repmat(edge2, [N1 1]); end end # tolerance for precision tol = 1e-14; # initialize result array x0 = zeros(N1, 1); y0 = zeros(N1, 1); ## Detect parallel and colinear cases # indices of parallel edges #par = abs(dx1.*dy2 - dx1.*dy2) return [NaN NaN] x0(par & ~col) = NaN; y0(par & ~col) = NaN; ## Process colinear edges # colinear edges may have 0, 1 or infinite intersection # Discrimnation based on position of edge2 vertices on edge1 if sum(col)>0 # array for storing results of colinear edges resCol = Inf*ones(size(col)); # compute position of edge2 vertices wrt edge1 t1 = edgePosition(edge2(col, 1:2), edge1(col, :)); t2 = edgePosition(edge2(col, 3:4), edge1(col, :)); # control location of vertices: we want t1t2 tmp = t1; t1 = t2; t2 = tmp; end # edge totally before first vertex or totally after last vertex resCol(col(t2<-eps)) = NaN; resCol(col(t1>1+eps)) = NaN; # set up result into point coordinate x0(col) = resCol; y0(col) = resCol; # touches on first point of first edge touch = col(abs(t2)<1e-14); x0(touch) = edge1(touch, 1); y0(touch) = edge1(touch, 2); # touches on second point of first edge touch = col(abs(t1-1)<1e-14); x0(touch) = edge1(touch, 3); y0(touch) = edge1(touch, 4); end ## Process non parallel cases # process intersecting edges whose interecting lines intersect i = find(~par); # use a test to avoid process empty arrays if sum(i)>0 # extract base parameters of supporting lines for non-parallel edges x1 = edge1(i,1); y1 = edge1(i,2); dx1 = edge1(i,3)-x1; dy1 = edge1(i,4)-y1; x2 = edge2(i,1); y2 = edge2(i,2); dx2 = edge2(i,3)-x2; dy2 = edge2(i,4)-y2; # compute intersection points of supporting lines delta = (dx2.*dy1-dx1.*dy2); x0(i) = ((y2-y1).*dx1.*dx2 + x1.*dy1.*dx2 - x2.*dy2.*dx1) ./ delta; y0(i) = ((x2-x1).*dy1.*dy2 + y1.*dx1.*dy2 - y2.*dx2.*dy1) ./ -delta; # compute position of intersection points on each edge # t1 is position on edge1, t2 is position on edge2 t1 = ((y0(i)-y1).*dy1 + (x0(i)-x1).*dx1) ./ (dx1.*dx1+dy1.*dy1); t2 = ((y0(i)-y2).*dy2 + (x0(i)-x2).*dx2) ./ (dx2.*dx2+dy2.*dy2); # check position of points on edges. # it should be comprised between 0 and 1 for both t1 and t2. # if not, the edges do not intersect out = t1<-tol | t1>1+tol | t2<-tol | t2>1+tol; x0(i(out)) = NaN; y0(i(out)) = NaN; end ## format output arguments point = [x0 y0]; endfunction geometry/inst/geom2d/drawBezierCurve.m0000644000175000017500000001010612035504503017655 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawBezierCurve (@var{points}) ## @deftypefnx {Function File} drawBezierCurve (@var{pp}) ## @deftypefnx {Function File} drawBezierCurve (@dots{}, @var{param}, @var{value}, @dots{}) ## @deftypefnx {Function File} {@var{h} =}drawBezierCurve (@dots{}) ## Draw a cubic bezier curve defined by the control points @var{points}. ## ## With only one input argument, draws the Bezier curve defined by the 4 control ## points stored in @var{points}. @var{points} is either a 4-by-2 array ## (vertical concatenation of point coordinates), or a 1-by-8 array (horizotnal ## concatenation of point coordinates). The curve could be described by its ## polynomial (output of @code{cbezier2poly}) @var{pp}, which should be a 2-by-4 ## array. ## ## The optional @var{param}, @var{value} pairs specify additional drawing ## parameters, see the @code{plot} function for details. The specific parameter ## 'discretization' with an integer associated value defines the amount of ## points used to plot the curve. If the output is requiered, the function ## returns the handle to the created graphic object. ## ## @seealso{cbezier2poly, plot} ## @end deftypefn function varargout = drawBezierCurve(points, varargin) # default number of discretization steps N = 64; # check if discretization step is specified if ~isempty(varargin) [tf idx] = ismember ({'discretization'},{varargin{1:2:end}}); if ~isempty(idx) N = varargin{idx+1}; varargin(idx:idx+1) = []; end end # parametrization variable for bezier (use N+1 points to have N edges) t = linspace(0, 1, N+1); if any(size(points) ~= [2 4]) [x y] = cbezier2poly(points,t); else # Got a polynomial description x = polyval(points(1,:),t); y = polyval(points(2,:),t); end # draw the curve h = plot(x, y, varargin{:}); # eventually return a handle to the created object if nargout > 0 varargout = {h}; end endfunction %!demo %! points = [0 0; 3 1; -2 1; 1 0]; %! drawBezierCurve(points); %! hold on %! plot(points([1 4],1),points([1 4],2),'go'); %! plot(points([2 3],1),points([2 3],2),'rs'); %! line(points([1 2],1),points([1 2],2),'color','k'); %! line(points([3 4],1),points([3 4],2),'color','k'); %! h = drawBezierCurve(points, 'discretization', 6, 'color','r'); %! hold off %!shared p %! p = [0 0; 3 1; -2 1; 1 0]; %!error(drawBezier()) %!error(drawBezier ('discretization')) %!error(drawBezier (p, 'discretization', 'a')) %!error(drawBezier (p(:))) geometry/inst/geom2d/edges2d.m0000644000175000017500000000420212035504503016067 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} edges2d () ## Description of functions operating on planar edges # # An edge is represented by the corodinate of its end points: # EDGE = [X1 Y1 X2 Y2]; # # A set of edges is represented by a N*4 array, each row representing an # edge. # # # @seealso{lines2d, rays2d, points2d # createEdge, edgeAngle, edgeLength, edgeToLine, midPoint # intersectEdges, intersectLineEdge, isPointOnEdge # clipEdge, transformEdge # drawEdge, drawCenteredEdge} ## @end deftypefn function edges2d(varargin) help('edges2d'); endfunction geometry/inst/geom2d/crackPattern2.m0000644000175000017500000001300312035504503017254 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{e} = } crackPattern2 (@var{box}, @var{points}, @var{alpha}) ## Create a (bounded) crack pattern tessellation ## ## E = crackPattern2(BOX, POINTS, ALPHA) ## create a crack propagation pattern wit following parameters : ## - pattern is bounded by area BOX which is a polygon. ## - each crack originates from points given in POINTS ## - directions of each crack is given by a [NxM] array ALPHA, where M is ## the number of rays emanating from each seed/ ## - a crack stop when it reaches another already created crack. ## - all cracks stop when they reach the border of the frame, given by box ## (a serie of 4 points). ## The result is a collection of edges, in the form [x1 y1 x2 y2]. ## ## E = crackPattern2(BOX, POINTS, ALPHA, SPEED) ## Also specify speed of propagation of each crack. ## ## ## See the result with : ## figure; ## drawEdge(E); ## ## @seealso{drawEdge} ## @end deftypefn function edges = crackPattern2(box, points, alpha, varargin) if ~isempty(varargin) speed = varargin{1}; else speed = ones(size(points, 1), 1); end # Compute line equations for each initial crack. # The 'Inf' at the end correspond to the position of the limit. # If an intersection point is found with another line, but whose position # is after this value, this means that another crack stopped it before it # reach the intersection point. NP = size(points, 1); lines = zeros(0, 5); for i=1:size(alpha, 2) lines = [lines; points speed.*cos(alpha(:,i)) speed.*sin(alpha(:,i)) Inf*ones(NP, 1)]; end NL = size(lines, 1); # initialize lines for borders, but assign a very high speed, to be sure # borders will stop all cracks. dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5; dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5; # add borders to the lines set lines = [lines ; createLine(box, dx, dy) Inf*ones(4,1)]; edges = zeros(0, 4); while true modif = 0; # try to update each line for i=1:NL # initialize first point of edge edges(i, 1:2) = lines(i, 1:2); # compute intersections with all other lines pi = intersectLines(lines(i,:), lines); # compute position of all intersection points on the current line pos = linePosition(pi, lines(i,:)); # consider points to the right (positive position), and sort them indr = find(pos>1e-12 & pos~=Inf); [posr, indr2] = sort(pos(indr)); # look for the closest intersection to the right for i2=1:length(indr2) # index of intersected line il = indr(indr2(i2)); # position of point relative to intersected line pos2 = linePosition(pi(il, :), lines(il, :)); # depending on the sign of position, tests if the line2 can # stop the current line, or if it was stopped before if pos2>0 if pos2 ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } createScaling (@var{s}) ## @deftypefnx {Function File} {@var{T} = } createScaling (@var{sx}, @var{sy}) ## Create the 3x3 matrix of a scaling in 2 dimensions. # # Assume scaling @var{s} is equal n all directions unless @var{sx} and @var{sy} are given. # Returns the matrix corresponding to scaling in the 2 main directions. # The returned matrix has the form: # [SX 0 0] # [0 SY 0] # [0 0 1] # # @seealso{transforms2d, transformPoint, createTranslation, createRotation} ## @end deftypefn function trans = createScaling(varargin) # defined default arguments sx = 1; sy = 1; cx = 0; cy = 0; # process input arguments if length(varargin)==1 # the argument is either the scaling factor in both direction, # or a 1x2 array containing scaling factor in each direction var = varargin{1}; sx = var(1); sy = var(1); if length(var)>1 sy = var(2); end elseif length(varargin)==2 # the 2 arguments are the scaling factors in each dimension sx = varargin{1}; sy = varargin{2}; elseif length(varargin)==3 # first argument is center, 2nd and 3d are scaling factors center = varargin{1}; cx = center(1); cy = center(2); sx = varargin{2}; sy = varargin{3}; end # create result matrix trans = [sx 0 cx*(1-sx); 0 sy cy*(1-sy); 0 0 1]; endfunction %!test %! trans = createScaling(2); %! assert (trans, [2 0 0;0 2 0;0 0 1], 1e-6); %!test %! trans = createScaling(2, 3); %! assert (trans, [2 0 0;0 3 0;0 0 1], 1e-6); %!test %! trans = createScaling([2 3]); %! assert (trans, [2 0 0;0 3 0;0 0 1], 1e-6); %!test %! sx = 2; %! sy = 3; %! p0 = [4 5]; %! trans1 = createScaling(p0, sx, sy); %! t1 = createTranslation(-p0); %! sca = createScaling(sx, sy); %! t2 = createTranslation(p0); %! trans2 = t2*sca*t1; %! assert (trans1, trans2, 1e-6); geometry/inst/geom2d/rotateVector.m0000644000175000017500000000441412035504503017240 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{vr} = } rotateVector (@var{v}, @var{theta}) ## Rotate a vector by a given angle ## ## Rotate the vector @var{v} by an angle @var{theta}, given in radians. ## ## Example ## ## @example ## rotateVector([1 0], pi/2) ## ans = ## 0 1 ## @end example ## ## @seealso{vectors2d, transformVector, createRotation} ## @end deftypefn function vr = rotateVector(v, angle) # precomputes angles cot = cos(angle); sit = sin(angle); # compute rotated coordinates vr = [cot * v(:,1) - sit * v(:,2) , sit * v(:,1) + cot * v(:,2)]; endfunction %!assert ([0 1],rotateVector([1 0],pi/2), 1e-6) %!assert (sqrt([0.5 0.5]),rotateVector([1 0],pi/4), 1e-6) geometry/inst/geom2d/edgeToLine.m0000644000175000017500000000415412035504503016577 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line} = } edgeToLine (@var{edge}) ## Convert an edge to a straight line ## ## LINE = edgeToLine(EDGE); ## Returns the line containing the edge EDGE. ## ## Example ## edge = [2 3 4 5]; ## line = edgeToLine(edge); ## figure(1); hold on; axis([0 10 0 10]); ## drawLine(line, 'color', 'g') ## drawEdge(edge, 'linewidth', 2) ## ## @seealso{edges2d, lines2d} ## @end deftypefn function line = edgeToLine(edge) line = [edge(:, 1:2) edge(:, 3:4)-edge(:, 1:2)]; endfunction geometry/inst/geom2d/private/0000755000175000017500000000000012130276034016051 5ustar juanpijuanpigeometry/inst/geom2d/private/assertTrue.m0000644000175000017500000000330312035504503020366 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} assertTrue () ## Wrapper. Not documented. ## ## @end deftypefn function assertTrue(a) assert(a); endfunction geometry/inst/geom2d/private/assertElementsAlmostEqual.m0000644000175000017500000000335212035504503023377 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} assertElementsAlmostEqual () ## Wrapper. Not documented. ## ## @end deftypefn function assertElementsAlmostEqual(a,b) assert(b,a,1e-6); endfunction geometry/inst/geom2d/private/assertAlmostEqual.m0000644000175000017500000000333212035504503021700 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} assertAlmostEqual () ## Wrapper. Not documented. ## ## @end deftypefn function assertAlmostEqual(a,b) assert(b,a,1e-6); endfunction geometry/inst/geom2d/private/assertEqual.m0000644000175000017500000000331112035504503020515 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} assertEqual () ## Wrapper. Not documented. ## ## @end deftypefn function assertEqual(a,b) assert(b,a); endfunction geometry/inst/geom2d/private/assertFalse.m0000644000175000017500000000330612035504503020504 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} assertFalse () ## Wrapper. Not documented. ## ## @end deftypefn function assertFalse(a) assert(!a); endfunction geometry/inst/geom2d/drawCircle.m0000644000175000017500000001034412035504503016635 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawCircle (@var{x0}, @var{y0}, @var{r}) ## @deftypefnx {Function File} {@var{h} = } drawCircle (@var{circle}) ## @deftypefnx {Function File} {@var{h} = } drawCircle (@var{center}, @var{radius}) ## @deftypefnx {Function File} {@var{h} = } drawCircle (@dots{}, @var{nstep}) ## @deftypefnx {Function File} {@var{h} = } drawCircle (@dots{}, @var{name}, @var{value}) ## Draw a circle on the current axis ## ## drawCircle(X0, Y0, R); ## Draw the circle with center (X0,Y0) and the radius R. If X0, Y0 and R ## are column vectors of the same length, draw each circle successively. ## ## drawCircle(CIRCLE); ## Concatenate all parameters in a Nx3 array, where N is the number of ## circles to draw. ## ## drawCircle(CENTER, RADIUS); ## Specify CENTER as Nx2 array, and radius as a Nx1 array. ## ## drawCircle(..., NSTEP); ## Specify the number of edges that will be used to draw the circle. ## Default value is 72, creating an approximation of one point for each 5 ## degrees. ## ## drawCircle(..., NAME, VALUE); ## Specifies plotting options as pair of parameters name/value. See plot ## documentation for details. ## ## ## H = drawCircle(...); ## return handles to each created curve. ## ## @seealso{circles2d, drawCircleArc, drawEllipse} ## @end deftypefn function varargout = drawCircle(varargin) # process input parameters var = varargin{1}; if size(var, 2) == 1 x0 = varargin{1}; y0 = varargin{2}; r = varargin{3}; varargin(1:3) = []; elseif size(var, 2) == 2 x0 = var(:,1); y0 = var(:,2); r = varargin{2}; varargin(1:2) = []; elseif size(var, 2) == 3 x0 = var(:,1); y0 = var(:,2); r = var(:,3); varargin(1) = []; else error('bad format for input in drawCircle'); end # ensure each parameter is column vector x0 = x0(:); y0 = y0(:); r = r(:); # default number of discretization steps N = 72; # check if discretization step is specified if ~isempty(varargin) var = varargin{1}; if length(var)==1 && isnumeric(var) N = round(var); varargin(1) = []; end end # parametrization variable for circle (use N+1 as first point counts twice) t = linspace(0, 2*pi, N+1); cot = cos(t); sit = sin(t); # empty array for graphic handles h = zeros(size(x0)); # compute discretization of each circle for i = 1:length(x0) xt = x0(i) + r(i) * cot; yt = y0(i) + r(i) * sit; h(i) = plot(xt, yt, varargin{:}); end if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom2d/intersectCircles.m0000644000175000017500000001070312035504503020062 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{points} = } intersectCircles (@var{circle1}, @var{circle2}) ## Intersection points of two circles. ## ## POINTS = intersectCircles(CIRCLE1, CIRCLE2) ## Computes the intersetion point of the two circles CIRCLE1 and CIRCLE1. ## Both circles are given with format: [XC YC R], with (XC,YC) being the ## coordinates of the center and R being the radius. ## POINTS is a 2-by-2 array, containing coordinate of an intersection ## point on each row. ## In the case of tangent circles, the intersection is returned twice. It ## can be simplified by using the 'unique' function. ## ## Example ## # intersection points of two distant circles ## c1 = [0 0 10]; ## c2 = [10 0 10]; ## pts = intersectCircles(c1, c2) ## pts = ## 5 -8.6603 ## 5 8.6603 ## ## # intersection points of two tangent circles ## c1 = [0 0 10]; ## c2 = [20 0 10]; ## pts = intersectCircles(c1, c2) ## pts = ## 10 0 ## 10 0 ## pts2 = unique(pts, 'rows') ## pts2 = ## 10 0 ## ## References ## http://local.wasp.uwa.edu.au/~pbourke/geometry/2circle/ ## http://mathworld.wolfram.com/Circle-CircleIntersection.html ## ## @seealso{circles2d, intersectLineCircle, radicalAxis} ## @end deftypefn function points = intersectCircles(circle1, circle2) # adapt sizes of inputs n1 = size(circle1, 1); n2 = size(circle2, 1); if n1 ~= n2 if n1 > 1 && n2 == 1 circle2 = repmat(circle2, n1, 1); elseif n2 > 1 && n1 == 1 circle1 = repmat(circle1, n2, 1); else error('Both input should have same number of rows'); end end # extract center and radius of each circle center1 = circle1(:, 1:2); center2 = circle2(:, 1:2); r1 = circle1(:,3); r2 = circle2(:,3); # allocate memory for result nPoints = length(r1); points = NaN * ones(2*nPoints, 2); # distance between circle centers d12 = distancePoints(center1, center2, 'diag'); # get indices of circle couples with intersections inds = d12 >= abs(r1 - r2) & d12 <= (r1 + r2); if sum(inds) == 0 return; end # angle of line from center1 to center2 angle = angle2Points(center1(inds,:), center2(inds,:)); # position of intermediate point, located at the intersection of the # radical axis with the line joining circle centers d1m = d12(inds) / 2 + (r1(inds).^2 - r2(inds).^2) ./ (2 * d12(inds)); tmp = polarPoint(center1(inds, :), d1m, angle); # distance between intermediate point and each intersection point h = sqrt(r1(inds).^2 - d1m.^2); # indices of valid intersections inds2 = find(inds)*2; inds1 = inds2 - 1; # create intersection points points(inds1, :) = polarPoint(tmp, h, angle - pi/2); points(inds2, :) = polarPoint(tmp, h, angle + pi/2); endfunction geometry/inst/geom2d/closed_path.m0000644000175000017500000000721412035504503017045 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} polygon (@var{x}) ## Returns a simple closed path that passes through all the points in @var{x}. ## @var{x} is a vector containing 2D coordinates of the points. ## ## @end deftypefn ## Author: Simeon Simeonov function y = closed_path(x) if(size(x,1) > 1 && size(x,1) < size(x,2)) x = x'; end N = size(x,1); # Number of points idx = zeros(N, 1); # ind contains the indices of the sorted coordinates a = find(x(:,2)==min(x(:,2))); if(size(a,1) > 1) [~, i] = sort(x(a,1)); a = a(i(1)); end x_1 = x(x(:,2)==x(a,2),:); # find all x with the same y coordinate if(x(a,1) == min(x(:,1))) x_2 = x(x(:,1)==x(a,1),:); # find all x with the same x coordinate else x_2 = x(a,:); end if(size(x_1,1) > 1 || size(x_2,1) > 1) if(size(x_1,1) > 1) x_1 = sort(x_1); # Sort by x coordinate y(1,:) = x(a,:); # original starting point end if (size(x_2,1) > 1) x_2 = sort(x_2, 'descend'); end x_not = [x_1; x_2]; i = ismember(x,x_not,'rows'); x(i, :) = []; x = [x_1(size(x_1,1),:); x]; x_1(size(x_1, 1),:) = []; N = size(x,1); a = 1; else x_1 = []; x_2 = x(a,:); end d = x - repmat(x(a,:), N, 1); th = d(:,2)./(d(:,1) + d(:,2)); [~, idx0] = ismember(sort(th(th==0)), th); [~, idx1] = ismember(sort(th(th>0)), th); [~, idx2] = ismember(sort(th(th<0)), th); idx = [a; idx0; idx1; idx2]; # I contains the indices of idx in a sorted order. [v i] = sort(idx) then # i==I. [~,I,J]= unique(idx); if(size(I,1) ~= size(J,1)) R = histc(J, 1:size(I,1)); # R(1) will always be 1? idx_sorted = idx(I); r = find(R>1); for ri = r' idx_repeated = idx_sorted(ri); idx(idx==idx_repeated) = find(th==th(idx_sorted(ri))); end end y = [x_1; x(idx,:); x_2;]; endfunction %!demo %! maxInt = 100; %! N = 25; %! %! for i = 1:5 %! x = randi(maxInt, N, 2); %! y = closed_path(x); %! plot(y(:,1), y(:,2), '*'); %! hold on; %! plot(y(:,1), y(:,2)); %! end geometry/inst/geom2d/drawCenteredEdge.m0000644000175000017500000001104712035504503017753 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawCenteredEdge (@var{center}, @var{L}, @var{theta}) ## @deftypefnx {Function File} {@var{h} =} drawCenteredEdge (@var{edge}) ## @deftypefnx {Function File} {@var{h} =} drawCenteredEdge (@dots{}, @var{name},@var{value}) ## Draw an edge centered on a point. ## ## drawCenteredEdge(CENTER, L, THETA) ## Draws an edge centered on point CENTER, with length L, and orientation ## THETA (given in degrees). Input arguments can also be arrays, that must ## all have the same number odf rows. ## ## drawCenteredEdge(EDGE) ## Concatenates edge parameters into a single N-by-4 array, containing: ## [XC YV L THETA]. ## ## drawCenteredEdge(..., NAME, VALUE) ## Also specifies drawing options by using one or several parameter name - ## value pairs (see doc of plot function for details). ## ## H = drawCenteredEdge(...) ## Returns handle(s) to the created edges(s). ## ## @example ## # Draw an ellipse with its two axes ## figure(1); clf; ## center = [50 40]; ## r1 = 30; r2 = 10; ## theta = 20; ## elli = [center r1 r2 theta]; ## drawEllipse(elli, 'linewidth', 2); ## axis([0 100 0 100]); axis equal; ## hold on; ## edges = [center 2*r1 theta ; center 2*r2 theta+90]; ## drawCenteredEdge(edges, 'linewidth', 2, 'color', 'g'); ## @end example ## ## @seealso{edges2d, drawEdge} ## @end deftypefn function varargout = drawCenteredEdge(center, len, theta, varargin) ## process input variables if size(center, 2) == 4 # manage edge in single parameter varargin = [{len, theta}, varargin]; len = center(:, 3); theta = center(:, 4); center = center(:, 1:2); N = size(center, 1); else # parameters given in different arguments # size of data NP = size(center, 1); NL = size(len, 1); ND = size(theta, 1); N = max([NP NL ND]); # ensure all data have same size if N > 1 if NP == 1, center = repmat(center, [N 1]); end if NL == 1, len = repmat(len, [N 1]); end if ND == 1, theta = repmat(theta, [N 1]); end end end # extract drawing options options = varargin(:); ## Draw edges # coordinates of center point xc = center(:, 1); yc = center(:, 2); # convert angle to radians theta = theta * pi / 180; # computation shortcuts cot = cos(theta); sit = sin(theta); # compute starting and ending points x1 = xc - len .* cot / 2; x2 = xc + len .* cot / 2; y1 = yc - len .* sit / 2; y2 = yc + len .* sit / 2; # draw the edges h = zeros(N, 1); for i = 1:N h(i) = plot([x1(i) x2(i)], [y1(i) y2(i)]); end # apply style to edges if ~isempty(options) > 0 for i = 1:N set(h(i), options{:}); end end ## Format output # process output arguments if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom2d/angleSort.m0000644000175000017500000000640512035504503016517 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {varargout =} angleSort (@var{pts}, varargin) ## Sort points in the plane according to their angle to origin ## ## ## PTS2 = angleSort(PTS); ## Computes angle of points with origin, and sort points with increasing ## angles in Counter-Clockwise direction. ## ## PTS2 = angleSort(PTS, PTS0); ## Computes angles between each point of PTS and PT0, which can be ## different from origin. ## ## PTS2 = angleSort(..., THETA0); ## Specifies the starting angle for sorting. ## ## [PTS2, I] = angleSort(...); ## Also returns in I the indices of PTS, such that PTS2 = PTS(I, :); ## ## @seealso{points2d, angles2d, angle2points, normalizeAngle} ## @end deftypefn function varargout = angleSort(pts, varargin) # default values pt0 = [0 0]; theta0 = 0; if length(varargin)==1 var = varargin{1}; if size(var, 2)==1 # specify angle theta0 = var; else pt0 = var; end elseif length(varargin)==2 pt0 = varargin{1}; theta0 = varargin{2}; end n = size(pts, 1); pts2 = pts - repmat(pt0, [n 1]); angle = lineAngle([zeros(n, 2) pts2]); angle = mod(angle - theta0 + 2*pi, 2*pi); [dummy, I] = sort(angle); # format output if nargout<2 varargout{1} = pts(I, :); elseif nargout==2 varargout{1} = pts(I, :); varargout{2} = I; end endfunction %!shared p1,p2,p3,p4,pts,center %! p1 = [0 0]; %! p2 = [10 0]; %! p3 = [10 10]; %! p4 = [0 10]; %! pts = [p1;p2;p3;p4]; %! center = [5 5]; %!test %! expected = pts([3 4 1 2], :); %! assert (expected, angleSort (pts, center), 1e-6); %!assert (pts, angleSort (pts, center, -pi), 1e-6); geometry/inst/geom2d/changelog.txt0000644000175000017500000001324511650352340017075 0ustar juanpijuanpi%% Copyright (c) 2011, INRA %% 2007-2011, David Legland %% 2011 Adapted to Octave by Juan Pablo Carbajal %% %% All rights reserved. %% (simplified BSD License) %% %% Redistribution and use in source and binary forms, with or without %% modification, are permitted provided that the following conditions are met: %% %% 1. Redistributions of source code must retain the above copyright notice, this %% list of conditions and the following disclaimer. %% %% 2. 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. %% %% 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. %% %% The views and conclusions contained in the software and documentation are %% those of the authors and should not be interpreted as representing official %% policies, either expressed or implied, of copyright holder. change log for geom2d geom2d, release 2011.??.?? ========================== New functions - added angleDiff and angleAbsDiff various doc updates geom2d, release 2011.06.30 ========================== New functions - added function rotateVector - added function randomPointInBox Changes - Shape orientation is now represented using degrees - function vectorAngle can now compute the angle between two vectors Bug fixes - enhanced function distancePointEdge - enhanced function isPointOnEdge - enhanced function isParallel - fixed bugs intersectLineCircle geom2d, release 2011.03.21 ========================== New functions - added functions intersectLineCircle and intersectCircles - added functions inertiaEllipse, isPointInEllipse - added function drawBezierCurve - added functions intersectBoxes and mergeBoxes Changes - re-organized the library in three sub-directories: geom2d, polygons2d, and polynomialCurves2d - cleanup of code and doc Bug fixes - several bugs fixed in clipEdge, isPointOnEdge geom2d, release 2010.08.06 ========================== New functions - polygonToRow and rowToPolygon, to convert polygon to a row vector - midPoint, to compute middle points of either 2 points or an edge - added rad2deg and deg2rad, for angle conversions Changes - createCircle and createdirectedCircle are now vectorized, and use different convention for 2 input variables (center + point and circle) - median line has been vectorized Bug fixes - fix bugs in intersectEdges - fix bugs in clipLine - rewrite drawLine using clipLine geom2d, release 2010.07.19 ========================== new functions - isCounterClockwise - intersectRayPolygon - clipRay - reverseEdge - drawBox - fitAffineTransform2d Changes - updated inertiaEllipse - fixed bugs in intersectEdges.m, isParallel.m and isPerpendicular.m - vectorized intersectLinePolygon - fixed precision bug in isPointOnEdge - renamed formatAngle to normalizeAngle - created help file 'angles2d' - fixed bug in weighted centroid computation various bug fixes, and doc updates. geom2d, release 2009.07.22 ========================== new features - new functions for polygons: polygonPoint, polygonSubcurve, polygonLoops, distancePointPolygon, distancePolygons, expandPolygon, polygonSelfIntersections, projPointOnPolygon, isPointInPolygon, reveresPolygon - new functions for polylines: intersectPolylines, polylineSelfIntersections, distancePolylines, isPointOnPolyline, reveresPolyline - projPointOnPolyline can also return the distance of the point to the polyline - function 'edgeToLine' converts an edge to its supporting line Changes - Renamed functions + subcurve -> polylineSubCurve + curveCentroid -> polylineCentroid + invertLine -> reverseLine - Compatibility considerations + parallelLine: changed convention for signed distance various bug fixes, and doc updates. geom2d, release 2009.06.15 ========================== * new features - radicalAxis from 2 circles: - moment of a curve (polyline): curveMoment, curveCMoment, curveCSMoment - new functions for polylines distancePointPolyline, drawPolyline, polylineLength, polylinePoint, polylineSubcurve, projPointOnPolyline * changes - changed some function names to avoid potential name conflicts, and to make function names more explicit: + rotation -> createRotation + scaling -> createScaling + translation -> createRotation + homothecy -> createHomothecy + lineSymmetry -> createLineReflection + inCircle -> isPointInCircle + onCircle -> isPointOnCircle + onEdge -> isPointOnEdge + onLine -> isPointOnLine + onRay -> isPointOnRay + normalize -> normalizeVector * bug fixes - fixed bug in intersectEdges many updates in doc. geometry/inst/geom2d/cartesianLine.m0000644000175000017500000000447312035504503017345 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line} = } cartesianLine (@var{A}, @var{B},@var{C}) ## Create a straight line from cartesian equation coefficients. ## ## Create a line verifying the Cartesian equation: ## @var{A}*x + @var{B}*x + @var{C} = 0; ## ## @seealso{lines2d, createLine} ## @end deftypefn function line = cartesianLine(varargin) if length(varargin)==1 var = varargin{1}; a = var(:,1); b = var(:,2); c = var(:,3); elseif length(varargin)==3 a = varargin{1}; b = varargin{2}; c = varargin{3}; end # normalisation factor d = a.*a + b.*b; x0 = -a.*c./d; y0 = -b.*c./d; theta = atan2(-a, b); dx = cos(theta); dy = sin(theta); line = [x0 y0 dx dy]; endfunction geometry/inst/geom2d/transformLine.m0000644000175000017500000000501612035504503017401 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line2} = } transformLine (@var{line1}, @var{T}) ## Transform a line with an affine transform. ## ## Returns the line @var{line1} transformed with affine transform @var{T}. ## @var{line1} has the form [x0 y0 dx dy], and @var{T} is a transformation ## matrix. ## ## Format of @var{T} can be one of : ## [a b] , [a b c] , or [a b c] ## [d e] [d e f] [d e f] ## [0 0 1] ## ## Also works when @var{line1} is a [Nx4] array of double. In this case, @var{line2} ## has the same size as @var{line1}. ## ## @seealso{lines2d, transforms2d, transformPoint} ## @end deftypefn function dest = transformLine(line, trans) # isolate points points1 = line(:, 1:2); points2 = line(:, 1:2) + line(:, 3:4); # transform points points1 = transformPoint(points1, trans); points2 = transformPoint(points2, trans); dest = createLine(points1, points2); endfunction geometry/inst/geom2d/angleDiff.m0000644000175000017500000000510312035504503016432 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dif} =} angleDiff (@var{angle1}, @var{angle2}) ## Difference between two angles ## ## Computes the signed angular difference between two angles in radians. ## The result is comprised between -PI and +PI. ## ## Example ## A = angleDiff(-pi/4, pi/4) ## A = ## 1.5708 # equal to pi/2 ## A = angleDiff(pi/4, -pi/4) ## A = ## -1.5708 # equal to -pi/2 ## ## @seealso{angles2d, angleAbsDiff} ## @end deftypefn function dif = angleDiff(angle1, angle2) # first, normalization angle1 = normalizeAngle(angle1); angle2 = normalizeAngle(angle2); # compute difference and normalize in [-pi pi] dif = normalizeAngle(angle2 - angle1, 0); endfunction %!test %! dif = angleDiff(0, pi/2); %! assert (pi/2, dif, 1e-6); %!test %! dif = angleDiff(pi/2, 0); %! assert (-pi/2, dif, 1e-6); %!test %! dif = angleDiff(0, 3*pi/2); %! assert (-pi/2, dif, 1e-6); %!test %! dif = angleDiff(3*pi/2, 0); %! assert (pi/2, dif, 1e-6); geometry/inst/geom2d/ellipse2cov.m0000644000175000017500000000652712035504503017015 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{K} = } ellipse2cov (@var{elli}) ## @deftypefnx {Function File} {@var{K} = } ellipse2cov (@var{ra}, @var{rb}) ## @deftypefnx {Function File} {@var{K} = } ellipse2cov (@dots{}, @var{theta}) ## Calculates covariance matrix from ellipse. ## ## If only one input is given, @var{elli} must define an ellipse as described in ## @command{ellipses2d}. ## If two inputs are given, @var{ra} and @var{rb} define the half-lenght of the ## axes. ## If a third input is given, @var{theta} must be the angle of rotation of the ## ellipse in radians, and in counter-clockwise direction. ## ## The output @var{K} contains the covariance matrix define by the ellipse. ## ## Run @code{demo ellipse2cov} to see an example. ## ## @seealso{ellipses2d, cov2ellipse, drawEllipse} ## @end deftypefn function K = ellipse2cov (elli, varargin); ra = 1; rb = 1; theta = 0; switch numel (varargin) case 0 ## ellipse format if numel (elli) != 5 print_usage (); end ra = elli(1,3); rb = elli(1,4); theta = elli(1,5)*pi/180; case 2 ## ra,rb if numel (elli) != 1 print_usage (); end ra = elli; rb = varargin{1}; case 3 ## ra,rb, theta if numel (elli) != 1 print_usage (); end ra = elli; rb = varargin{1}; theta = varargin{2}; otherwise print_usage (); end T = createRotation (theta)(1:2,1:2); K = T*diag([ra rb])*T'; endfunction %!demo %! elli = [0 0 1 3 -45]; %! %! # Create 2D normal random variables with covarinace defined by elli. %! K = ellipse2cov (elli) %! L = chol(K,'lower'); %! u = randn(1e3,2)*L'; %! %! Kn = cov (u) %! %! figure(1) %! plot(u(:,1),u(:,2),'.r'); %! hold on; %! drawEllipse(elli,'linewidth',2); %! hold off %! axis tight geometry/inst/geom2d/drawEllipse.m0000644000175000017500000001141012035504503017024 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawEllipse (@var{elli}) ## @deftypefnx {Function File} {@var{h} = } drawEllipse (@var{xc}, @var{yc}, @var{ra}, @var{rb}) ## @deftypefnx {Function File} {@var{h} = } drawEllipse (@var{xc}, @var{yc}, @var{ra}, @var{rb}, @var{theta}) ## @deftypefnx {Function File} {@var{h} = } drawEllipse (@dots{}, @var{param}, @var{value}) ## Draw an ellipse on the current axis. ## ## drawEllipse(ELLI); ## Draws the ellipse ELLI in the form [XC YC RA RB THETA], with center ## (XC, YC), with main axis of half-length RA and RB, and orientation ## THETA in degrees counted counter-clockwise. ## Puts all parameters into one single array. ## ## drawEllipse(XC, YC, RA, RB); ## drawEllipse(XC, YC, RA, RB, THETA); ## Specifies ellipse parameters as separate arguments (old syntax). ## ## drawEllipse(..., NAME, VALUE); ## Specifies drawing style of ellipse, see the help of plot function. ## ## H = drawEllipse(...); ## Also returns handles to the created line objects. ## ## -> Parameters can also be arrays. In this case, all arrays are supposed ## to have the same size. ## ## Example: ## @example ## # Draw an ellipse centered in [50 50], with semi major axis length of ## # 40, semi minor axis length of 20, and rotated by 30 degrees. ## figure(1); clf; hold on; ## drawEllipse([50 50 40 20 30]); ## axis equal; ## @end example ## ## @seealso{ellipses2d, drawCircle, drawEllipseArc, ellipseAsPolygon} ## @end deftypefn function varargout = drawEllipse(varargin) # extract dawing style strings styles = {}; for i = 1:length(varargin) if ischar(varargin{i}) styles = varargin(i:end); varargin(i:end) = []; break; end end # extract ellipse parameters if length(varargin)==1 # ellipse is given in a single array ellipse = varargin{1}; x0 = ellipse(:, 1); y0 = ellipse(:, 2); a = ellipse(:, 3); b = ellipse(:, 4); if length(ellipse)>4 theta = ellipse(:, 5); else theta = zeros(size(x0)); end elseif length(varargin)>=4 # ellipse parameters given as separate arrays x0 = varargin{1}; y0 = varargin{2}; a = varargin{3}; b = varargin{4}; if length(varargin)>4 theta = varargin{5}; else theta = zeros(size(x0)); end else error('drawEllipse: incorrect input arguments'); end ## Process drawing of a set of ellipses # angular positions of vertices t = linspace(0, 2*pi, 145); # compute position of points to draw each ellipse h = zeros(length(x0), 1); for i = 1:length(x0) # pre-compute rotation angles (given in degrees) cot = cosd(theta(i)); sit = sind(theta(i)); # compute position of points used to draw current ellipse xt = x0(i) + a(i) * cos(t) * cot - b(i) * sin(t) * sit; yt = y0(i) + a(i) * cos(t) * sit + b(i) * sin(t) * cot; # stores handle to graphic object h(i) = plot(xt, yt, styles{:}); end # return handles if required if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom2d/distancePointEdge.m0000644000175000017500000001176312035504503020155 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dist} = } distancePointEdge (@var{point}, @var{edge}) ## @deftypefnx {Function File} {@var{dist} = } distancePointEdge (@dots{}, @var{opt}) ## @deftypefnx {Function File} {[@var{dist} @var{pos}]= } distancePointEdge (@dots{}) ## Minimum distance between a point and an edge ## ## Return the euclidean distance between edge @var{edge} and point @var{point}. ## @var{edge} has the form: [x1 y1 x2 y2], and @var{point} is [x y]. ## If @var{edge} is Ne-by-4 and @var{point} is Np-by-2, then @var{dist} is ## Np-by-Ne, where each row contains the distance of each point to all the edges. ## ## If @var{opt} is true (or equivalent), the optput is cmpatible with the original function: ## @table @samp ## @item 1 ## If @var{point} is 1-by-2 array, the result is Ne-by-1 array computed for each edge. ## @item 2 ## If @var{edge} is a 1-by-4 array, the result is Np-by-1 computed for each point. ## @item 3 ## If both @var{point} and @var{edge} are array, they must have the same number of ## rows, and the result is computed for each couple @code{@var{point}(i,:),@var{edge}(i,:)}. ## @end table ## ## If the the second output argument @var{pos} is requested, the function also ## returns the position of closest point on the edge. @var{pos} is comprised ## between 0 (first point) and 1 (last point). ## ## @seealso{edges2d, points2d, distancePoints, distancePointLine} ## @end deftypefn ## Rewritten to accept different numbers of points and edges. ## 2012 - Juan Pablo Carbajal function [dist, tp] = distancePointEdge(point, edge, opt=[]) Np = size (point,1); Ne = size (edge,1); edge = edge.'; # direction vector of each edge dx = edge(3,:) - edge(1,:); dy = edge(4,:) - edge(2,:); # compute position of points projected on the supporting line # (Size of tp is the max number of edges or points) delta = dx .* dx + dy .* dy; mask = delta < eps; delta(mask) = 1; warning ('off', 'Octave:broadcast'); tp = ((point(:, 1) - edge(1, :)) .* dx + (point(:, 2) - edge(2, :)) .* dy) ./ delta; tp(:,mask) = 0; # change position to ensure projected point is located on the edge tp(tp < 0) = 0; tp(tp > 1) = 1; # coordinates of projected point p0x = (edge(1,:) + tp .* dx); p0y = (edge(2,:) + tp .* dy); # compute distance between point and its projection on the edge dist = sqrt((point(:,1) - p0x) .^ 2 + (point(:,2) - p0y) .^ 2); warning ('on', 'Octave:broadcast'); ## backwards compatibility if opt if Np != Ne && (Ne != 1 && Np !=1) error ("geometry:InvalidArgument", ... "Sizes must be equal or one of the inputs must be 1-by-N array."); end if Np == Ne dist = diag(dist)(:); tp = diag(tp)(:); elseif Np == 1 dist = dist.'; tp = tp.'; end end endfunction ## Original code ##tp = ((point(:, 1) - edge(:, 1)) .* dx + (point(:, 2) - edge(:, 2)) .* dy) ./ delta; ### ensure degenerated edges are correclty processed (consider the first ### vertex is the closest) ##if Ne > 1 ## tp(delta < eps) = 0; ##elseif delta < eps ## tp(:) = 0; ##end ### change position to ensure projected point is located on the edge ##tp(tp < 0) = 0; ##tp(tp > 1) = 1; ### coordinates of projected point ##p0 = [edge(:,1) + tp .* dx, edge(:,2) + tp .* dy]; ### compute distance between point and its projection on the edge ##dist = sqrt((point(:,1) - p0(:,1)) .^ 2 + (point(:,2) - p0(:,2)) .^ 2); geometry/inst/geom2d/angleAbsDiff.m0000644000175000017500000000464512035504503017072 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dif} =} angleAbsDiff (@var{angle1}, @var{angle2}) ## Computes the absolute angular difference between two angles in radians. ## The result is comprised between 0 and pi. ## ## @example ## A = angleAbsDiff(pi/2, pi/3) ## A = ## 0.5236 # equal to pi/6 ## @end example ## ## @seealso{angles2d, angleDiff} ## @end deftypefn function dif = angleAbsDiff(angle1, angle2) # first, normalization angle1 = normalizeAngle(angle1); angle2 = normalizeAngle(angle2); # compute difference and normalize dif = normalizeAngle(angle1 - angle2); dif = min(dif, 2*pi - dif); endfunction %!shared xp %! xp = pi/2; %!assert (xp, angleAbsDiff (pi/2, 0), 1e-6); %!assert (xp, angleAbsDiff (0, pi/2), 1e-6); %!assert (xp, angleAbsDiff (0, 3*pi/2), 1e-6); %!assert (xp, angleAbsDiff (3*pi/2, 0), 1e-6); geometry/inst/geom2d/createRay.m0000644000175000017500000000677112035504503016506 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} { @var{ray} = } createRay (@var{point}, @var{angle}) ## @deftypefnx {Function File} { @var{ray} = } createRay (@var{x0},@var{y0}, @var{angle}) ## @deftypefnx {Function File} { @var{ray} = } createRay (@var{p1}, @var{p2}) ## Create a ray (half-line), from various inputs. ## ## A Ray is represented in a parametric form: [x0 y0 dx dy]. ## x = x0 + t*dx ## y = y0 + t*dy; ## for all t>0. ## ## @var{point} is a Nx2 array giving the starting point of the ray, and @var{angle} is the ## orientation of the ray respect to the positive x-axis. The ray origin can be specified with 2 input arguments @var{x0},@var{y0}. ## ## If two points @var{p1}, @var{p2} are given, creates a ray starting from point @var{p1} and going in the direction of point ## @var{p2}. ## ## Example ## @example ## origin = [3 4]; ## theta = pi/6; ## ray = createRay(origin, theta); ## axis([0 10 0 10]); ## drawRay(ray); ## @end example ## ## @seealso{rays2d, createLine, points2d} ## @end deftypefn function ray = createRay(varargin) if length(varargin)==2 p0 = varargin{1}; arg = varargin{2}; if size(arg, 2)==1 # second input is the ray angle ray = [p0 cos(arg) sin(arg)]; else # second input is another point ray = [p0 arg-p0]; end elseif length(varargin)==3 x = varargin{1}; y = varargin{2}; theta = varargin{3}; ray = [x y cos(theta) sin(theta)]; else error("Wrong number of arguments in 'createRay'. "); end endfunction %!shared p1,p2,ray %! p1 = [1 1]; %! p2 = [2 3]; %! ray = createRay(p1, p2); %!assert (p1, ray(1,1:2), 1e-6); %!assert (p2-p1, ray(1,3:4), 1e-6); %!shared p1,p2,ray %! p1 = [1 1;1 1]; %! p2 = [2 3;2 4]; %! ray = createRay(p1, p2); %!assert (2, size(ray, 1)); %!assert (p1, ray(:,1:2), 1e-6); %!assert (p2-p1, ray(:,3:4), 1e-6); geometry/inst/geom2d/isPointOnLine.m0000644000175000017500000000523212035504503017310 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPointOnLine (@var{point}, @var{line}) ## Test if a point belongs to a line ## ## B = isPointOnLine(POINT, LINE) ## with POINT being [xp yp], and LINE being [x0 y0 dx dy]. ## Returns 1 if point lies on the line, 0 otherwise. ## ## If POINT is an N*2 array of points, B is a N*1 array of booleans. ## ## If LINE is a N*4 array of line, B is a 1*N array of booleans. ## ## @seealso {lines2d, points2d, isPointOnEdge, isPointOnRay, angle3Points} ## @end deftypefn function b = isPointOnLine(point, line, varargin) # extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end # number of lines and of points Nl = size(line, 1); Np = size(point, 1); # adapt the size of inputs x0 = repmat(line(:,1)', Np, 1); y0 = repmat(line(:,2)', Np, 1); dx = repmat(line(:,3)', Np, 1); dy = repmat(line(:,4)', Np, 1); xp = repmat(point(:,1), 1, Nl); yp = repmat(point(:,2), 1, Nl); # test if lines are colinear b = abs((xp-x0).*dy-(yp-y0).*dx)./hypot(dx, dy) < tol; endfunction geometry/inst/geom2d/randomPointInBox.m0000644000175000017500000000554112035504503020013 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{points} =} randomPointInBox (@var{box}) ## @deftypefnx {Function File} {@var{points} =} randomPointInBox (@var{box}, @var{n}) ## Generate random points within a box. ## ## Generate a random point within the box @var{box}. The result is a 1-by-2 row ## vector. If @var{n} is given, generates @var{n} points. The result is a ## @var{n}-by-2 array. ## ## Example ## ## @example ## # draw points within a box ## box = [10 80 20 60]; ## pts = randomPointInBox(box, 500); ## figure(1); clf; hold on; ## drawBox(box); ## drawPoint(pts, '.'); ## axis('equal'); ## axis([0 100 0 100]); ## @end example ## ## @seealso{edges2d, boxes2d, clipLine} ## @end deftypefn function points = randomPointInBox(box, N=1, varargin) # extract box bounds xmin = box(1); xmax = box(2); ymin = box(3); ymax = box(4); # compute size of box dx = xmax - xmin; dy = ymax - ymin; # compute point coordinates points = [rand(N, 1)*dx+xmin , rand(N, 1)*dy+ymin]; endfunction %!demo %! # draw points within a box %! bb = [10 80 20 60]; %! pts = randomPointInBox(bb, 500); %! figure(1); clf; hold on; %! drawBox(bb); %! drawPoint(pts, '.'); %! axis equal %! axis([0 100 0 100]); geometry/inst/geom2d/ellipseAsPolygon.m0000644000175000017500000000615312035504503020052 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p} = } ellipseAsPolygon (@var{ell}, @var{n}) ## Convert an ellipse into a series of points ## ## P = ellipseAsPolygon(ELL, N); ## converts ELL given as [x0 y0 a b] or [x0 y0 a b theta] into a polygon ## with N edges. The result P is (N+1)-by-2 array containing coordinates ## of the N+1 vertices of the polygon. ## The resulting polygon is closed, i.e. the last point is the same as the ## first one. ## ## P = ellipseAsPolygon(ELL); ## Use a default number of edges equal to 72. This result in one piont for ## each 5 degrees. ## ## [X Y] = ellipseAsPolygon(...); ## Return the coordinates o fvertices in two separate arrays. ## ## @seealso{ellipses2d, circleAsPolygon, rectAsPolygon, drawEllipse} ## @end deftypefn function varargout = ellipseAsPolygon(ellipse, N) # default value for N if nargin < 2 N = 72; end # angle of ellipse theta = 0; if size(ellipse, 2) > 4 theta = ellipse(:,5); end # get ellipse parameters xc = ellipse(:,1); yc = ellipse(:,2); a = ellipse(:,3); b = ellipse(:,4); # create time basis t = linspace(0, 2*pi, N+1)'; # pre-compute trig functions (angles is in degrees) cot = cosd(theta); sit = sind(theta); # position of points x = xc + a * cos(t) * cot - b * sin(t) * sit; y = yc + a * cos(t) * sit + b * sin(t) * cot; # format output depending on number of a param. if nargout == 1 varargout = {[x y]}; elseif nargout == 2 varargout = {x, y}; end endfunction geometry/inst/geom2d/beltproblem.m0000644000175000017500000001157212035504503017071 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{tangent},@var{inner}] = } beltproblem (@var{c}, @var{r}) ## Finds the four lines tangent to two circles with given centers and radii. ## ## The function solves the belt problem in 2D for circles with center @var{c} and ## radii @var{r}. ## ## @strong{INPUT} ## @table @var ## @item c ## 2-by-2 matrix containig coordinates of the centers of the circles; one row per circle. ## @item r ## 2-by-1 vector with the radii of the circles. ##@end table ## ## @strong{OUPUT} ## @table @var ## @item tangent ## 4-by-4 matrix with the points of tangency. Each row describes a segment(edge). ## @item inner ## 4-by-2 vector with the point of intersection of the inner tangents (crossed belts) ## with the segment that joins the centers of the two circles. If ## the i-th edge is not an inner tangent then @code{inner(i,:)=[NaN,NaN]}. ## @end table ## ## Example: ## ## @example ## c = [0 0;1 3]; ## r = [1 0.5]; ## [T inner] = beltproblem(c,r) ## @result{} T = ## -0.68516 0.72839 1.34258 2.63581 ## 0.98516 0.17161 0.50742 2.91419 ## 0.98675 -0.16225 1.49338 2.91888 ## -0.88675 0.46225 0.55663 3.23112 ## ## @result{} inner = ## 0.66667 2.00000 ## 0.66667 2.00000 ## NaN NaN ## NaN NaN ## ## @end example ## ## @seealso{edges2d} ## @end deftypefn function [edgeTan inner] = beltproblem(c,r) x0 = [c(1,1) c(1,2) c(2,1) c(2,2)]; r0 = r([1 1 2 2]); middleEdge = createEdge(c(1,:),c(2,:)); ind0 = [1 0 1 0; 0 1 1 0; 1 1 1 0; -1 0 1 0; 0 -1 1 0; -1 -1 1 0;... 1 0 0 1; 0 1 0 1; 1 1 0 1; -1 0 0 1; 0 -1 0 1; -1 -1 0 1;... 1 0 1 1; 0 1 1 1; 1 1 1 1; -1 0 1 1; 0 -1 1 1; -1 -1 1 1;... 1 0 -1 0; 0 1 -1 0; 1 1 -1 0; -1 0 -1 0; 0 -1 -1 0; -1 -1 -1 0;... 1 0 0 -1; 0 1 0 -1; 1 1 0 -1; -1 0 0 -1; 0 -1 0 -1; -1 -1 0 -1;... 1 0 -1 -1; 0 1 -1 -1; 1 1 -1 -1; -1 0 -1 -1; 0 -1 -1 -1; -1 -1 -1 -1]; nInit = size(ind0,1); ir = randperm(nInit); edgeTan = zeros(4,4); inner = zeros(4,2); nSol = 0; i=1; ## Solve for 2 different lines while nSol<4 && i 1e-6); end if all(notequal) nSol = nSol+1; edgeTan(nSol,:) = createEdge(sol(1:2),sol(3:4)); # Find innerTangent inner(nSol,:) = intersectEdges(middleEdge,edgeTan(nSol,:)); end i = i+1; end endfunction function res = belt(x,c,r) res = zeros(4,1); res(1,1) = (x(3:4) - c(2,1:2))*(x(3:4) - x(1:2))'; res(2,1) = (x(1:2) - c(1,1:2))*(x(3:4) - x(1:2))'; res(3,1) = sumsq(x(1:2) - c(1,1:2)) - r(1)^2; res(4,1) = sumsq(x(3:4) - c(2,1:2)) - r(2)^2; end %!demo %! c = [0 0;1 3]; %! r = [1 0.5]; %! [T inner] = beltproblem(c,r) %! %! figure(1) %! clf %! h = drawEdge(T); %! set(h(find(~isnan(inner(:,1)))),'color','r'); %! set(h,'linewidth',2); %! hold on %! drawCircle([c(1,:) r(1); c(2,:) r(2)],'linewidth',2); %! axis tight %! axis equal %! %! # ------------------------------------------------------------------- %! # The circles with the tangents edges are plotted. The solution with %! # crossed belts (inner tangets) is shown in red. geometry/inst/geom2d/inertiaEllipse.m0000644000175000017500000000656012035504503017534 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{ell} = } inertiaEllipse (@var{pts}) ## Inertia ellipse of a set of points ## ## ELL = inertiaEllipse(PTS); ## where PTS is a N*2 array containing coordinates of N points, computes ## the inertia ellispe of the set of points. ## ## The result has the form: ## ELL = [XC YC A B THETA], ## with XC and YC being the center of mass of the point set, A and B are ## the lengths of the inertia ellipse (see below), and THETA is the angle ## of the main inertia axis with the horizontal (counted in degrees ## between 0 and 180). ## A and B are the standard deviations of the point coordinates when ## ellipse is aligned with the inertia axes. ## ## @example ## pts = randn(100, 2); ## pts = transformPoint(pts, createScaling(5, 2)); ## pts = transformPoint(pts, createRotation(pi/6)); ## pts = transformPoint(pts, createTranslation(3, 4)); ## ell = inertiaEllipse(pts); ## figure(1); clf; hold on; ## drawPoint(pts); ## drawEllipse(ell, 'linewidth', 2, 'color', 'r'); ## @end example ## ## @seealso{ellipses2d, drawEllipse} ## @end deftypefn function ell = inertiaEllipse(points) # ellipse center xc = mean(points(:,1)); yc = mean(points(:,2)); # recenter points x = points(:,1) - xc; y = points(:,2) - yc; # number of points n = size(points, 1); # inertia parameters Ixx = sum(x.^2) / n; Iyy = sum(y.^2) / n; Ixy = sum(x.*y) / n; # compute ellipse semi-axis lengths common = sqrt( (Ixx - Iyy)^2 + 4 * Ixy^2); ra = sqrt(2) * sqrt(Ixx + Iyy + common); rb = sqrt(2) * sqrt(Ixx + Iyy - common); # compute ellipse angle in degrees theta = atan2(2 * Ixy, Ixx - Iyy) / 2; theta = rad2deg(theta); # create the resulting inertia ellipse ell = [xc yc ra rb theta]; endfunction geometry/inst/geom2d/triangleGrid.m0000644000175000017500000000501312035504503017166 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pts} = } triangleGrid (@var{bounds}, @var{origin}, @var{size}) ## Generate triangular grid of points in the plane. ## ## usage ## PTS = triangleGrid(BOUNDS, ORIGIN, SIZE) ## generate points, lying in the window defined by BOUNDS, given in form ## [xmin ymin xmax ymax], starting from origin with a constant step equal ## to size. ## SIZE is constant and is equals to the length of the sides of each ## triangles. ## ## TODO: add possibility to use rotated grid ## ## @end deftypefn function varargout = triangleGrid(bounds, origin, size, varargin) dx = size(1); dy = size(1)*sqrt(3); # consider two square grids with different centers pts1 = squareGrid(bounds, origin, [dx dy], varargin{:}); pts2 = squareGrid(bounds, origin + [dx dy]/2, [dx dy], varargin{:}); # gather points pts = [pts1;pts2]; # process output if nargout>0 varargout{1} = pts; end endfunction geometry/inst/geom2d/createTranslation.m0000644000175000017500000000507512035504503020245 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } createTranslation (@var{vector}) ## @deftypefnx {Function File} {@var{T} = } createTranslation (@var{dx},@var{dy}) ## Create the 3*3 matrix of a translation. ## ## Returns the matrix corresponding to a translation by the vector [@var{dx} @var{dy}]. ## The components can be given as two arguments. ## The returned matrix has the form : ## [1 0 TX] ## [0 1 TY] ## [0 0 1] ## ## @seealso{transforms2d, transformPoint, createRotation, createScaling} ## @end deftypefn function trans = createTranslation(varargin) # process input arguments if isempty(varargin) tx = 0; ty = 0; elseif length(varargin)==1 var = varargin{1}; tx = var(1); ty = var(2); else tx = varargin{1}; ty = varargin{2}; end # create the matrix representing the translation trans = [1 0 tx ; 0 1 ty ; 0 0 1]; endfunction %!test %! trans = createTranslation(2, 3); %! assert (trans, [1 0 2;0 1 3;0 0 1], 1e-6); geometry/inst/geom2d/isLeftOriented.m0000644000175000017500000000444512035504503017503 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isLeftOriented (@var{point}, @var{line}) ## Test if a point is on the left side of a line ## ## B = isLeftOriented(POINT, LINE); ## Returns TRUE if the point lies on the left side of the line with ## respect to the line direction. ## ## @seealso{lines2d, points2d, isCounterClockwise, isPointOnLine, distancePointLine} ## @end deftypefn function b = isLeftOriented(point, line) Nl = size(line, 1); Np = size(point, 1); x0 = repmat(line(:,1)', Np, 1); y0 = repmat(line(:,2)', Np, 1); dx = repmat(line(:,3)', Np, 1); dy = repmat(line(:,4)', Np, 1); xp = repmat(point(:,1), 1, Nl); yp = repmat(point(:,2), 1, Nl); b = (xp-x0).*dy-(yp-y0).*dx < 0; endfunction geometry/inst/geom2d/lines2d.m0000644000175000017500000000517012035504503016117 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} lines2d () ## Description of functions operating on planar lines. # # The term 'line' refers to a planar straight line, which is an unbounded # curve. Line segments defined between 2 points, which are bounded, are # called 'edge', and are presented in file 'edges2d'. # # A straight line is defined by a point (its origin), and a vector (its # direction). The different parameters are bundled into a row vector: # LINE = [x0 y0 dx dy]; # # A line contains all points (x,y) such that: # x = x0 + t*dx # y = y0 + t*dy; # for all t between -infinity and +infinity. # # @seealso{points2d, vectors2d, edges2d, rays2d # createLine, cartesianLine, medianLine, edgeToLine # orthogonalLine, parallelLine, bisector, radicalAxis # lineAngle, linePosition, projPointOnLine # isPointOnLine, distancePointLine, isLeftOriented # intersectLines, intersectLineEdge, clipLine # invertLine, transformLine, drawLine # lineFit} ## @end deftypefn function lines2d(varargin) help('lines2d'); endfunction geometry/inst/geom2d/orthogonalLine.m0000644000175000017500000000452412035504503017545 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{perp} = } orthogonalLine (@var{line}, @var{point}) ## Create a line orthogonal to another one. # # Returns the line orthogonal to the line @var{line} and going through the # point given by @var{point}. Directed angle from @var{line} to @var{perp} is pi/2. # @var{line} is given as [x0 y0 dx dy] and @var{point} is [xp yp]. # # @seealso{lines2d, parallelLine} ## @end deftypefn function res = orthogonalLine(line, point) N = max(size(point, 1), size(line, 1)); if size(point, 1)>1 res = point; else res = ones(N, 1)*point; end if size(line, 1)>1 res(:,3) = -line(:,4); res(:,4) = line(:,3); else res(:,3) = -ones(N,1)*line(4); res(:,4) = ones(N,1)*line(3); end endfunction geometry/inst/geom2d/createEdge.m0000644000175000017500000001164512035504503016613 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{edge} = } createEdge (@var{p1}, @var{p2}) ## @deftypefnx {Function File} {@var{edge} = } createEdge (@var{x0}, @var{y0}, @var{dx}, @var{dy}) ## @deftypefnx {Function File} {@var{edge} = } createEdge (@var{param}) ## @deftypefnx {Function File} {@var{edge} = } createEdge (@var{line}, @var{d}) ## Create an edge between two points, or from a line. ## ## The internal format for edge representation is given by coordinates of ## two points : [x1 y1 x2 y2]. ## This function can serve as a line to edge converter. ## ## ## Returns the edge between the two given points @var{p1} and @var{p2}. ## ## Returns the edge going through point (@var{x0}, @var{y0}) and with direction ## vector (@var{dx},@var{dy}). ## ## When @var{param} is an array of 4 values, creates the edge going through the ## point (param(1) param(2)), and with direction vector given by ## (param(3) param(4)). ## ## When @var{line} is given, creates the edge contained in @var{line}, with same ## direction and start point, but with length given by @var{d}. ## ## ## Note: in all cases, parameters can be vertical arrays of the same ## dimension. The result is then an array of edges, of dimensions [N*4]. ## ## @seealso{edges2d, lines2d, drawEdge, clipEdge} ## @end deftypefn function edge = createEdge(varargin) if length(varargin)==1 # Only one input parameter. It can be : # - line angle # - array of four parameters # TODO : add control for arrays of lines. var = varargin{1}; if size(var, 2)==4 # 4 parameters of the line in a single array. #edge = var; edge = zeros(size(var)); edge(:, 1:2) = var(:,1:2); edge(:, 3:4) = edge(:, 1:2)+var(:,3:4); elseif size(var, 2)==1 # 1 parameter : angle of the line, going through origin. edge = [zeros(size(var,1)) zeros(size(var,1)) cos(var) sin(var)]; else error('wrong number of dimension for arg1 : can be 1 or 4'); end elseif length(varargin)==2 # 2 input parameters. They can be : # - 2 points, then 2 arrays of 1*2 double, # - a line, and a distance. v1 = varargin{1}; v2 = varargin{2}; if size(v1, 2)==2 # first input parameter is first point, and second input is the # second point. #edge = [v1(:,1), v1(:,2), v2(:,1), v2(:,2)]; edge = [v1 v2]; else # first input parameter is a line, and second one a distance. angle = atan2(v1(:,4), v1(:,3)); edge = [v1(:,1), v1(:,2), v1(:,1)+v2.*cos(angle), v1(:,2)+v2.*sin(angle)]; end elseif length(varargin)==3 # 3 input parameters : # first one is a point belonging to the line, # second and third ones are direction vector of the line (dx and dy). p = varargin{1}; edge = [p(:,1) p(:,2) p(:,1)+varargin{2} p(:,2)+varargin{3}]; elseif length(varargin)==4 # 4 input parameters : # they are x0, y0 (point belonging to line) and dx, dy (direction # vector of the line). # All parameters should have the same size. edge = [varargin{1} varargin{2} varargin{1}+varargin{3} varargin{2}+varargin{4}]; else error('Wrong number of arguments in ''createLine'' '); end endfunction geometry/inst/geom2d/drawCircleArc.m0000644000175000017500000000761212035504503017267 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawCircleArc (@var{xc}, @var{yc}, @var{r}, @var{start}, @var{end}) ## @deftypefnx {Function File} {@var{h} = } drawCircleArc (@var{arc}) ## @deftypefnx {Function File} {@var{h} = } drawCircleArc (@dots{}, @var{param}, @var{value}) ## Draw a circle arc on the current axis ## ## drawCircleArc(XC, YC, R, START, EXTENT); ## Draws circle with center (XC, YC), with radius R, starting from angle ## START, and with angular extent given by EXTENT. START and EXTENT angles ## are given in degrees. ## ## drawCircleArc(ARC); ## Puts all parameters into one single array. ## ## drawCircleArc(..., PARAM, VALUE); ## specifies plot properties by using one or several parameter name-value ## pairs. ## ## H = drawCircleArc(...); ## Returns a handle to the created line object. ## ## @example ## # Draw a red thick circle arc ## arc = [10 20 30 -120 240]; ## figure; ## axis([-50 100 -50 100]); ## hold on ## drawCircleArc(arc, 'LineWidth', 3, 'Color', 'r') ## @end example ## ## @seealso{circles2d, drawCircle, drawEllipse} ## @end deftypefn function varargout = drawCircleArc(varargin) if nargin == 0 error('Need to specify circle arc'); end circle = varargin{1}; if size(circle, 2) == 5 x0 = circle(:,1); y0 = circle(:,2); r = circle(:,3); start = circle(:,4); extent = circle(:,5); varargin(1) = []; elseif length(varargin) >= 5 x0 = varargin{1}; y0 = varargin{2}; r = varargin{3}; start = varargin{4}; extent = varargin{5}; varargin(1:5) = []; else error('drawCircleArc: please specify center, radius and angles of circle arc'); end # convert angles in radians t0 = deg2rad(start); t1 = t0 + deg2rad(extent); # number of line segments N = 60; # initialize handles vector h = zeros(length(x0), 1); # draw each circle arc individually for i = 1:length(x0) # compute basis t = linspace(t0(i), t1(i), N+1)'; # compute vertices coordinates xt = x0(i) + r(i)*cos(t); yt = y0(i) + r(i)*sin(t); # draw the circle arc h(i) = plot(xt, yt, varargin{:}); end if nargout > 0 varargout = {h}; end endfunction geometry/inst/geom2d/normalizeVector.m0000644000175000017500000000466212035504503017747 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{vn} = } normalizeVector (@var{v}) ## Normalize a vector to have norm equal to 1 ## ## Returns the normalization of vector @var{v}, such that ||@var{v}|| = 1. ## @var{v} can be either a row or a column vector. ## ## When @var{v} is a MxN array, normalization is performed for each row of the ## array. ## ## Example: ## ## @example ## vn = normalizeVector([3 4]) ## vn = ## 0.6000 0.8000 ## vectorNorm(vn) ## ans = ## 1 ## @end example ## ## @seealso{vectors2d, vectorNorm} ## @end deftypefn function vn = normalizeVector(v) dim = size(v); if dim(1)==1 || dim(2)==1 vn = v / sqrt(sum(v.^2)); else #same as: vn = v./repmat(sqrt(sum(v.*v, 2)), [1 dim(2)]); vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); end endfunction %!assert (1,vectorNorm (normalizeVector ([3 4]))) geometry/inst/geom2d/angles2d.m0000644000175000017500000000440712035504503016260 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} angles2d () ## Description of functions for manipulating angles ## ## Angles are normalized in an interval of width 2*PI. Most geom2d ## functions return results in the [0 2*pi] interval, but it can be ## convenient to consider the [-pi pi] interval as well. See the ## normalizeAngle function to switch between conventions. ## ## Angles are usually oriented. The default orientation is the CCW ## (Counter-Clockwise) orientation. ## ## @seealso{angle2Points, angle3Points, angleAbsDiff, normalizeAngle, vectorAngle, ## angleDiff, angleSort, lineAngle, edgeAngle, deg2rad, rad2deg} ## @end deftypefn function angles2d help('angles2d'); endfunction geometry/inst/geom2d/parallelLine.m0000644000175000017500000000523112035504503017161 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{res} = } parallelLine (@var{line}, @var{point}) ## @deftypefnx {Function File} {@var{res} = } parallelLine (@var{line}, @var{dist}) ## Create a line parallel to another one. ## ## Returns the line with same direction vector than @var{line} and going through ## the point given by @var{point}. ## @var{line} is given as [x0 y0 dx dy] and @var{point} is [xp yp]. ## ## Uses relative distance to specify position. The new line will be ## located at distance @var{dist}, counted positive in the right side of @var{line} ## and negative in the left side. ## ## @seealso{lines2d, orthogonalLine, distancePointLine} ## @end deftypefn function res = parallelLine(line, point) if size(point, 1)==1 # use a distance. Compute position of point located at distance DIST on # the line orthogonal to the first one. point = pointOnLine([line(:,1) line(:,2) line(:,4) -line(:,3)], point); end # normal case: compute line through a point with given direction res = zeros(1, 4); res(1:2) = point; res(3:4) = line(3:4); endfunction geometry/inst/geom2d/cov2ellipse.m0000644000175000017500000000617012055124512017007 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{ellipse} = } cov2ellipse (@var{K}) ## @deftypefnx {Function File} {[@var{ra} @var{rb} @var{theta}] = } cov2ellipse (@var{K}) ## @deftypefnx {Function File} {@dots{} = } cov2ellipse (@dots{}, @samp{tol},@var{tol}) ## Calculates ellipse parameters from covariance matrix. ## ## @var{K} must be symmetric positive (semi)definite. The optional argument ## @samp{tol} sets the tolerance for the verification of the ## positive-(semi)definiteness of the matrix @var{K} (see @command{isdefinite}). ## ## If only one output argument is supplied a vector defining a ellipse is returned ## as defined in @command{ellipses2d}. Otherwise the angle @var{theta} is given ## in radians. ## ## Run @code{demo cov2ellipse} to see an example. ## ## @seealso{ellipses2d, cov2ellipse, drawEllipse} ## @end deftypefn function varargout = cov2ellipse (K, varargin); parser = inputParser (); parser.FunctionName = "cov2ellipse"; parser = addParamValue (parser,'Tol', 100*eps*norm (K, "fro"), @(x)x>0); parser = parse(parser,varargin{:}); if isdefinite (K,parser.Results.Tol) == -1 print_usage end [R S W] = svd (K); theta = atan2 (R(2,1), R(1,1)); v = sqrt (diag(S))'; if nargout == 1 varargout{1} = [0 0 v theta*180/pi]; elseif nargout == 3 varargout{1} = v(1); varargout{2} = v(2); varargout{3} = theta; end endfunction %!demo %! K = [2 1; 1 2]; %! L = chol(K,'lower'); %! u = randn(1e3,2)*L'; %! %! elli = cov2ellipse (K) %! %! figure(1) %! plot(u(:,1),u(:,2),'.r'); %! hold on; %! drawEllipse(elli,'linewidth',2); %! hold off %! axis tight geometry/inst/geom2d/isPointOnEdge.m0000644000175000017500000002231212035504503017263 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPointOnEdge (@var{point}, @var{edge}) ## @deftypefnx {Function File} {@var{b} = } isPointOnEdge (@var{point}, @var{edge}, @var{tol}) ## @deftypefnx {Function File} {@var{b} = } isPointOnEdge (@var{point}, @var{edgearray}) ## @deftypefnx {Function File} {@var{b} = } isPointOnEdge (@var{pointarray}, @var{edgearray}) ## Test if a point belongs to an edge. # # with @var{point} being [xp yp], and @var{edge} being [x1 y1 x2 y2], returns TRUE if # the point is located on the edge, and FALSE otherwise. # # Specify an optilonal tolerance value @var{tol}. The tolerance is given as a # fraction of the norm of the edge direction vector. Default is 1e-14. # # When one of the inputs has several rows, return the result of the test # for each element of the array tested against the single parameter. # # When both @var{pointarray} and @var{edgearray} have the same number of rows, # returns a column vector with the same number of rows. # When the number of rows are different and both greater than 1, returns # a Np-by-Ne matrix of booleans, containing the result for each couple of # point and edge. # # @seealso{edges2d, points2d, isPointOnLine} ## @end deftypefn function b = isPointOnEdge(point, edge, varargin) # extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end # number of edges and of points Np = size(point, 1); Ne = size(edge, 1); # adapt size of inputs if needed, and extract elements for computation if Np == Ne # When the number of points and edges is the same, the one-to-one test # will be computed, so there is no need to repeat matrices dx = edge(:,3) - edge(:,1); dy = edge(:,4) - edge(:,2); lx = point(:,1) - edge(:,1); ly = point(:,2) - edge(:,2); elseif Np == 1 # one point, several edges dx = edge(:, 3) - edge(:, 1); dy = edge(:, 4) - edge(:, 2); lx = point(ones(Ne, 1), 1) - edge(:, 1); ly = point(ones(Ne, 1), 2) - edge(:, 2); elseif Ne == 1 # several points, one edge dx = (edge(3) - edge(1)) * ones(Np, 1); dy = (edge(4) - edge(2)) * ones(Np, 1); lx = point(:, 1) - edge(1); ly = point(:, 2) - edge(2); else # Np points and Ne edges: # Create an array for each parameter, so that the result will be a # Np-by-Ne matrix of booleans (requires more memory, and uses repmat) x0 = repmat(edge(:, 1)', Np, 1); y0 = repmat(edge(:, 2)', Np, 1); dx = repmat(edge(:,3)', Np, 1) - x0; dy = repmat(edge(:,4)', Np, 1) - y0; lx = repmat(point(:, 1), 1, Ne) - x0; ly = repmat(point(:, 2), 1, Ne) - y0; end # test if point is located on supporting line b1 = (abs(lx.*dy - ly.*dx) ./ hypot(dx, dy)) < tol; # compute position of point with respect to edge bounds # use different tests depending on line angle ind = abs(dx) > abs(dy); t = zeros(size(dx)); t(ind) = lx( ind) ./ dx( ind); t(~ind) = ly(~ind) ./ dy(~ind); # check if point is located between edge bounds b = t >- tol & t-1 < tol & b1; endfunction %!shared points, vertices, edges %!demo %! # create a point array %! points = [10 10;15 10; 30 10]; %! # create an edge array %! vertices = [10 10;20 10;20 20;10 20]; %! edges = [vertices vertices([2:end 1], :)]; %! %! # Test one point and one edge %! isPointOnEdge(points(1,:), edges(1,:)) %! isPointOnEdge(points(3,:), edges(1,:)) %!demo %! # create a point array %! points = [10 10;15 10; 30 10]; %! # create an edge array %! vertices = [10 10;20 10;20 20;10 20]; %! edges = [vertices vertices([2:end 1], :)]; %! %! # Test one point and several edges %! isPointOnEdge(points(1,:), edges)' %!demo %! # create a point array %! points = [10 10;15 10; 30 10]; %! # create an edge array %! vertices = [10 10;20 10;20 20;10 20]; %! edges = [vertices vertices([2:end 1], :)]; %! %! # Test several points and one edge %! isPointOnEdge(points, edges(1,:))' %!demo %! # create a point array %! points = [10 10;15 10; 30 10]; %! # create an edge array %! vertices = [10 10;20 10;20 20;10 20]; %! edges = [vertices vertices([2:end 1], :)]; %! %! # Test N points and N edges %! isPointOnEdge(points, edges(1:3,:))' %!demo %! # create a point array %! points = [10 10;15 10; 30 10]; %! # create an edge array %! vertices = [10 10;20 10;20 20;10 20]; %! edges = [vertices vertices([2:end 1], :)]; %! %! # Test NP points and NE edges %! isPointOnEdge(points, edges) %!test %! p1 = [10 20]; %! p2 = [80 20]; %! edge = [p1 p2]; %! p0 = [10 20]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [80 20]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [50 20]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [9.99 20]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [80.01 20]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [50 21]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [79 19]; %! assert (!isPointOnEdge(p0, edge)); %!test %! p1 = [20 10]; %! p2 = [20 80]; %! edge = [p1 p2]; %! p0 = [20 10]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [20 80]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [20 50]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [20 9.99]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [20 80.01]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [21 50]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [19 79]; %! assert (!isPointOnEdge(p0, edge)); %!test %! p1 = [10 20]; %! p2 = [60 70]; %! edge = [p1 p2]; %! assert (isPointOnEdge(p1, edge)); %! assert (isPointOnEdge(p2, edge)); %! p0 = [11 21]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [59 69]; %! assert (isPointOnEdge(p0, edge)); %! p0 = [9.99 19.99]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [60.01 70.01]; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [30 50.01]; %! assert (!isPointOnEdge(p0, edge)); %!test %! edge = [10 20 80 20; 20 10 20 80; 20 10 60 70]; %! p0 = [20 20]; %! assert ([true ; true ; false], isPointOnEdge(p0, edge)); %!test %! k = 1e15; %! p1 = [10 20]*k; %! p2 = [60 70]*k; %! edge = [p1 p2]; %! assert (isPointOnEdge(p1, edge)); %! assert (isPointOnEdge(p2, edge)); %! p0 = [11 21]*k; %! assert (isPointOnEdge(p0, edge)); %! p0 = [59 69]*k; %! assert (isPointOnEdge(p0, edge)); %! p0 = [9.99 19.99]*k; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [60.01 70.01]*k; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [30 50.01]*k; %! assert (!isPointOnEdge(p0, edge)); %!test %! k = 1e-10; %! p1 = [10 20]*k; %! p2 = [60 70]*k; %! edge = [p1 p2]; %! assert (isPointOnEdge(p1, edge)); %! assert (isPointOnEdge(p2, edge)); %! p0 = [11 21]*k; %! assert (isPointOnEdge(p0, edge)); %! p0 = [59 69]*k; %! assert (isPointOnEdge(p0, edge)); %! p0 = [9.99 19.99]*k; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [60.01 70.01]*k; %! assert (!isPointOnEdge(p0, edge)); %! p0 = [30 50.01]*k; %! assert (!isPointOnEdge(p0, edge)); %!test %! p1 = [10 20]; %! p2 = [80 20]; %! edge = [p1 p2]; %! p0 = [10 20; 80 20; 50 20;50 21]; %! exp = [true;true;true;false]; %! assert (exp, isPointOnEdge(p0, edge)); %!test %! p1 = [10 20]; %! p2 = [80 20]; %! edge = [p1 p2]; %! p0 = [40 20]; %! exp = [true;true;true;true]; %! assert (exp, isPointOnEdge(p0, [edge;edge;edge;edge])); %!test %! edge1 = [10 20 80 20]; %! edge2 = [30 10 30 80]; %! edges = [edge1; edge2]; %! p0 = [40 20;30 90]; %! exp = [true;false]; %! assert (exp, isPointOnEdge(p0, edges)); geometry/inst/geom2d/circleArcAsCurve.m0000644000175000017500000000551112035504503017736 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p} = } circleArcAsCurve (@var{arc}, @var{N}) ## Convert a circle arc into a series of points ## ## P = circleArcAsCurve(ARC, N); ## convert the circle ARC into a series of N points. ## ARC is given in the format: [XC YC R THETA1 DTHETA] ## where XC and YC define the center of the circle, R its radius, THETA1 ## is the start of the arc and DTHETA is the angle extent of the arc. Both ## angles are given in degrees. ## N is the number of vertices of the resulting polyline, default is 65. ## ## The result is a N-by-2 array containing coordinates of the N points. ## ## [X Y] = circleArcAsCurve(ARC, N); ## Return the result in two separate arrays with N lines and 1 column. ## ## ## @seealso{circles2d, circleAsPolygon, drawCircle, drawPolygon} ## @end deftypefn function varargout = circleArcAsCurve(arc, N) # default value for N if nargin < 2 N = 65; end # vector of positions t0 = deg2rad(arc(4)); t1 = t0 + deg2rad(arc(5)); t = linspace(t0, t1, N)'; # compute coordinates of vertices x = arc(1) + arc(3) * cos(t); y = arc(2) + arc(3) * sin(t); # format output if nargout <= 1 varargout = {[x y]}; else varargout = {x, y}; end endfunction geometry/inst/geom2d/createHomothecy.m0000644000175000017500000000432112035504503017677 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } createHomothecy (@var{point}, @var{ratio}) ## Create the the 3x3 matrix of an homothetic transform. # # @var{point} is the center of the homothecy, @var{ratio} is its factor. # # @seealso{transforms2d, transformPoint, createTranslation} ## @end deftypefn function trans = createHomothecy(point, ratio) # extract coordinate of center x0 = point(:,1); y0 = point(:,2); # compute coefficients of the matrix m00 = ratio; m01 = 0; m02 = x0*(1-ratio); m10 = 0; m11 = ratio; m12 = y0*(1-ratio); # create transformation trans = [m00 m01 m02; m10 m11 m12; 0 0 1]; endfunction geometry/inst/geom2d/pointOnLine.m0000644000175000017500000000434712035504503017022 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} = } pointOnLine (@var{line}, @var{d}) ## Create a point on a line at a given position on the line. ## ## Creates the point belonging to the line @var{line}, and located at the ## distance @var{d} from the line origin. ## @var{line} has the form [x0 y0 dx dy]. ## @var{line} and @var{d} should have the same number N of rows. The result will have ## N rows and 2 column (x and y positions). ## ## @seealso{lines2d, points2d, onLine, onLine, linePosition} ## @end deftypefn function point = pointOnLine(lin, pos) ang = lineAngle(lin); point = [lin(:,1) + pos .* cos(ang), lin(:,2) + pos .* sin(ang)]; endfunction geometry/inst/geom2d/intersectLines.m0000644000175000017500000001373112035504503017554 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} =} intersectLines (@var{line1}, @var{line2}) ## @deftypefnx {Function File} {@var{point} =} intersectLines (@var{line1}, @var{line2},@var{eps}) ## Return all intersection points of N lines in 2D. ## ## Returns the intersection point of lines @var{line1} and @var{line2}. ## @var{line1} and @var{line2} are [1*4] ## arrays, containing parametric representation of each line (in the form ## [x0 y0 dx dy], see @code{createLine} for details). ## ## In case of colinear lines, returns [Inf Inf]. ## In case of parallel but not colinear lines, returns [NaN NaN]. ## ## If each input is [N*4] array, the result is a [N*2] array containing ## intersections of each couple of lines. ## If one of the input has N rows and the other 1 row, the result is a ## [N*2] array. ## ## A third input argument specifies the tolerance for detecting parallel lines. ## Default is 1e-14. ## ## Example ## ## @example ## line1 = createLine([0 0], [10 10]); ## line2 = createLine([0 10], [10 0]); ## point = intersectLines(line1, line2) ## point = ## 5 5 ## @end example ## ## @seealso{lines2d, edges2d, intersectEdges, intersectLineEdge, intersectLineCircle} ## @end deftypefn function point = intersectLines(line1, line2, varargin) # extreact tolerance tol = 1e-14; if !isempty(varargin) tol = varargin{1}; end x1 = line1(:,1); y1 = line1(:,2); dx1 = line1(:,3); dy1 = line1(:,4); x2 = line2(:,1); y2 = line2(:,2); dx2 = line2(:,3); dy2 = line2(:,4); N1 = length(x1); N2 = length(x2); # indices of parallel lines par = abs(dx1.*dy2 - dx2.*dy1) < tol; # indices of colinear lines col = abs((x2-x1) .* dy1 - (y2-y1) .* dx1) < tol & par ; x0(col) = Inf; y0(col) = Inf; x0(par & !col) = NaN; y0(par & !col) = NaN; i = !par; # compute intersection points if N1==N2 x0(i) = ((y2(i)-y1(i)).*dx1(i).*dx2(i) + x1(i).*dy1(i).*dx2(i) - x2(i).*dy2(i).*dx1(i)) ./ ... (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ; y0(i) = ((x2(i)-x1(i)).*dy1(i).*dy2(i) + y1(i).*dx1(i).*dy2(i) - y2(i).*dx2(i).*dy1(i)) ./ ... (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ; elseif N1==1 x0(i) = ((y2(i)-y1).*dx1.*dx2(i) + x1.*dy1.*dx2(i) - x2(i).*dy2(i).*dx1) ./ ... (dx2(i).*dy1-dx1.*dy2(i)) ; y0(i) = ((x2(i)-x1).*dy1.*dy2(i) + y1.*dx1.*dy2(i) - y2(i).*dx2(i).*dy1) ./ ... (dx1.*dy2(i)-dx2(i).*dy1) ; elseif N2==1 x0(i) = ((y2-y1(i)).*dx1(i).*dx2 + x1(i).*dy1(i).*dx2 - x2.*dy2.*dx1(i)) ./ ... (dx2.*dy1(i)-dx1(i).*dy2) ; y0(i) = ((x2-x1(i)).*dy1(i).*dy2 + y1(i).*dx1(i).*dy2 - y2.*dx2.*dy1(i)) ./ ... (dx1(i).*dy2-dx2.*dy1(i)) ; else # formattage a rajouter x0(i) = ((y2(i)-y1(i)).*dx1(i).*dx2(i) + x1(i).*dy1(i).*dx2(i) - x2(i).*dy2(i).*dx1(i)) ./ ... (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ; y0(i) = ((x2(i)-x1(i)).*dy1(i).*dy2(i) + y1(i).*dx1(i).*dy2(i) - y2(i).*dx2(i).*dy1(i)) ./ ... (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ; end # concatenate result point = [x0' y0']; endfunction %!test # basic test with two orthogonal lines %! line1 = [3 1 0 1]; %! line2 = [1 4 1 0]; %! assert (intersectLines(line1, line2), [3 4], 1e-6); %!test # orthognal diagonal lines %! line1 = [0 0 3 2]; %! line2 = [5 -1 4 -6]; %! assert (intersectLines(line1, line2), [3 2], 1e-6); %!test # one diagonal and one horizontal line %! line1 = [10 2 25 0]; %! line2 = [5 -1 4 -6]; %! assert (intersectLines(line1, line2), [3 2], 1e-6); %!test # check for dx and dy very big compared to other line %! line1 = [3 1 0 1000]; %! line2 = [1 4 -14 0]; %! assert (intersectLines(line1, line2), [3 4], 1e-6); %!test %! line1 = [2 0 20000 30000]; %! line2 = [1 6 1 -1]; %! assert (intersectLines(line1, line2), [4 3], 1e-6); %!test %! line1 = [3 1 0 1]; %! line2 = repmat([1 4 1 0], 5, 1); %! res = repmat([3 4], 5, 1); %! inters = intersectLines(line1, line2); %! assert (res, inters, 1e-6); %!test %! line1 = repmat([3 1 0 1], 5, 1); %! line2 = [1 4 1 0]; %! res = repmat([3 4], 5, 1); %! inters = intersectLines(line1, line2); %! assert (res, inters, 1e-6); %!test %! line1 = repmat([3 1 0 1], 5, 1); %! line2 = repmat([1 4 1 0], 5, 1); %! res = repmat([3 4], 5, 1); %! inters = intersectLines(line1, line2); %! assert (res, inters, 1e-6); geometry/inst/geom2d/intersectLineEdge.m0000644000175000017500000001001712035504503020150 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} = } intersecLineEdge (@var{line}, @var{edge}) ## Return intersection between a line and an edge. ## ## Returns the intersection point of lines @var{line} and edge @var{edge}. ## @var{line} is a 1x4 array containing parametric representation of the line ## (in the form [x0 y0 dx dy], see @code{createLine} for details). ## @var{edge} is a 1x4 array containing coordinates of first and second point ## (in the form [x1 y1 x2 y2], see @code{createEdge} for details). ## ## In case of colinear line and edge, returns [Inf Inf]. ## If line does not intersect edge, returns [NaN NaN]. ## ## If each input is [N*4] array, the result is a [N*2] array containing ## intersections for each couple of edge and line. ## If one of the input has N rows and the other 1 row, the result is a ## [N*2] array. ## ## @seealso{lines2d, edges2d, intersectEdges, intersectLine} ## @end deftypefn function point = intersectLineEdge(lin, edge) x0 = lin(:,1); y0 = lin(:,2); dx1 = lin(:,3); dy1 = lin(:,4); x1 = edge(:,1); y1 = edge(:,2); x2 = edge(:,3); y2 = edge(:,4); dx2 = x2-x1; dy2 = y2-y1; N1 = length(x0); N2 = length(x1); # indices of parallel lines par = abs(dx1.*dy2-dx2.*dy1)<1e-14; # indices of colinear lines col = abs((x1-x0).*dy1-(y1-y0).*dx1)<1e-14 & par ; xi(col) = Inf; yi(col) = Inf; xi(par & ~col) = NaN; yi(par & ~col) = NaN; i = ~par; # compute intersection points if N1==N2 xi(i) = ((y1(i)-y0(i)).*dx1(i).*dx2(i) + x0(i).*dy1(i).*dx2(i) - x1(i).*dy2(i).*dx1(i)) ./ ... (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ; yi(i) = ((x1(i)-x0(i)).*dy1(i).*dy2(i) + y0(i).*dx1(i).*dy2(i) - y1(i).*dx2(i).*dy1(i)) ./ ... (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ; elseif N1==1 xi(i) = ((y1(i)-y0).*dx1.*dx2(i) + x0.*dy1.*dx2(i) - x1(i).*dy2(i).*dx1) ./ ... (dx2(i).*dy1-dx1.*dy2(i)) ; yi(i) = ((x1(i)-x0).*dy1.*dy2(i) + y0.*dx1.*dy2(i) - y1(i).*dx2(i).*dy1) ./ ... (dx1.*dy2(i)-dx2(i).*dy1) ; elseif N2==1 xi(i) = ((y1-y0(i)).*dx1(i).*dx2 + x0(i).*dy1(i).*dx2 - x1(i).*dy2.*dx1(i)) ./ ... (dx2.*dy1(i)-dx1(i).*dy2) ; yi(i) = ((x1-x0(i)).*dy1(i).*dy2 + y0(i).*dx1(i).*dy2 - y1(i).*dx2.*dy1(i)) ./ ... (dx1(i).*dy2-dx2.*dy1(i)) ; end point = [xi' yi']; out = find(~isPointOnEdge(point, edge)); point(out, :) = repmat([NaN NaN], [length(out) 1]); endfunction geometry/inst/geom2d/crackPattern.m0000644000175000017500000001642112035504503017201 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{e} = } crackPattern (@var{box}, @var{points}, @var{alpha}) ## Create a (bounded) crack pattern tessellation ## ## E = crackPattern2(BOX, POINTS, ALPHA) ## create a crack propagation pattern wit following parameters : ## - pattern is bounded by area BOX which is a polygon. ## - each crack originates from points given in POINTS ## - directions of each crack is given by a [NxM] array ALPHA, where M is ## the number of rays emanating from each seed/ ## - a crack stop when it reaches another already created crack. ## - all cracks stop when they reach the border of the frame, given by box ## (a serie of 4 points). ## The result is a collection of edges, in the form [x1 y1 x2 y2]. ## ## E = crackPattern2(BOX, POINTS, ALPHA, SPEED) ## Also specify speed of propagation of each crack. ## ## ## See the result with : ## figure; ## drawEdge(E); ## ## @seealso{drawEdge} ## @end deftypefn function edges = crackPattern(box, points, alpha, varargin) if ~isempty(varargin) speed = varargin{1}; else speed = ones(size(points, 1), 1); end # Compute line equations for each initial crack. # The two 'Inf' at the end correspond to the position of the limit. # If an intersection point is found with another line, but whose position # is after this value, this means that another crack stopped it before it # reach the intersection point. # There is one 'end position' for each side of the crack. lines = [points speed.*cos(alpha) speed.*sin(alpha) Inf*ones(size(points, 1), 2)]; # initialize lines for borders, but assign a very high speed, to be sure # borders will stop all cracks. dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5; dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5; # add borders to the lines set lines = [lines ; createLine(box, dx, dy) Inf*ones(4,2)]; edges = zeros(0, 4); while true modif = 0; # try to update each line for i=1:size(points, 1) # compute intersections with all other lines pi = intersectLines(lines(i,:), lines); # compute position of all intersection points on the current line pos = linePosition(pi, lines(i,:)); # consider points to the right (positive position), and sort them indr = find(pos>=0 & pos~=Inf); [posr, indr2] = sort(pos(indr)); # look for the closest intersection to the right for i2=1:length(indr2) # index of intersected line il = indr(indr2(i2)); # position of point relative to intersected line pos2 = linePosition(pi(il, :), lines(il, :)); # depending on the sign of position, tests if the line2 can # stop the current line, or if it was stopped before if pos2>0 if pos20 if pos2 ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{d} = } edgePosition (@var{point}, @var{edge}) ## Return position of a point on an edge ## ## POS = edgePosition(POINT, EDGE); ## Computes position of point POINT on the edge EDGE, relative to the ## position of edge vertices. ## EDGE has the form [x1 y1 x2 y2], ## POINT has the form [x y], and is assumed to belong to edge. ## The position POS has meaning: ## POS<0: POINT is located before the first vertex ## POS=0: POINT is located on the first vertex ## 0 ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pos} =} linePosition (@var{point}, @var{line}) ## Position of a point on a line. ## ## Computes position of point @var{point} on the line @var{line}, relative to origin ## point and direction vector of the line. ## @var{line} has the form [x0 y0 dx dy], ## @var{point} has the form [x y], and is assumed to belong to line. ## ## If @var{line} is an array of NL lines, return NL positions, corresponding to ## each line. ## ## If @var{point} is an array of NP points, return NP positions, corresponding ## to each point. ## ## If @var{point} is an array of NP points and @var{line}S is an array of NL lines, ## return an array of [NP NL] position, corresponding to each couple ## point-line. ## ## Example ## ## @example ## line = createLine([10 30], [30 90]); ## linePosition([20 60], line) ## ans = ## .5 ## @end example ## ## @seealso{lines2d, createLine, projPointOnLine, isPointOnLine} ## @end deftypefn function d = linePosition(point, lin) # number of inputs Nl = size(lin, 1); Np = size(point, 1); if Np == Nl # if both inputs have the same size, no problem dxl = lin(:, 3); dyl = lin(:, 4); dxp = point(:, 1) - lin(:, 1); dyp = point(:, 2) - lin(:, 2); elseif Np == 1 # one point, several lines dxl = lin(:, 3); dyl = lin(:, 4); dxp = point(ones(Nl, 1), 1) - lin(:, 1); dyp = point(ones(Nl, 1), 2) - lin(:, 2); elseif Nl == 1 # one lin, several points dxl = lin(ones(Np, 1), 3); dyl = lin(ones(Np, 1), 4); dxp = point(:, 1) - lin(1); dyp = point(:, 2) - lin(2); else # expand one of the array to have the same size dxl = repmat(lin(:,3)', Np, 1); dyl = repmat(lin(:,4)', Np, 1); dxp = repmat(point(:,1), 1, Nl) - repmat(lin(:,1)', Np, 1); dyp = repmat(point(:,2), 1, Nl) - repmat(lin(:,2)', Np, 1); end # compute position d = (dxp.*dxl + dyp.*dyl) ./ (dxl.^2 + dyl.^2); endfunction %!demo %! point = [20 60;10 30;25 75]; %! lin = createLine([10 30], [30 90]); %! pos = linePosition(point, lin) %! %! plot(point(:,1),point(:,2),'ok'); %! hold on %! drawLine(lin,'color','r'); %! plot(lin(1)+lin(3)*pos,lin(2)+lin(4)*pos,'xb') %! hold off %!test %! point = [20 60]; %! lin = createLine([10 30], [30 90]); %! res = .5; %! pos = linePosition(point, lin); %! assert (res, pos); %!test %! point = [20 60;10 30;25 75]; %! lin = createLine([10 30], [30 90]); %! res = [.5; 0; .75]; %! pos = linePosition(point, lin); %! assert (res, pos); %!test %! point = [20 60]; %! lin1 = createLine([10 30], [30 90]); %! lin2 = createLine([0 0], [20 60]); %! lin3 = createLine([20 60], [40 120]); %! lines = [lin1;lin2;lin3]; %! res = [.5; 1; 0]; %! pos = linePosition(point, lines); %! assert (res, pos); geometry/inst/geom2d/radicalAxis.m0000644000175000017500000000562712035504503017012 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{line} = } radicalAxis (@var{circle1}, @var{circle2}) ## Compute the radical axis (or radical line) of 2 circles ## ## L = radicalAxis(C1, C2) ## Computes the radical axis of 2 circles. ## ## Example ## C1 = [10 10 5]; ## C2 = [60 50 30]; ## L = radicalAxis(C1, C2); ## hold on; axis equal;axis([0 100 0 100]); ## drawCircle(C1);drawCircle(C2);drawLine(L); ## ## Ref: ## http://mathworld.wolfram.com/RadicalLine.html ## http://en.wikipedia.org/wiki/Radical_axis ## ## @seealso{lines2d, circles2d, createCircle} ## ## @end deftypefn function line = radicalAxis(circle1, circle2) # extract circles parameters x1 = circle1(:,1); x2 = circle2(:,1); y1 = circle1(:,2); y2 = circle2(:,2); r1 = circle1(:,3); r2 = circle2(:,3); # distance between each couple of centers dist = sqrt((x2-x1).^2 + (y2-y1).^2); # relative position of intersection point of # the radical line with the line joining circle centers d = (dist.^2 + r1.^2 - r2.^2) * .5 ./ dist; # compute angle of radical axis angle = lineAngle(createLine([x1 y1], [x2 y2])); cot = cos(angle); sit = sin(angle); # parameters of the line x0 = x1 + d*cot; y0 = y1 + d*sit; dx = -sit; dy = cot; # concatenate into one structure line = [x0 y0 dx dy]; endfunction geometry/inst/geom2d/isPointOnCircle.m0000644000175000017500000000461612035504503017627 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPointOnCircle (@var{point}, @var{circle}) ## Test if a point is located on a given circle. ## ## B = isPointOnCircle(POINT, CIRCLE) ## return true if point is located on the circle, i.e. if the distance to ## the circle center equals the radius up to an epsilon value. ## ## B = isPointOnCircle(POINT, CIRCLE, TOL) ## Specifies the tolerance value. ## ## Example: ## isPointOnCircle([1 0], [0 0 1]) ## returns true, whereas ## isPointOnCircle([1 1], [0 0 1]) ## return false ## ## @seealso{circles2d, isPointInCircle} ## @end deftypefn function b = isPointOnCircle(point, circle, varargin) tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); b = abs(d-circle(:,3)) ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawPoint (@var{x}, @var{y}) ## @deftypefnx {Function File} {@var{h} = } drawPoint (@var{coord}) ## @deftypefnx {Function File} {@var{h} = } drawPoint (@dots{}, @var{opt}) ## Draw the point on the axis. # # Draws points defined by coordinates @var{x} and @var{y}. # @var{x} and @var{y} should be array the same size. Coordinates can be # packed coordinates in a single [N*2] array @var{coord}. Options @var{opt} # are passed to the @code{plot} function. # # @seealso{points2d, clipPoints} # ## @end deftypefn function varargout = drawPoint(varargin) # process input arguments var = varargin{1}; if size(var, 2)==1 # points stored in separate arrays px = varargin{1}; py = varargin{2}; varargin(1:2) = []; else # points packed in one array px = var(:, 1); py = var(:, 2); varargin(1) = []; end # ensure we have column vectors px = px(:); py = py(:); # default drawing options, but keep specified options if it has the form of # a bundled string if length(varargin)~=1 varargin = [{'linestyle', 'none', 'marker', 'o', 'color', 'b'}, varargin]; end # plot the points, using specified drawing options h = plot(px(:), py(:), varargin{:}); # process output arguments if nargout>0 varargout{1}=h; end endfunction %!demo %! drawPoint(10, 10); %!demo %! t = linspace(0, 2*pi, 20)'; %! drawPoint([5*cos(t)+10 3*sin(t)+10], 'r+'); geometry/inst/geom2d/bisector.m0000644000175000017500000000774112035504503016377 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{ray} = } bisector (@var{line1}, @var{line2}) ## @deftypefnx {Function File} {@var{ray} = } bisector (@var{p1}, @var{p2}, @var{p3}) ## Return the bisector of two lines, or 3 points. ## ## Creates the bisector of the two lines, given as [x0 y0 dx dy]. ## ## create the bisector of lines (@var{p2} @var{p1}) and (@var{p2} @var{p3}). ## ## The result has the form [x0 y0 dx dy], with [x0 y0] being the origin ## point ans [dx dy] being the direction vector, normalized to have unit ## norm. ## ## @seealso{lines2d, rays2d} ## @end deftypefn function ray = bisector(varargin) if length(varargin)==2 # two lines line1 = varargin{1}; line2 = varargin{2}; point = intersectLines(line1, line2); elseif length(varargin)==3 # three points p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; line1 = createLine(p2, p1); line2 = createLine(p2, p3); point = p2; elseif length(varargin)==1 # three points, given in one array var = varargin{1}; p1 = var(1, :); p2 = var(2, :); p3 = var(3, :); line1 = createLine(p2, p1); line2 = createLine(p2, p3); point = p2; end # compute line angles a1 = lineAngle(line1); a2 = lineAngle(line2); # compute bisector angle (angle of first line + half angle between lines) angle = mod(a1 + mod(a2-a1+2*pi, 2*pi)/2, pi*2); # create the resulting ray ray = [point cos(angle) sin(angle)]; endfunction %!shared privpath %! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private']; %!test %! addpath (privpath,'-end') %! p0 = [0 0]; %! p1 = [10 0]; %! p2 = [0 10]; %! line1 = createLine(p0, p1); %! line2 = createLine(p0, p2); %! ray = bisector(line1, line2); %! assertElementsAlmostEqual([0 0], ray(1,1:2)); %! assertAlmostEqual(pi/4, lineAngle(ray)); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! p0 = [0 0]; %! p1 = [10 0]; %! p2 = [0 10]; %! ray = bisector(p1, p0, p2); %! assertElementsAlmostEqual([0 0], ray(1,1:2)); %! assertAlmostEqual(pi/4, lineAngle(ray)); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! p0 = [0 0]; %! p1 = [10 0]; %! p2 = [0 10]; %! ray = bisector([p1; p0; p2]); %! assertElementsAlmostEqual([0 0], ray(1,1:2)); %! assertAlmostEqual(pi/4, lineAngle(ray)); %! rmpath (privpath); geometry/inst/geom2d/geom2d_Contents.m0000644000175000017500000002727612035504503017624 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} geom2d_Contents () ## Geometry 2D Toolbox ## Version 1.2.0 21-Oct-2011 . ## ## Library to handle and visualize geometric primitives such as points, ## lines, circles and ellipses, polygons... ## ## The goal is to provide a low-level library for manipulating geometrical ## primitives, making easier the development of more complex geometric ## algorithms. ## ## Most functions works for planar shapes, but some ones have been ## extended to 3D or to any dimension. ## ## Points ## points2d - Description of functions operating on points ## clipPoints - Clip a set of points by a box ## centroid - Compute centroid (center of mass) of a set of points ## midPoint - Middle point of two points or of an edge ## isCounterClockwise - Compute relative orientation of 3 points ## polarPoint - Create a point from polar coordinates (rho + theta) ## angle2Points - Compute horizontal angle between 2 points ## angle3Points - Compute oriented angle made by 3 points ## angleSort - Sort points in the plane according to their angle to origin ## distancePoints - Compute distance between two points ## minDistancePoints - Minimal distance between several points ## transformPoint - Transform a point with an affine transform ## drawPoint - Draw the point on the axis. ## ## Vectors ## vectors2d - Description of functions operating on plane vectors ## createVector - Create a vector from two points ## vectorNorm - Compute norm of a vector, or of a set of vectors ## vectorAngle - Angle of a vector, or between 2 vectors ## normalizeVector - Normalize a vector to have norm equal to 1 ## isPerpendicular - Check orthogonality of two vectors ## isParallel - Check parallelism of two vectors ## transformVector - Transform a vector with an affine transform ## rotateVector - Rotate a vector by a given angle ## ## Straight lines ## lines2d - Description of functions operating on planar lines ## createLine - Create a straight line from 2 points, or from other inputs ## medianLine - Create a median line between two points ## cartesianLine - Create a straight line from cartesian equation coefficients ## orthogonalLine - Create a line orthogonal to another one. ## parallelLine - Create a line parallel to another one. ## intersectLines - Return all intersection points of N lines in 2D ## lineAngle - Computes angle between two straight lines ## linePosition - Position of a point on a line ## lineFit - Fit a straight line to a set of points ## clipLine - Clip a line with a box ## reverseLine - Return same line but with opposite orientation ## transformLine - Transform a line with an affine transform ## drawLine - Draw the line on the current axis ## ## Edges (line segments between 2 points) ## edges2d - Description of functions operating on planar edges ## createEdge - Create an edge between two points, or from a line ## edgeToLine - Convert an edge to a straight line ## edgeAngle - Return angle of edge ## edgeLength - Return length of an edge ## midPoint - Middle point of two points or of an edge ## edgePosition - Return position of a point on an edge ## clipEdge - Clip an edge with a rectangular box ## reverseEdge - Intervert the source and target vertices of edge ## intersectEdges - Return all intersections between two set of edges ## intersectLineEdge - Return intersection between a line and an edge ## transformEdge - Transform an edge with an affine transform ## drawEdge - Draw an edge given by 2 points ## drawCenteredEdge - Draw an edge centered on a point ## ## Rays ## rays2d - Description of functions operating on planar rays ## createRay - Create a ray (half-line), from various inputs ## bisector - Return the bisector of two lines, or 3 points ## clipRay - Clip a ray with a box ## drawRay - Draw a ray on the current axis ## ## Relations between points and lines ## distancePointEdge - Minimum distance between a point and an edge ## distancePointLine - Minimum distance between a point and a line ## projPointOnLine - Project of a point orthogonally onto a line ## pointOnLine - Create a point on a line at a given position on the line ## isPointOnLine - Test if a point belongs to a line ## isPointOnEdge - Test if a point belongs to an edge ## isPointOnRay - Test if a point belongs to a ray ## isLeftOriented - Test if a point is on the left side of a line ## ## Circles ## circles2d - Description of functions operating on circles ## createCircle - Create a circle from 2 or 3 points ## createDirectedCircle - Create a directed circle ## intersectCircles - Intersection points of two circles ## intersectLineCircle - Intersection point(s) of a line and a circle ## circleAsPolygon - Convert a circle into a series of points ## circleArcAsCurve - Convert a circle arc into a series of points ## isPointInCircle - Test if a point is located inside a given circle ## isPointOnCircle - Test if a point is located on a given circle. ## enclosingCircle - Find the minimum circle enclosing a set of points. ## radicalAxis - Compute the radical axis (or radical line) of 2 circles ## drawCircle - Draw a circle on the current axis ## drawCircleArc - Draw a circle arc on the current axis ## ## Ellipses ## ellipses2d - Description of functions operating on ellipses ## inertiaEllipse - Inertia ellipse of a set of points ## isPointInEllipse - Check if a point is located inside a given ellipse ## ellipseAsPolygon - Convert an ellipse into a series of points ## drawEllipse - Draw an ellipse on the current axis ## drawEllipseArc - Draw an ellipse arc on the current axis ## ## Geometric transforms ## transforms2d - Description of functions operating on transforms ## createTranslation - Create the 3*3 matrix of a translation ## createRotation - Create the 3*3 matrix of a rotation ## createScaling - Create the 3*3 matrix of a scaling in 2 dimensions ## createHomothecy - Create the the 3x3 matrix of an homothetic transform ## createBasisTransform - Compute matrix for transforming a basis into another basis ## createLineReflection - Create the the 3x3 matrix of a line reflection ## fitAffineTransform2d - Fit an affine transform using two point sets ## ## Angles ## angles2d - Description of functions for manipulating angles ## normalizeAngle - Normalize an angle value within a 2*PI interval ## angleAbsDiff - Absolute difference between two angles ## angleDiff - Difference between two angles ## deg2rad - Convert angle from degrees to radians ## rad2deg - Convert angle from radians to degrees ## ## Boxes ## boxes2d - Description of functions operating on bounding boxes ## intersectBoxes - Intersection of two bounding boxes ## mergeBoxes - Merge two boxes, by computing their greatest extent ## randomPointInBox - Generate random point within a box ## drawBox - Draw a box defined by coordinate extents ## ## Various drawing functions ## drawBezierCurve - Draw a cubic bezier curve defined by 4 control points ## drawParabola - Draw a parabola on the current axis ## drawOrientedBox - Draw centered oriented rectangle ## drawRect - Draw rectangle on the current axis ## drawArrow - Draw an arrow on the current axis ## drawLabels - Draw labels at specified positions ## drawShape - Draw various types of shapes (circles, polygons...) ## ## Other shapes ## squareGrid - Generate equally spaces points in plane. ## hexagonalGrid - Generate hexagonal grid of points in the plane. ## triangleGrid - Generate triangular grid of points in the plane. ## crackPattern - Create a (bounded) crack pattern tessellation ## crackPattern2 - Create a (bounded) crack pattern tessellation ## ## ## Credits: ## * function 'enclosingCircle' rewritten from a file from Yazan Ahed ## , available on Matlab File Exchange ## ## @end deftypefn function geom2d_Contents () help('geom2d_Contents'); ## Deprecated functions # createMedian - create a median line # minDistance - compute minimum distance between a point and a set of points # homothecy - create a homothecy as an affine transform # rotation - return 3*3 matrix of a rotation # translation - return 3*3 matrix of a translation # scaling - return 3*3 matrix of a scaling in 2 dimensions # lineSymmetry - create line symmetry as 2D affine transform # vecnorm - compute norm of vector or of set of vectors # normalize - normalize a vector # onCircle - test if a point is located on a given circle. # inCircle - test if a point is located inside a given circle. # onEdge - test if a point belongs to an edge # onLine - test if a point belongs to a line # onRay - test if a point belongs to a ray # invertLine - return same line but with opposite orientation # clipLineRect - clip a line with a polygon # formatAngle - Ensure an angle value is comprised between 0 and 2*PI ## Others... # drawRect2 - Draw centered rectangle on the current axis endfunction geometry/inst/geom2d/edgeAngle.m0000644000175000017500000000440312035504503016430 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{theta} =} edgeAngle(@var{edge}) ## Return angle of edge ## ## A = edgeAngle(EDGE) ## Returns the angle between horizontal, right-axis and the edge EDGE. ## Angle is given in radians, between 0 and 2*pi, in counter-clockwise ## direction. ## Notation for edge is [x1 y1 x2 y2] (coordinates of starting and ending ## points). ## ## Example ## p1 = [10 20]; ## p2 = [30 40]; ## rad2deg(edgeAngle([p1 p2])) ## ans = ## 45 ## ## @seealso{edges2d, angles2d, edgeAngle, lineAngle, edgeLength} ## @end deftypefn function theta = edgeAngle(edge) line = createLine(edge(:,1:2), edge(:,3:4)); theta = lineAngle(line); endfunction geometry/inst/geom2d/transformEdge.m0000644000175000017500000000546112035504503017362 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{edge2} = } transformEdge (@var{edge1}, @var{T}) ## Transform an edge with an affine transform. ## ## Where @var{edge1} has the form [x1 y1 x2 y1], and @var{T} is a transformation ## matrix, return the edge transformed with affine transform @var{T}. ## ## Format of TRANS can be one of : ## [a b] , [a b c] , or [a b c] ## [d e] [d e f] [d e f] ## [0 0 1] ## ## Also works when @var{edge1} is a [Nx4] array of double. In this case, @var{edge2} ## has the same size as @var{edge1}. ## ## @seealso{edges2d, transforms2d, transformPoint, translation, rotation} ## @end deftypefn function dest = transformEdge(edge, trans) dest = zeros(size(edge)); # compute position dest(:,1) = edge(:,1)*trans(1,1) + edge(:,2)*trans(1,2); dest(:,2) = edge(:,1)*trans(2,1) + edge(:,2)*trans(2,2); dest(:,3) = edge(:,3)*trans(1,1) + edge(:,3)*trans(1,2); dest(:,4) = edge(:,4)*trans(2,1) + edge(:,4)*trans(2,2); # add translation vector, if exist if size(trans, 2)>2 dest(:,1) = dest(:,1)+trans(1,3); dest(:,2) = dest(:,2)+trans(2,3); dest(:,3) = dest(:,3)+trans(1,3); dest(:,4) = dest(:,4)+trans(2,3); end endfunction geometry/inst/geom2d/fitAffineTransform2d.m0000644000175000017500000000471412035504503020577 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } fitAffineTransform2d (@var{pts1}, @var{pts2}) ## Fit an affine transform using two point sets. ## ## Example ## ## @example ## N = 10; ## pts = rand(N, 2)*10; ## trans = createRotation(3, 4, pi/4); ## pts2 = transformPoint(pts, trans); ## pts3 = pts2 + randn(N, 2)*2; ## fitted = fitAffineTransform2d(pts, pts2) ##@end example ## ## @seealso{transforms2d} ## @end deftypefn function trans = fitAffineTransform2d(pts1, pts2) # number of points N = size(pts1, 1); # main matrix of the problem A = [... pts1(:,1) pts1(:,2) ones(N,1) zeros(N, 3) ; ... zeros(N, 3) pts1(:,1) pts1(:,2) ones(N,1) ]; # conditions initialisations B = [pts2(:,1) ; pts2(:,2)]; # compute coefficients using least square coefs = A\B; # format to a matrix trans = [coefs(1:3)' ; coefs(4:6)'; 0 0 1]; endfunction geometry/inst/geom2d/drawRect.m0000644000175000017500000000673112035504503016336 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{r} = } drawRect (@var{x}, @var{y}, @var{w}, @var{h}) ## @deftypefnx {Function File} {@var{r} = } drawRect (@var{x}, @var{y}, @var{w}, @var{h}, @var{theta}) ## @deftypefnx {Function File} {@var{r} = } drawRect (@var{coord}) ## Draw rectangle on the current axis. ## ## r = DRAWRECT(x, y, w, h) draw rectangle with width W and height H, at ## position (X, Y). ## the four corners of rectangle are then : ## (X, Y), (X+W, Y), (X, Y+H), (X+W, Y+H). ## ## r = DRAWRECT(x, y, w, h, theta) also specifies orientation for ## rectangle. Theta is given in degrees. ## ## r = DRAWRECT(coord) is the same as DRAWRECT(X,Y,W,H), but all ## parameters are packed into one array, whose dimensions is 4*1 or 5*1. ## ## ## @seealso{drawBox, drawOrientedBox} ## @end deftypefn function varargout = drawRect(varargin) # default values theta = 0; # get entered values if length(varargin) > 3 x = varargin{1}; y = varargin{2}; w = varargin{3}; h = varargin{4}; if length(varargin)> 4 theta = varargin{5} * pi / 180; end else coord = varargin{1}; x = coord(1); y = coord(2); w = coord(3); h = coord(4); if length(coord) > 4 theta = coord(5) * pi / 180; end end r = zeros(size(x)); for i = 1:length(x) tx = zeros(5, 1); ty = zeros(5, 1); tx(1) = x(i); ty(1) = y(i); tx(2) = x(i) + w(i) * cos(theta(i)); ty(2) = y(i) + w(i) * sin(theta(i)); tx(3) = x(i) + w(i) * cos(theta(i)) - h(i) * sin(theta(i)); ty(3) = y(i) + w(i) * sin(theta(i)) + h(i) * cos(theta(i)); tx(4) = x(i) - h(i) * sin(theta(i)); ty(4) = y(i) + h(i) * cos(theta(i)); tx(5) = x(i); ty(5) = y(i); r(i) = line(tx, ty); end if nargout > 0 varargout{1} = r; end endfunction geometry/inst/geom2d/transformPoint.m0000644000175000017500000000651212035504503017605 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pt2} = } transformPoint (@var{pt1}, @var{Trans}) ## @deftypefnx {Function File} {[@var{px2} @var{py2}]= } transformPoint (@var{px1}, @var{py1}, @var{Trans}) ## Transform a point with an affine transform. ## ## where @var{pt1} has the form [xp yp], and @var{Trans} is a [2x2], [2x3] or [3x3] ## matrix, returns the point transformed with affine transform @var{Trans}. ## ## Format of @var{Trans} can be one of : ## [a b] , [a b c] , or [a b c] ## [d e] [d e f] [d e f] ## [0 0 1] ## ## Also works when @var{pt1} is a [Nx2] array of double. In this case, @var{pt2} has ## the same size as @var{pt1}. ## ## Also works when @var{px1} and @var{py1} are arrays the same size. The function ## transform each couple of (@var{px1}, @var{py1}), and return the result in ## (@var{px2}, @var{py2}), which is the same size as (@var{px1} @var{py1}). ## ## @seealso{points2d, transforms2d, createTranslation, createRotation} ## @end deftypefn function varargout = transformPoint(varargin) if length(varargin)==2 var = varargin{1}; px = var(:,1); py = var(:,2); trans = varargin{2}; elseif length(varargin)==3 px = varargin{1}; py = varargin{2}; trans = varargin{3}; else error('wrong number of arguments in "transformPoint"'); end # compute position px2 = px*trans(1,1) + py*trans(1,2); py2 = px*trans(2,1) + py*trans(2,2); # add translation vector, if exist if size(trans, 2)>2 px2 = px2 + trans(1,3); py2 = py2 + trans(2,3); end if nargout==0 || nargout==1 varargout{1} = [px2 py2]; elseif nargout==2 varargout{1} = px2; varargout{2} = py2; end endfunction geometry/inst/geom2d/isPointInEllipse.m0000644000175000017500000000546512035504503020020 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} = } isPointInellipse (@var{point}, @var{ellipse}) ## Check if a point is located inside a given ellipse ## ## B = isPointInEllipse(POINT, ELLIPSE) ## Returns true if point is located inside the given ellipse. ## ## B = isPointInEllipse(POINT, ELLIPSE, TOL) ## Specifies the tolerance value ## ## Example: ## isPointInEllipse([1 0], [0 0 2 1 0]) ## ans = ## 1 ## isPointInEllipse([0 0], [0 0 2 1 0]) ## ans = ## 1 ## isPointInEllipse([1 1], [0 0 2 1 0]) ## ans = ## 0 ## isPointInEllipse([1 1], [0 0 2 1 30]) ## ans = ## 1 ## ## @seealso{ellipses2d, isPointInCircle} ## @end deftypefn function b = isPointInEllipse(point, ellipse, varargin) # extract computation tolerance tol = 1e-14; if ~isempty(varargin) tol = varargin{1}; end # compute ellipse to unit circle transform rot = createRotation(-deg2rad(ellipse(5))); sca = createScaling(1./ellipse(3:4)); trans = sca * rot; # transform points to unit circle basis pTrans = bsxfun(@minus, point, ellipse(:,1:2)); pTrans = transformPoint(pTrans, trans); # test if distance to origin smaller than 1 b = sqrt(sum(power(pTrans, 2), 2)) - 1 <= tol; endfunction geometry/inst/geom2d/drawParabola.m0000644000175000017500000001104312035504503017152 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawParabola (@var{parabola}) ## @deftypefnx {Function File} {@var{h} = } drawParabola (@var{parabola}, @var{t}) ## @deftypefnx {Function File} {@var{h} = } drawParabola (@dots{}, @var{param}, @var{value}) ## Draw a parabola on the current axis. ## ## drawParabola(PARABOLA); ## Draws a vertical parabola, defined by its vertex and its parameter. ## Such a parabola admits a vertical axis of symetry. ## ## The algebraic equation of parabola is given by: ## (Y - YV) = A * (X - VX)^2 ## Where XV and YV are vertex coordinates and A is parabola parameter. ## ## A parametric equation of parabola is given by: ## x(t) = t + VX; ## y(t) = A * t^2 + VY; ## ## PARABOLA can also be defined by [XV YV A THETA], with theta being the ## angle of rotation of the parabola (in degrees and Counter-Clockwise). ## ## drawParabola(PARABOLA, T); ## Specifies which range of 't' are used for drawing parabola. If T is an ## array with only two values, the first and the last values are used as ## interval bounds, and several values are distributed within this ## interval. ## ## drawParabola(..., NAME, VALUE); ## Can specify one or several graphical options using parameter name-value ## pairs. ## ## H = drawParabola(...); ## Returns an handle to the created graphical object. ## ## ## Example: ## @example ## figure(1); clf; hold on; ## drawParabola([50 50 .2 30]); ## drawParabola([50 50 .2 30], [-1 1], 'color', 'r', 'linewidth', 2); ## axis equal; ## @end example ## ## @seealso{drawCircle, drawEllipse} ## @end deftypefn function varargout = drawParabola(varargin) # Extract parabola if nargin<1 error('geom2d:IllegalArgument', ... 'Please specify parabola representation'); end # input parabola is given as a packed array parabola = varargin{1}; varargin(1) = []; x0 = parabola(:,1); y0 = parabola(:,2); a = parabola(:,3); if size(parabola, 2)>3 theta = parabola(:, 4); else theta = zeros(length(a), 1); end # extract parametrisation bounds bounds = [-100 100]; if ~isempty(varargin) var = varargin{1}; if isnumeric(var) bounds = var; varargin(1) = []; end end # create parametrisation if length(bounds)>2 t = bounds; else t = linspace(bounds(1), bounds(end), 100); end # create handle array (in the case of several parabola) h = zeros(size(x0)); # draw each parabola for i=1:length(x0) # compute transformation trans = ... createTranslation(x0(i), y0(i)) * ... createRotation(deg2rad(theta(i))) * ... createScaling(1, a); # compute points on the parabola [xt yt] = transformPoint(t(:), t(:).^2, trans); # draw it h(i) = plot(xt, yt, varargin{:}); end # process output arguments if nargout>0 varargout{1}=h; end endfunction geometry/inst/geom2d/angle2Points.m0000644000175000017500000000711412035504503017124 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{alpha} =} angle2Points (@var{p1}, @var{p2}) ## Compute horizontal angle between 2 points ## ## @var{p1} and @var{p2} are either [1x2] arrays, or [Nx2] arrays, in this case ## @var{alpha} is a [Nx1] array. The angle computed is the horizontal angle of ## the line (@var{p1},@var{p2}). ## ## Result is always given in radians, between 0 and 2*pi. ## ## @seealso{points2d, angles2d, angle3points, normalizeAngle, vectorAngle} ## @end deftypefn function theta = angle2Points(varargin) # process input arguments if length(varargin)==2 p1 = varargin{1}; p2 = varargin{2}; elseif length(varargin)==1 var = varargin{1}; p1 = var(1,:); p2 = var(2,:); end # ensure data have correct size n1 = size(p1, 1); n2 = size(p2, 1); if n1~=n2 && min(n1, n2)>1 error('angle2Points: wrong size for inputs'); end # angle of line (P2 P1), between 0 and 2*pi. dp = bsxfun(@minus, p2, p1); theta = mod(atan2(dp(:,2), dp(:,1)) + 2*pi, 2*pi); endfunction %!test %! # all points inside window, possibly touching edges %! p1 = [0 0]; %! p2 = [10 0]; %! angle_ = angle2Points (p1, p2); %! assert (angle_,0,1e-6); %! angle_ = angle2Points (p2, p1); %! assert (angle_,pi,1e-6); %!test %! # all points inside window, possibly touching edges %! p1 = [0 0]; %! p2 = [0 10]; %! angle_ = angle2Points (p1, p2); %! assert (pi/2, angle_,1e-6); %! angle_ = angle2Points (p2, p1); %! assert (3*pi/2, angle_,1e-6); %!test %! # all points inside window, possibly touching edges %! p1 = [0 0;0 0;0 0;0 0]; %! p2 = [10 0;10 10;0 10;-10 10]; %! angle_ = angle2Points (p1, p2); %! assert (size (p1, 1), size (angle_, 1)); %! res = [0;pi/4;pi/2;3*pi/4]; %! assert (res, angle_, 1e-6); %!test %! # all points inside window, possibly touching edges %! p1 = [0 0]; %! p2 = [10 0;10 10;0 10;-10 10]; %! angle_ = angle2Points (p1, p2); %! assert(size (p2, 1), size (angle_, 1)); %! res = [0;pi/4;pi/2;3*pi/4]; %! assert(res, angle_,1e-6); geometry/inst/geom2d/circles2d.m0000644000175000017500000000510712035504503016431 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} circles2d () ## Description of functions operating on circles ## ## Circles are represented by their center and their radius: ## C = [xc yc r]; ## One sometimes considers orientation of circle, by adding an extra ## boolean value in 4-th position, with value TRUE for direct (i.e. ## turning Counter-clockwise) circles. ## ## Circle arcs are represented by their center, their radius, the starting ## angle and the angle extent, both in degrees: ## CA = [xc yc r theta0 dtheta]; ## ## Ellipses are represented by their center, their 2 semi-axis length, and ## their angle (in degrees) with Ox direction. ## E = [xc yc A B theta]; ## ## @seealso{ellipses2d, createCircle, createDirectedCircle, enclosingCircle ## isPointInCircle, isPointOnCircle ## intersectLineCircle, intersectCircles, radicalAxis ## circleAsPolygon, circleArcAsCurve ## drawCircle, drawCircleArc} ## @end deftypefn function circles2d(varargin) help('circles2d'); endfunction geometry/inst/geom2d/isCounterClockwise.m0000644000175000017500000001277212035504503020404 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{ccw} = } isCounterClockwise (@var{p1}, @var{p2}, @var{p3}) ## @deftypefnx {Function File} {@var{ccw} = } isCounterClockwise (@var{p1}, @var{p2}, @var{p3},@var{tol}) ## Compute relative orientation of 3 points ## ## Computes the orientation of the 3 points. The returns is: ## +1 if the path @var{p1}-> @var{p2}-> @var{p3} turns Counter-Clockwise (i.e., the point @var{p3} ## is located "on the left" of the line @var{p1}- @var{p2}) ## -1 if the path turns Clockwise (i.e., the point @var{p3} lies "on the right" ## of the line @var{p1}- @var{p2}) ## 0 if the point @var{p3} is located on the line segment [ @var{p1} @var{p2}]. ## ## This function can be used in more complicated algorithms: detection of ## line segment intersections, convex hulls, point in triangle... ## ## @var{ccw} = isCounterClockwise( @var{p1}, @var{p2}, @var{p3}, EPS); ## Specifies the threshold used for detecting colinearity of the 3 points. ## Default value is 1e-12 (absolute). ## ## Example ## ## @example ## isCounterClockwise([0 0], [10 0], [10 10]) ## ans = ## 1 ## isCounterClockwise([0 0], [0 10], [10 10]) ## ans = ## -1 ## isCounterClockwise([0 0], [10 0], [5 0]) ## ans = ## 0 ## @end example ## ## @seealso{points2d, isPointOnLine, isPointInTriangle} ## @end deftypefn function res = isCounterClockwise(p1, p2, p3, varargin) # get threshold value eps = 1e-12; if ~isempty(varargin) eps = varargin{1}; end # ensure all data have same size np = max([size(p1, 1) size(p2, 1) size(p3,1)]); if np > 1 if size(p1,1) == 1 p1 = repmat(p1, np, 1); end if size(p2,1) == 1 p2 = repmat(p2, np, 1); end if size(p3,1) == 1 p3 = repmat(p3, np, 1); end end # init with 0 res = zeros(np, 1); # extract vector coordinates x0 = p1(:, 1); y0 = p1(:, 2); dx1 = p2(:, 1) - x0; dy1 = p2(:, 2) - y0; dx2 = p3(:, 1) - x0; dy2 = p3(:, 2) - y0; # check non colinear cases res(dx1 .* dy2 > dy1 .* dx2) = 1; res(dx1 .* dy2 < dy1 .* dx2) = -1; # case of colinear points ind = abs(dx1 .* dy2 - dy1 .* dx2) < eps; res(ind( (dx1(ind) .* dx2(ind) < 0) | (dy1(ind) .* dy2(ind) < 0) )) = -1; res(ind( hypot(dx1(ind), dy1(ind)) < hypot(dx2(ind), dy2(ind)) )) = 1; endfunction %!shared p0,pu,pd,pl,pr %! p0 = [2, 3]; # center point %! pu = [2, 4]; # up point %! pd = [2, 2]; # down point %! pl = [1, 3]; # left point %! pr = [3, 3]; # right point %!assert (+1, isCounterClockwise(pl, p0, pu)); %!assert (+1, isCounterClockwise(pd, p0, pl)); %!assert (+1, isCounterClockwise(pr, p0, pd)); %!assert (+1, isCounterClockwise(pu, p0, pr)); # turn 90° right => return -1 %!assert (-1, isCounterClockwise(pl, p0, pd)); %!assert (-1, isCounterClockwise(pd, p0, pr)); %!assert (-1, isCounterClockwise(pr, p0, pu)); %!assert (-1, isCounterClockwise(pu, p0, pl)); %!test # turn 90° left => return +1 %! pts1 = [pl;pd;pr;pu;pl;pd;pr;pu]; %! pts2 = [p0;p0;p0;p0;p0;p0;p0;p0]; %! pts3 = [pu;pl;pd;pr;pd;pr;pu;pl]; %! expected = [1;1;1;1;-1;-1;-1;-1]; %! result = isCounterClockwise(pts1, pts2, pts3); %! assert (result, expected, 1e-6); # aligned with p0-p1-p2 => return +1 %!assert (+1, isCounterClockwise(pl, p0, pr)); %!assert (+1, isCounterClockwise(pu, p0, pd)); %!assert (+1, isCounterClockwise(pr, p0, pl)); %!assert (+1, isCounterClockwise(pd, p0, pu)); # aligned ]ith p0-p2-p1 => return 0 %!assert (0, isCounterClockwise(pl, pr, p0)); %!assert (0, isCounterClockwise(pu, pd, p0)); %!assert (0, isCounterClockwise(pr, pl, p0)); %!assert (0, isCounterClockwise(pd, pu, p0)); # aligned with p1-p0-p2 => return -1 %!assert (-1, isCounterClockwise(p0, pl, pr)); %!assert (-1, isCounterClockwise(p0, pu, pd)); %!assert (-1, isCounterClockwise(p0, pr, pl)); %!assert (-1, isCounterClockwise(p0, pr, pl)); geometry/inst/geom2d/minDistancePoints.m0000644000175000017500000002365012035504503020215 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dist} = } minDistancePoints (@var{pts}) ## @deftypefnx {Function File} {@var{dist} = } minDistancePoints (@var{pts1},@var{pts2}) ## @deftypefnx {Function File} {@var{dist} = } minDistancePoints (@dots{},@var{norm}) ## @deftypefnx {Function File} {[@var{dist} @var{i} @var{j}] = } minDistancePoints (@var{pts1}, @var{pts2}, @dots{}) ## @deftypefnx {Function File} {[@var{dist} @var{j}] = } minDistancePoints (@var{pts1}, @var{pts2}, @dots{}) ## Minimal distance between several points. ## ## Returns the minimum distance between all couple of points in @var{pts}. @var{pts} is ## an array of [NxND] values, N being the number of points and ND the ## dimension of the points. ## ## Computes for each point in @var{pts1} the minimal distance to every point of ## @var{pts2}. @var{pts1} and @var{pts2} are [NxD] arrays, where N is the number of points, ## and D is the dimension. Dimension must be the same for both arrays, but ## number of points can be different. ## The result is an array the same length as @var{pts1}. ## ## When @var{norm} is provided, it uses a user-specified norm. @var{norm}=2 means euclidean norm (the default), ## @var{norm}=1 is the Manhattan (or "taxi-driver") distance. ## Increasing @var{norm} growing up reduces the minimal distance, with a limit ## to the biggest coordinate difference among dimensions. ## ## ## Returns indices @var{i} and @var{j} of the 2 points which are the closest. @var{dist} ## verifies relation: ## @var{dist} = distancePoints(@var{pts}(@var{i},:), @var{pts}(@var{j},:)); ## ## If only 2 output arguments are given, it returns the indices of points which are the closest. @var{j} has the ## same size as @var{dist}. for each I It verifies the relation : ## @var{dist}(I) = distancePoints(@var{pts1}(I,:), @var{pts2}(@var{J},:)); ## ## ## Examples: ## ## @example ## # minimal distance between random planar points ## points = rand(20,2)*100; ## minDist = minDistancePoints(points); ## ## # minimal distance between random space points ## points = rand(30,3)*100; ## [minDist ind1 ind2] = minDistancePoints(points); ## minDist ## distancePoints(points(ind1, :), points(ind2, :)) ## # results should be the same ## ## # minimal distance between 2 sets of points ## points1 = rand(30,2)*100; ## points2 = rand(30,2)*100; ## [minDists inds] = minDistancePoints(points1, points2); ## minDists(10) ## distancePoints(points1(10, :), points2(inds(10), :)) ## # results should be the same ## @end example ## ## @seealso{points2d, distancePoints} ## @end deftypefn function varargout = minDistancePoints(p1, varargin) ## Initialisations # default norm (euclidean) n = 2; # flag for processing of all points allPoints = false; # process input variables if isempty(varargin) # specify only one array of points, not the norm p2 = p1; elseif length(varargin)==1 var = varargin{1}; if length(var)>1 # specify two arrays of points p2 = var; allPoints = true; else # specify array of points and the norm n = var; p2 = p1; end else # specify two array of points and the norm p2 = varargin{1}; n = varargin{2}; allPoints = true; end # number of points in each array n1 = size(p1, 1); n2 = size(p2, 1); # dimension of points d = size(p1, 2); ## Computation of distances # allocate memory dist = zeros(n1, n2); # different behaviour depending on the norm used if n==2 # Compute euclidian distance. this is the default case # Compute difference of coordinate for each pair of point ([n1*n2] array) # and for each dimension. -> dist is a [n1*n2] array. # in 2D: dist = dx.*dx + dy.*dy; for i=1:d dist = dist + (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2; end # compute minimal distance: if ~allPoints # either on all couple of points mat = repmat((1:n1)', [1 n1]); ind = mat < mat'; [minSqDist ind] = min(dist(ind)); else # or for each point of P1 [minSqDist ind] = min(dist, [], 2); end # convert squared distance to distance minDist = sqrt(minSqDist); elseif n==inf # infinite norm corresponds to maximum absolute value of differences # in 2D: dist = max(abs(dx) + max(abs(dy)); for i=1:d dist = max(dist, abs(p1(:,i)-p2(:,i))); end else # compute distance using the specified norm. # in 2D: dist = power(abs(dx), n) + power(abs(dy), n); for i=1:d dist = dist + power((abs(repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1]))), n); end # compute minimal distance if ~allPoints # either on all couple of points mat = repmat((1:n1)', [1 n1]); ind = mat < mat'; [minSqDist ind] = min(dist(ind)); else # or for each point of P1 [minSqDist ind] = min(dist, [], 2); end # convert squared distance to distance minDist = power(minSqDist, 1/n); end if ~allPoints # convert index in array to row ad column subindices. # This uses the fact that index are sorted in a triangular matrix, # with the last index of each column being a so-called triangular # number ind2 = ceil((-1+sqrt(8*ind+1))/2); ind1 = ind - ind2*(ind2-1)/2; ind2 = ind2 + 1; end ## format output parameters # format output depending on number of asked parameters if nargout<=1 varargout{1} = minDist; elseif nargout==2 # If two arrays are asked, 'ind' is an array of indices, one for each # point in var{pts}1, corresponding to the result in minDist varargout{1} = minDist; varargout{2} = ind; elseif nargout==3 # If only one array is asked, minDist is a scalar, ind1 and ind2 are 2 # indices corresponding to the closest points. varargout{1} = minDist; varargout{2} = ind1; varargout{3} = ind2; end endfunction %!test %! pts = [50 10;40 60;30 30;20 0;10 60;10 30;0 10]; %! assert (minDistancePoints(pts), 20); %!test %! pts = [10 10;25 5;20 20;30 20;10 30]; %! [dist ind1 ind2] = minDistancePoints(pts); %! assert (10, dist, 1e-6); %! assert (3, ind1, 1e-6); %! assert (4, ind2, 1e-6); %!test %! pts = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20]; %! assert (minDistancePoints([40 50], pts), 10*sqrt(5), 1e-6); %! assert (minDistancePoints([25 30], pts), 5*sqrt(5), 1e-6); %! assert (minDistancePoints([30 40], pts), 10, 1e-6); %! assert (minDistancePoints([20 40], pts), 0, 1e-6); %!test %! pts1 = [40 50;25 30;40 20]; %! pts2 = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20]; %! res = [10*sqrt(5);5*sqrt(5);10]; %! assert (minDistancePoints(pts1, pts2), res, 1e-6); %!test %! pts = [50 10;40 60;40 30;20 0;10 60;10 30;0 10]; %! assert (minDistancePoints(pts, 1), 30, 1e-6); %! assert (minDistancePoints(pts, 100), 20, 1e-6); %!test %! pts = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20]; %! assert (minDistancePoints([40 50], pts, 2), 10*sqrt(5), 1e-6); %! assert (minDistancePoints([25 30], pts, 2), 5*sqrt(5), 1e-6); %! assert (minDistancePoints([30 40], pts, 2), 10, 1e-6); %! assert (minDistancePoints([20 40], pts, 2), 0, 1e-6); %! assert (minDistancePoints([40 50], pts, 1), 30, 1e-6); %! assert (minDistancePoints([25 30], pts, 1), 15, 1e-6); %! assert (minDistancePoints([30 40], pts, 1), 10, 1e-6); %! assert (minDistancePoints([20 40], pts, 1), 0, 1e-6); %!test %! pts1 = [40 50;25 30;40 20]; %! pts2 = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20]; %! res1 = [10*sqrt(5);5*sqrt(5);10]; %! assert (minDistancePoints(pts1, pts2, 2), res1, 1e-6); %! res2 = [30;15;10]; %! assert (minDistancePoints(pts1, pts2, 1), res2); %!test %! pts1 = [40 50;20 30;40 20]; %! pts2 = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20]; %! dists0 = [10*sqrt(5);10;10]; %! inds1 = [3;3;4]; %! [minDists inds] = minDistancePoints(pts1, pts2); %! assert (dists0, minDists); %! assert (inds1, inds); geometry/inst/geom2d/createBasisTransform.m0000644000175000017500000001012512035504503020674 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{T} = } createBasisTransfrom (@var{@var{target}}) ## @deftypefnx {Function File} {@var{T} = } createBasisTransfrom (@var{@var{source}}, @var{@var{target}}) ## Compute matrix for transforming a basis into another basis ## ## With only one input arguemnt, assumes the @var{source} is the standard (Oij) basis, with origin at (0,0), ## first direction vector equal to (1,0) and second direction vector ## equal to (0,1). Otherwise @var{@var{source}} specifies the @var{source} basis. ## ## Both @var{source} and @var{target} represent basis, in the following form: ## [x0 y0 ex1 ey1 ex2 ey2] ## [y0 y0] is the origin of the basis, [ex1 ey1] is the first direction ## vector, and [ex2 ey2] is the second direction vector. ## ## The result @var{T} is a 3-by-3 matrix such that a point expressed with ## coordinates of the first basis will be represented by new coordinates ## @code{P2 = transformPoint(P1, @var{T})} in the @var{target} basis. ## ## Example ## @example ## # standard basis transform ## src = [0 0 1 0 0 1]; ## # @var{target} transform, just a rotation by atan(2/3) followed by a scaling ## tgt = [0 0 .75 .5 -.5 .75]; ## # compute transform ## trans = createBasisTransform(src, tgt); ## # transform the point (.25,1.25) into the point (1,1) ## p1 = [.25 1.25]; ## p2 = transformPoint(p1, trans) ## ans = ## 1 1 ## @end example ## ## @seealso{transforms2d} ## @end deftypefn function transfo = createBasisTransform(source, target) # init basis transform to identity t1 = eye(3); t2 = eye(3); if nargin==2 # from source to reference basis t1(1:2, 1) = source(3:4); t1(1:2, 2) = source(5:6); t1(1:2, 3) = source(1:2); else # if only one input, use first input as target basis, and leave the # first matrix to identity target = source; end # from reference to target basis t2(1:2, 1) = target(3:4); t2(1:2, 2) = target(5:6); t2(1:2, 3) = target(1:2); # compute transfo # same as: transfo = inv(t2)*t1; transfo = t2\t1; endfunction %!demo %! # standard basis transform %! src = [0 0 1 0 0 1]; %! # target transform, just a rotation by atan(2/3) followed by a scaling %! tgt = [0 0 .75 .5 -.5 .75]; %! # compute transform %! trans = createBasisTransform(src, tgt); %! # transform the point (.25,1.25) into the point (1,1) %! p1 = [.25 1.25]; %! p2 = transformPoint(p1, trans) geometry/inst/geom2d/vectorNorm.m0000644000175000017500000000673312035504503016723 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{nm} = } vectorNorm (@var{v}) ## @deftypefnx {Function File} {@var{nm} = } vectorNorm (@var{v},@var{n}) ## Compute norm of a vector, or of a set of vectors ## ## Without extra arguments, returns the euclidean norm of vector V. ## Optional argument @var{n} specifies the norm to use. N can be any value ## greater than 0. ## @table @samp ## @item N=1 ## City lock norm. ## @item N=2 ## Euclidean norm. ## @item N=inf ## Compute max coord. ## @end table ## ## When @var{v} is a MxN array, compute norm for each vector of the array. ## Vector are given as rows. Result is then a Mx1 array. ## ## Example ## ## @example ## n1 = vectorNorm([3 4]) ## n1 = ## 5 ## ## n2 = vectorNorm([1, 10], inf) ## n2 = ## 10 ## @end example ## ## @seealso{vectors2d, vectorAngle} ## @end deftypefn function n = vectorNorm(v, varargin) # size of vector dim = size(v); # extract the type of norm to compute d = 2; if ~isempty(varargin) d = varargin{1}; end if d==2 # euclidean norm: sum of squared coordinates, and take square root if dim(1)==1 || dim(2)==1 n = sqrt(sum(v.*v)); else n = sqrt(sum(v.*v, 2)); end elseif d==1 # absolute norm: sum of absolute coordinates if dim(1)==1 || dim(2)==1 n = sum(abs(v)); else n = sum(abs(v), 2); end elseif d==inf # infinite norm: uses the maximal corodinate if dim(1)==1 || dim(2)==1 n = max(v); else n = max(v, [], 2); end else # Other norms, use explicit but slower expression if dim(1)==1 || dim(2)==1 n = power(sum(power(v, d)), 1/d); else n = power(sum(power(v, d), 2), 1/d); end end endfunction %!assert (5, vectorNorm ([3 4])) %!assert(10, vectorNorm ([1, 10], inf)) geometry/inst/geom2d/circleAsPolygon.m0000644000175000017500000000514512035504503017656 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{P} = } circleAsPolygon (@var{circle}, @var{N}) ## Convert a circle into a series of points ## ## P = circleAsPolygon(CIRCLE, N); ## convert circle given as [x0 y0 r], where x0 and y0 are coordinate of ## center, and r is the radius, into an array of [(N+1)x2] double, ## containing x and y values of points. ## The polygon is closed ## ## P = circleAsPolygon(CIRCLE); ## uses a default value of N=64 points ## ## Example ## circle = circleAsPolygon([10 0 5], 16); ## figure; ## drawPolygon(circle); ## ## @seealso{circles2d, polygons2d, createCircle} ## @end deftypefn function varargout = circleAsPolygon(circle, varargin) # determines number of points N = 64; if ~isempty(varargin) N = varargin{1}; end # create circle t = linspace(0, 2*pi, N+1)'; x = circle(1) + circle(3)*cos(t); y = circle(2) + circle(3)*sin(t); if nargout==1 varargout{1}=[x y]; elseif nargout==2 varargout{1}=x; varargout{2}=y; end endfunction geometry/inst/geom2d/drawOrientedBox.m0000644000175000017500000000720312035504503017656 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{hb} = } drawOrientedBox (@var{box}) ## @deftypefnx {Function File} {@var{hb} = } drawOrientedBox (@dots{}, @var{param}, @var{value}) ## Draw centered oriented rectangle. ## ## Syntax ## drawOrientedBox(BOX) ## drawOrientedBox(BOX, 'PropertyName', propertyvalue, ...) ## ## Description ## drawOrientedBox(OBOX) ## Draws an oriented rectangle (or bounding box) on the current axis. ## OBOX is a 1-by-5 row vector containing box center, dimension (length ## and width) and orientation (in degrees): ## OBOX = [CX CY LENGTH WIDTH THETA]. ## ## When OBOX is a N-by-5 array, the N boxes are drawn. ## ## HB = drawOrientedBox(...) ## Returns a handle to the created graphic object(s). Object style can be ## modified using syntaw like: ## set(HB, 'color', 'g', 'linewidth', 2); ## ## @seealso{drawPolygon, drawRect, drawBox} ## @end deftypefn function varargout = drawOrientedBox(box, varargin) ## Parses input arguments if nargin > 4 && sum(cellfun(@isnumeric, varargin(1:4))) == 4 cx = box; cy = varargin{1}; hl = varargin{2} / 2; hw = varargin{3} / 2; theta = varargin{4}; varargin = varargin(5:end); else cx = box(:,1); cy = box(:,2); hl = box(:,3) / 2; hw = box(:,4) / 2; theta = box(:,5); end ## Draw each box # allocate memory for graphical handle hr = zeros(length(cx), 1); # iterate on oriented boxes for i = 1:length(cx) # pre-compute angle data cot = cosd(theta(i)); sit = sind(theta(i)); # x and y shifts lc = hl(i) * cot; ls = hl(i) * sit; wc = hw(i) * cot; ws = hw(i) * sit; # coordinates of box vertices vx = cx(i) + [-lc + ws; lc + ws ; lc - ws ; -lc - ws ; -lc + ws]; vy = cy(i) + [-ls - wc; ls - wc ; ls + wc ; -ls + wc ; -ls - wc]; # draw polygons hr(i) = line(vx, vy, varargin{:}); end ## Format output if nargout > 0 varargout = {hr}; end endfunction geometry/inst/geom2d/drawBox.m0000644000175000017500000000534012035504503016164 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawBox (@var{box}) ## @deftypefnx {Function File} {@var{h} =} drawBox (@var{box}, @var{param}, @var{value}, @dots{}) ## Draw a box defined by coordinate extents ## ## Draws a box defined by its extent: @var{box} = [@var{xmin} @var{xmax} ## @var{ymin} @var{ymax}]. Addtional ## arguments are passed to function @code{plot}. If requested, it returns the ## handle to the graphics object created. ## ## @seealso{drawOrientedBox, drawRect, plot} ## @end deftypefn function varargout = drawBox(box, varargin) # default values xmin = box(:,1); xmax = box(:,2); ymin = box(:,3); ymax = box(:,4); nBoxes = size(box, 1); r = zeros(nBoxes, 1); # iterate on boxes for i = 1:nBoxes # exract min and max values tx(1) = xmin(i); ty(1) = ymin(i); tx(2) = xmax(i); ty(2) = ymin(i); tx(3) = xmax(i); ty(3) = ymax(i); tx(4) = xmin(i); ty(4) = ymax(i); tx(5) = xmin(i); ty(5) = ymin(i); # display polygon r(i) = plot(tx, ty, varargin{:}); end # format output if nargout > 0 varargout = {r}; end endfunction geometry/inst/geom2d/mergeBoxes.m0000644000175000017500000000513612035504503016661 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{box} =} mergeBoxes (@var{box1}, @var{box2}) ## Merge two boxes, by computing their greatest extent. ## # Example ## ## @example ## box1 = [5 20 5 30]; ## box2 = [0 15 0 15]; ## mergeBoxes(box1, box2) ## ans = ## 0 20 0 30 ## @end example ## ## @seealso{boxes2d, drawBox, intersectBoxes} ## @end deftypefn function bb = mergeBoxes(box1, box2) # unify sizes of data if size(box1,1) == 1 box1 = repmat(box1, size(box2,1), 1); elseif size(box2, 1) == 1 box2 = repmat(box2, size(box1,1), 1); elseif size(box1,1) != size(box2,1) error('geom2d:Error', 'Bad size for inputs'); end # compute extreme coords mini = min(box1(:,[1 3]), box2(:,[1 3])); maxi = max(box1(:,[2 4]), box2(:,[2 4])); # concatenate result into a new box structure bb = [mini(:,1) maxi(:,1) mini(:,2) maxi(:,2)]; endfunction %!test %! box1 = [5 20 10 25]; %! box2 = [0 15 15 20]; %! res = [0 20 10 25]; %! bb = mergeBoxes(box1, box2); %! assert (res, bb, 1e-6); geometry/inst/geom2d/drawLabels.m0000644000175000017500000000673112035676207016656 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawLabels (@var{x}, @var{y}, @var{lbl}) ## @deftypefnx {Function File} drawLabels (@var{pos}, @var{lbl}) ## @deftypefnx {Function File} drawLabels (@dots{}, @var{numbers}, @var{format}) ## Draw labels at specified positions. ## ## DRAWLABELS(X, Y, LBL) draw labels LBL at position X and Y. ## LBL can be either a string array, or a number array. In this case, ## string are created by using sprintf function, with '#.2f' mask. ## ## DRAWLABELS(POS, LBL) draw labels LBL at position specified by POS, ## where POS is a N*2 int array. ## ## DRAWLABELS(..., NUMBERS, FORMAT) create labels using sprintf function, ## with the mask given by FORMAT (e. g. '#03d' or '5.3f'), and the ## corresponding values. ## @end deftypefn function varargout = drawLabels(varargin) # check if enough inputs are given if isempty(varargin) error('wrong number of arguments in drawLabels'); end # process input parameters var = varargin{1}; if size(var, 2)==1 if length(varargin)<3 error('wrong number of arguments in drawLabels'); end px = var; py = varargin{2}; lbl = varargin{3}; varargin(1:3) = []; else if length(varargin)<2 error('wrong number of arguments in drawLabels'); end px = var(:,1); py = var(:,2); lbl = varargin{2}; varargin(1:2) = []; end format = '%.2f'; if ~isempty(varargin) format = varargin{1}; end if size(format, 1)==1 && size(px, 1)>1 format = repmat(format, size(px, 1), 1); end labels = cell(length(px), 1); if isnumeric(lbl) for i=1:length(px) labels{i} = sprintf(format(i,:), lbl(i)); end elseif ischar(lbl) for i=1:length(px) labels{i} = lbl(i,:); end elseif iscell(lbl) labels = lbl; end labels = char(labels); h = text(px, py, labels); if nargout>0 varargout{1}=h; end endfunction geometry/inst/geom2d/lineAngle.m0000644000175000017500000000723112035504503016455 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{theta} =} lineAngle(varargin) ## Computes angle between two straight lines ## ## A = lineAngle(LINE); ## Returns the angle between horizontal, right-axis and the given line. ## Angle is fiven in radians, between 0 and 2*pi, in counter-clockwise ## direction. ## ## A = lineAngle(LINE1, LINE2); ## Returns the directed angle between the two lines. Angle is given in ## radians between 0 and 2*pi, in counter-clockwise direction. ## ## @seealso{lines2d, angles2d, createLine, normalizeAngle} ## @end deftypefn function theta = lineAngle(varargin) nargs = length(varargin); if nargs == 1 # angle of one line with horizontal line = varargin{1}; theta = mod(atan2(line(:,4), line(:,3)) + 2*pi, 2*pi); elseif nargs==2 # angle between two lines theta1 = lineAngle(varargin{1}); theta2 = lineAngle(varargin{2}); theta = mod(bsxfun(@minus, theta2, theta1)+2*pi, 2*pi); end endfunction # horizontal %!test %! line1 = createLine([2 3 1 0]); %! assert (lineAngle(line1), 0, 1e-6); %!test %! line1 = createLine([2 3 0 1]); %! assert (lineAngle(line1), pi/2, 1e-6); %!test %! line1 = createLine([2 3 1 1]); %! assert (lineAngle(line1), pi/4, 1e-6); %!test %! line1 = createLine([2 3 5 -1]); %! assert (lineAngle(line1), mod(atan2(-1, 5)+2*pi, 2*pi), 1e-6); %!test %! line1 = createLine([2 3 5000 -1000]); %! assert (lineAngle(line1), mod(atan2(-1, 5)+2*pi, 2*pi), 1e-6); %!test %! line1 = createLine([2 3 -1 0]); %! assert (lineAngle(line1), pi, 1e-6); # test lineAngle with two parameters : angle between 2 lines # check for 2 orthogonal lines %!test %! line1 = createLine([1 3 1 0]); %! line2 = createLine([-2 -1 0 1]); %! assert (lineAngle(line1, line2), pi/2, 1e-6); %! assert (lineAngle(line2, line1), 3*pi/2, 1e-6); # check for 2 orthogonal lines, with very different parametrizations %!test %! line1 = createLine([1 3 1 1]); %! line2 = createLine([-2 -1 -1000 1000]); %! assert (lineAngle(line1, line2), pi/2, 1e-6); %! assert (lineAngle(line2, line1), 3*pi/2, 1e-6); geometry/inst/geom2d/createCircle.m0000644000175000017500000001032212035504503017137 0ustar juanpijuanpi## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{circle} = } createCircle (@var{p1}, @var{p2}, @var{p3}) ## @deftypefnx {Function File} {@var{circle} = } createCircle (@var{p1}, @var{p2}) ## Create a circle from 2 or 3 points. ## ## Creates the circle passing through the 3 given points. ## C is a 1x3 array of the form: [XC YX R]. ## ## When two points are given, creates the circle whith center @var{p1} and passing ## throuh the point @var{p2}. ## ## Works also when input are point arrays the same size, in this case the ## result has as many lines as the point arrays. ## ## Example ## ## @example ## # Draw a circle passing through 3 points. ## p1 = [10 15]; ## p2 = [15 20]; ## p3 = [10 25]; ## circle = createCircle(p1, p2, p3); ## figure; hold on; axis equal; axis([0 50 0 50]); ## drawPoint([p1 ; p2; p3]); ## drawCircle(circle); ## @end example ## ## @seealso{circles2d, createDirectedCircle} ## @end deftypefn function circle = createCircle(varargin) if nargin == 2 # inputs are the center and a point on the circle p1 = varargin{1}; p2 = varargin{2}; x0 = p1(:,1); y0 = p1(:,2); r = hypot((p2(:,1)-x0), (p2(:,2)-y0)); elseif nargin == 3 # inputs are three points on the circle p1 = varargin{1}; p2 = varargin{2}; p3 = varargin{3}; # compute circle center line1 = medianLine(p1, p2); line2 = medianLine(p1, p3); point = intersectLines(line1, line2); x0 = point(:, 1); y0 = point(:, 2); # circle radius r = hypot((p1(:,1)-x0), (p1(:,2)-y0)); end # create array for returning result circle = [x0 y0 r]; endfunction %!shared privpath %! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private']; %!test %! addpath (privpath,'-end') %! p1 = [10 15]; %! p2 = [15 20]; %! p3 = [10 25]; %! exp = [10 20 5]; %! circle = createCircle(p1, p2, p3); %! assertEqual(exp, circle); %! circle = createCircle(p3, p1, p2); %! assertEqual(exp, circle); %! circle = createCircle(p2, p3, p1); %! assertEqual(exp, circle); %! rmpath (privpath); %!test %! addpath (privpath,'-end') %! p1 = [10 15]; %! p2 = [15 20]; %! p3 = [10 25]; %! exp = [10 20 5]; %! p1 = [p1; p1+10; p1+20; p1-5]; %! p2 = [p2; p2+10; p2+20; p2-5]; %! p3 = [p3; p3+10; p3+20; p3-5]; %! exp = repmat(exp, 4, 1) + [0 0 0;10 10 0;20 20 0;-5 -5 0]; %! circle = createCircle(p1, p2, p3); %! assertEqual(exp, circle); %! circle = createCircle(p3, p1, p2); %! assertEqual(exp, circle); %! circle = createCircle(p2, p3, p1); %! assertEqual(exp, circle); %! rmpath (privpath); geometry/inst/io/0000755000175000017500000000000012130276034013631 5ustar juanpijuanpigeometry/inst/io/drawing3.svg0000644000175000017500000000205211650352340016070 0ustar juanpijuanpi image/svg+xml geometry/inst/io/drawing4.svg0000644000175000017500000000407011650352340016073 0ustar juanpijuanpi image/svg+xml geometry/inst/io/drawing5.svg0000644000175000017500000000374611650352340016105 0ustar juanpijuanpi image/svg+xml geometry/inst/io/drawing.svg0000644000175000017500000000340111650352340016004 0ustar juanpijuanpi image/svg+xml geometry/inst/io/private/0000755000175000017500000000000012130276034015303 5ustar juanpijuanpigeometry/inst/io/private/ruledSurfGeo.m0000644000175000017500000000333112035676207020101 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{str} = ruledSurfGeo (@var{id}, @var{nloop}, @var{loops}, @var{centerid}) ## Generates a string for Gmsh Ruled Surface format. ## ## Creates a ruled surface with identifier @var{id}, i.e., a surface that can be ## interpolated using transfinite interpolation. @var{nloop} indicates the number ## of loops that define the surface. @var{loops} should contain the identification ## number of a line loop composed of either three or four elementary lines. ## @var{centerid} is the identification number of the center of the sphere, this ## forces the surface to be a spherical patch. ## ## @end deftypefn function str = ruledSurfGeo(id,nloop,loops,centerid) substr = repmat(',%d',1,nloop-1); if ~isempty(centerid) str = sprintf(['Ruled Surface(%d) = {%d' substr '} In Sphere {%d};\n'], ... id,loops,centerid); else error('data2geo:Error',"The id of the centers shouldn't be empty"); end end geometry/inst/io/private/lineLoopGeo.m0000644000175000017500000000264412035676207017715 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{str} = lineLoopGeo (@var{id}, @var{nl}, @var{lns}) ## Generates a string for Gmsh Line Loop format. ## ## The third elementary entity is the surface. In order to define a ## simple rectangular surface from defined lines, a ## line loop has first to be defined. A line loop is a list of ## connected lines, a sign being associated with each line (depending ## on the orientation of the line). @var{id} is an indentifier for the loop. ## @var{nl} is the number of lines in the loop. @var{lns} is the list of lines. ## ## @end deftypefn function str = lineLoopGeo(id,nl,lns) substr = repmat(',%d',1,nl-1); str = sprintf(['Line Loop(%d) = {%d' substr '};\n'],id,lns); end geometry/inst/io/private/inkex.py0000644000175000017500000002020011767211422016772 0ustar juanpijuanpi#!/usr/bin/env python """ inkex.py A helper module for creating Inkscape extensions Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ import sys, copy, optparse, random, re import gettext from math import * _ = gettext.gettext #a dictionary of all of the xmlns prefixes in a standard inkscape doc NSS = { u'sodipodi' :u'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd', u'cc' :u'http://creativecommons.org/ns#', u'ccOLD' :u'http://web.resource.org/cc/', u'svg' :u'http://www.w3.org/2000/svg', u'dc' :u'http://purl.org/dc/elements/1.1/', u'rdf' :u'http://www.w3.org/1999/02/22-rdf-syntax-ns#', u'inkscape' :u'http://www.inkscape.org/namespaces/inkscape', u'xlink' :u'http://www.w3.org/1999/xlink', u'xml' :u'http://www.w3.org/XML/1998/namespace' } #a dictionary of unit to user unit conversion factors uuconv = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, 'm':3543.3070866, 'km':3543307.0866, 'pc':15.0, 'yd':3240 , 'ft':1080} def unittouu(string): '''Returns userunits given a string representation of units in another system''' unit = re.compile('(%s)$' % '|'.join(uuconv.keys())) param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') p = param.match(string) u = unit.search(string) if p: retval = float(p.string[p.start():p.end()]) else: retval = 0.0 if u: try: return retval * uuconv[u.string[u.start():u.end()]] except KeyError: pass return retval def uutounit(val, unit): return val/uuconv[unit] try: from lxml import etree except: sys.exit(_('The fantastic lxml wrapper for libxml2 is required by inkex.py and therefore this extension. Please download and install the latest version from http://cheeseshop.python.org/pypi/lxml/, or install it through your package manager by a command like: sudo apt-get install python-lxml')) def debug(what): sys.stderr.write(str(what) + "\n") return what def errormsg(msg): """Intended for end-user-visible error messages. (Currently just writes to stderr with an appended newline, but could do something better in future: e.g. could add markup to distinguish error messages from status messages or debugging output.) Note that this should always be combined with translation: import gettext _ = gettext.gettext ... inkex.errormsg(_("This extension requires two selected paths.")) """ sys.stderr.write((unicode(msg) + "\n").encode("UTF-8")) def check_inkbool(option, opt, value): if str(value).capitalize() == 'True': return True elif str(value).capitalize() == 'False': return False else: raise optparse.OptionValueError("option %s: invalid inkbool value: %s" % (opt, value)) def addNS(tag, ns=None): val = tag if ns!=None and len(ns)>0 and NSS.has_key(ns) and len(tag)>0 and tag[0]!='{': val = "{%s}%s" % (NSS[ns], tag) return val class InkOption(optparse.Option): TYPES = optparse.Option.TYPES + ("inkbool",) TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER) TYPE_CHECKER["inkbool"] = check_inkbool class Effect: """A class for creating Inkscape SVG Effects""" def __init__(self, *args, **kwargs): self.document=None self.ctx=None self.selected={} self.doc_ids={} self.options=None self.args=None self.OptionParser = optparse.OptionParser(usage="usage: %prog [options] SVGfile",option_class=InkOption) self.OptionParser.add_option("--id", action="append", type="string", dest="ids", default=[], help="id attribute of object to manipulate") def effect(self): pass def getoptions(self,args=sys.argv[1:]): """Collect command line arguments""" self.options, self.args = self.OptionParser.parse_args(args) def parse(self,file=None): """Parse document in specified file or on stdin""" try: try: stream = open(file,'r') except: stream = open(self.svg_file,'r') except: stream = sys.stdin self.document = etree.parse(stream) stream.close() def getposinlayer(self): #defaults self.current_layer = self.document.getroot() self.view_center = (0.0,0.0) layerattr = self.document.xpath('//sodipodi:namedview/@inkscape:current-layer', namespaces=NSS) if layerattr: layername = layerattr[0] layer = self.document.xpath('//svg:g[@id="%s"]' % layername, namespaces=NSS) if layer: self.current_layer = layer[0] xattr = self.document.xpath('//sodipodi:namedview/@inkscape:cx', namespaces=NSS) yattr = self.document.xpath('//sodipodi:namedview/@inkscape:cy', namespaces=NSS) doc_height = unittouu(self.document.getroot().get('height')) if xattr and yattr: x = xattr[0] y = yattr[0] if x and y: self.view_center = (float(x), doc_height - float(y)) # FIXME: y-coordinate flip, eliminate it when it's gone in Inkscape def getselected(self): """Collect selected nodes""" for i in self.options.ids: path = '//*[@id="%s"]' % i for node in self.document.xpath(path, namespaces=NSS): self.selected[i] = node def getElementById(self, id): path = '//*[@id="%s"]' % id el_list = self.document.xpath(path, namespaces=NSS) if el_list: return el_list[0] else: return None def getParentNode(self, node): for parent in self.document.getiterator(): if node in parent.getchildren(): return parent break def getdocids(self): docIdNodes = self.document.xpath('//@id', namespaces=NSS) for m in docIdNodes: self.doc_ids[m] = 1 def getNamedView(self): return self.document.xpath('//sodipodi:namedview', namespaces=NSS)[0] def createGuide(self, posX, posY, angle): atts = { 'position': str(posX)+','+str(posY), 'orientation': str(sin(radians(angle)))+','+str(-cos(radians(angle))) } guide = etree.SubElement( self.getNamedView(), addNS('guide','sodipodi'), atts ) return guide def output(self): """Serialize document into XML on stdout""" self.document.write(sys.stdout) def affect(self, args=sys.argv[1:], output=True): """Affect an SVG document with a callback effect""" self.svg_file = args[-1] self.getoptions(args) self.parse() self.getposinlayer() self.getselected() self.getdocids() self.effect() if output: self.output() def uniqueId(self, old_id, make_new_id = True): new_id = old_id if make_new_id: while new_id in self.doc_ids: new_id += random.choice('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') self.doc_ids[new_id] = 1 return new_id def xpathSingle(self, path): try: retval = self.document.xpath(path, namespaces=NSS)[0] except: errormsg(_("No matching node for expression: %s") % path) retval = None return retval # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 geometry/inst/io/private/simplepath.py0000644000175000017500000001564211767211422020040 0ustar juanpijuanpi#!/usr/bin/env python """ simplepath.py functions for digesting paths into a simple list structure Copyright (C) 2005 Aaron Spike, aaron@ekips.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ import re, math def lexPath(d): """ returns and iterator that breaks path data identifies command and parameter tokens """ offset = 0 length = len(d) delim = re.compile(r'[ \t\r\n,]+') command = re.compile(r'[MLHVCSQTAZmlhvcsqtaz]') parameter = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') while 1: m = delim.match(d, offset) if m: offset = m.end() if offset >= length: break m = command.match(d, offset) if m: yield [d[offset:m.end()], True] offset = m.end() continue m = parameter.match(d, offset) if m: yield [d[offset:m.end()], False] offset = m.end() continue #TODO: create new exception raise Exception, 'Invalid path data!' ''' pathdefs = {commandfamily: [ implicitnext, #params, [casts,cast,cast], [coord type,x,y,0] ]} ''' pathdefs = { 'M':['L', 2, [float, float], ['x','y']], 'L':['L', 2, [float, float], ['x','y']], 'H':['H', 1, [float], ['x']], 'V':['V', 1, [float], ['y']], 'C':['C', 6, [float, float, float, float, float, float], ['x','y','x','y','x','y']], 'S':['S', 4, [float, float, float, float], ['x','y','x','y']], 'Q':['Q', 4, [float, float, float, float], ['x','y','x','y']], 'T':['T', 2, [float, float], ['x','y']], 'A':['A', 7, [float, float, float, int, int, float, float], ['r','r','a',0,'s','x','y']], 'Z':['L', 0, [], []] } def parsePath(d): """ Parse SVG path and return an array of segments. Removes all shorthand notation. Converts coordinates to absolute. """ retval = [] lexer = lexPath(d) pen = (0.0,0.0) subPathStart = pen lastControl = pen lastCommand = '' while 1: try: token, isCommand = lexer.next() except StopIteration: break params = [] needParam = True if isCommand: if not lastCommand and token.upper() != 'M': raise Exception, 'Invalid path, must begin with moveto.' else: command = token else: #command was omited #use last command's implicit next command needParam = False if lastCommand: if lastCommand.isupper(): command = pathdefs[lastCommand][0] else: command = pathdefs[lastCommand.upper()][0].lower() else: raise Exception, 'Invalid path, no initial command.' numParams = pathdefs[command.upper()][1] while numParams > 0: if needParam: try: token, isCommand = lexer.next() if isCommand: raise Exception, 'Invalid number of parameters' except StopIteration: raise Exception, 'Unexpected end of path' cast = pathdefs[command.upper()][2][-numParams] param = cast(token) if command.islower(): if pathdefs[command.upper()][3][-numParams]=='x': param += pen[0] elif pathdefs[command.upper()][3][-numParams]=='y': param += pen[1] params.append(param) needParam = True numParams -= 1 #segment is now absolute so outputCommand = command.upper() #Flesh out shortcut notation if outputCommand in ('H','V'): if outputCommand == 'H': params.append(pen[1]) if outputCommand == 'V': params.insert(0,pen[0]) outputCommand = 'L' if outputCommand in ('S','T'): params.insert(0,pen[1]+(pen[1]-lastControl[1])) params.insert(0,pen[0]+(pen[0]-lastControl[0])) if outputCommand == 'S': outputCommand = 'C' if outputCommand == 'T': outputCommand = 'Q' #current values become "last" values if outputCommand == 'M': subPathStart = tuple(params[0:2]) pen = subPathStart if outputCommand == 'Z': pen = subPathStart else: pen = tuple(params[-2:]) if outputCommand in ('Q','C'): lastControl = tuple(params[-4:-2]) else: lastControl = pen lastCommand = command retval.append([outputCommand,params]) return retval def formatPath(a): """Format SVG path data from an array""" return "".join([cmd + " ".join([str(p) for p in params]) for cmd, params in a]) def translatePath(p, x, y): for cmd,params in p: defs = pathdefs[cmd] for i in range(defs[1]): if defs[3][i] == 'x': params[i] += x elif defs[3][i] == 'y': params[i] += y def scalePath(p, x, y): for cmd,params in p: defs = pathdefs[cmd] for i in range(defs[1]): if defs[3][i] == 'x': params[i] *= x elif defs[3][i] == 'y': params[i] *= y elif defs[3][i] == 'r': # radius parameter params[i] *= x elif defs[3][i] == 's': # sweep-flag parameter if x*y < 0: params[i] = 1 - params[i] elif defs[3][i] == 'a': # x-axis-rotation angle if y < 0: params[i] = - params[i] def rotatePath(p, a, cx = 0, cy = 0): if a == 0: return p for cmd,params in p: defs = pathdefs[cmd] for i in range(defs[1]): if defs[3][i] == 'x': x = params[i] - cx y = params[i + 1] - cy r = math.sqrt((x**2) + (y**2)) if r != 0: theta = math.atan2(y, x) + a params[i] = (r * math.cos(theta)) + cx params[i + 1] = (r * math.sin(theta)) + cy # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 geometry/inst/io/private/pointGeo.m0000644000175000017500000000256212035676207017264 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{str} = poointGeo (@var{n}, @var{xyz}, @var{l}) ## Generates a string for Gmsh Point format. ## ## Gmsh's simplest `elementary entity', a `Point'. A Point is defined by a list ## of five numbers: @var{n} the identificator, @var{xyz} three coordinates (X, Y ## and Z), and a characteristic length @var{l} that sets the target element size ## at the point: ## The distribution of the mesh element sizes is then obtained by ## interpolation of these characteristic lengths throughout the ## geometry. ## ## @end deftypefn function str = pointGeo(n,xyz,l) str = sprintf('Point(%d) = {%.16g,%.16g,%.16g,%.16g};\n',n,xyz,l); end geometry/inst/io/private/planeSurfGeo.m0000644000175000017500000000335412035676207020072 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{str} = planeSurfGeo (@var{id}, @var{nloop},@var{loops}) ## Generates a string for Gmsh Plane Surface format. ## ## @var{id} is the plane surface's identification number. ## @var{nloop} is the number of loops defining the surface. ## @var{loops} contain the identification numbers of all the line loops defining ## the surface. The first line loop defines the exterior boundary of the surface; ## all other line loops define holes in the surface. A line loop defining a hole ## should not have any lines in common with the exterior line loop (in which case ## it is not a hole, and the two surfaces should be defined separately). ## Likewise, a line loop defining a hole should not have any lines in common with ## another line loop defining a hole in the same surface (in which case the two ## line loops should be combined). ## ## @end deftypefn function str = planeSurfGeo(id,nloop,loops) substr = repmat(',%d',1,nloop-1); str = sprintf(['Plane Surface(%d) = {%d' substr '};\n'],id,loops); end geometry/inst/io/private/lineGeo.m0000644000175000017500000000232012035676207017052 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{str} = lineGeo (@var{n}, @var{pi}, @var{pj}) ## Generates a string for Gmsh Line format. ## ## Curves are Gmsh's second type of elementery entities, and, ## amongst curves, straight lines are the simplest. A straight line is ## defined by a list of point numbers. The initial point @var{pi}, the final ## point @var{pj}. @var{n} is an indetifier for the line. ## ## @end deftypefn function str = lineGeo(n,i,j) str = sprintf('Line(%d) = {%d,%d};\n',n,i,j); end geometry/inst/io/data2geo.m0000644000175000017500000000700112035701351015472 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{fileStr} =} data2geo (@var{data}, @var{lc}) ## @deftypefnx {Function File} {@var{fileStr} =} data2geo (@dots{}, @var{param}, @var{value}) ## Uses data to build a file compatible with Gmsh. ## ## @var{data} is assumed to describe a polygon in @code{polygon2d} format. ## The argument @var{lc} specifies the edge size. ## ## The optional parameters can be 'output' followed with a string specifying a file ## to write, and 'spherical' followed by a real number @var{r} indicating that the ## polygon describes a spherical surface of radious @var{r}. ## ## @seealso{polygon2d, @@svg/path2polygon} ## @end deftypefn function strFile = data2geo(data,lc,varargin) nl = @()sprintf('\n'); ## Parse options filegiven = []; spherical = []; if nargin > 2 filegiven = find(cellfun(@(x)strcmpi(x,'output'),varargin)); spherical = find(cellfun(@(x)strcmpi(x,'spherical'),varargin)); end [n dim] = size(data); if dim == 2 data(:,3) = zeros(n,1); end header = ' // File created with Octave'; strFile = []; strFile = [strFile header nl()]; # Points strFile = [strFile '// Points' nl()]; for i=1:n strFile = [strFile pointGeo(i,data(i,:),lc)]; end # Lines strFile = [strFile '// Lines' nl()]; for i=1:n-1 strFile = [strFile lineGeo(i,i,i+1)]; end strFile = [strFile lineGeo(n,n,1)]; # Loop strFile = [strFile lineLoopGeo(n+1,n,1:n)]; # Surface if spherical sphr = varargin{spherical+1}; if dim ==2 sphr(1,3) = 0; end strFile = [strFile pointGeo(n+1,sphr,lc)]; strFile = [strFile ruledSurfGeo(n+3,1,n+1,n+1)]; else strFile = [strFile planeSurfGeo(n+2,1,n+1)]; end if filegiven outfile = varargin{filegiven+1}; fid = fopen(outfile,'w'); fprintf(fid,'%s',strFile); fclose(fid); disp(['DATA2GEO: Geometry file saved to ' outfile]) end endfunction %!demo %! points = [0 0 0; 0.1 0 0; 0.1 .3 0; 0 0.3 0]; %! strFile = data2geo(points,0.009); %! disp(strFile) %!demo %! dc = svg('drawing6.svg'); %! ids = dc.pathid(); %! P = dc.path2polygon(ids{1},12)(1:end-1,:); %! P = bsxfun(@minus, P, centroid(P)); %! P = simplifypolygon(P,'tol',5e-1); %! filename = tmpnam (); %! meshsize = sqrt(mean(sumsq(diff(P,1,1),2)))/2; %! data2geo (P, meshsize, 'output', [filename '.geo']); %! %! pkg load msh fpl %! T = msh2m_gmsh(filename); %! pdemesh(T.p,T.e,T.t) %! %! # -------------------------------------------------------------------------- %! # We load the drawing6.svg file into Octave and transform it into a polygon. %! # Then we create a temporary file where the .geo mesh will be written. %! # If the packages msh and fpl are available, a mesh is created from the .geo %! # file. geometry/inst/io/drawing2.svg0000644000175000017500000000371711650352340016100 0ustar juanpijuanpi image/svg+xml geometry/inst/io/drawing6.svg0000644000175000017500000000260411654115537016107 0ustar juanpijuanpi image/svg+xml geometry/inst/io/@svg/0000755000175000017500000000000012130276034014530 5ustar juanpijuanpigeometry/inst/io/@svg/pathid.m0000644000175000017500000000156212035504503016162 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} function_name () ## @end deftypefn function ids = pathid(obj,varargin) ids = fieldnames (obj.Path); endfunction geometry/inst/io/@svg/svg.m0000644000175000017500000000477412035504503015520 0ustar juanpijuanpi## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{obj} =} svg () ## @deftypefnx {Function File} {@var{obj} =} svg (@var{str}) ## Create object of the svg class. ## ## If no input argument is provided the object is empty. @var{str} can be a filename ## or a string defining an inline SVG. ## ## @end deftypefn function svg = svg(name='') svg = struct; ## SVG data. All the attributes of the node. ## The field unparsed contains all the attributes that are not being parsed. svg.Data = struct('height',[],'width',[],'id','null','normalized',false); ## SVG metadata. All the attributes of the node. ## The field unparsed contains all the attributes that are not being parsed. svg.Metadata = struct('unparsed',' '); ## SVG paths. It is a vector of path structs. Maybe path can be a object too? ## Order of Path.Data is important so we store in a cell (could be a matrix padded with zeros). ## All the paths stored in polyval compatible format. Straigth segments are also stored as a polynomial. svg.Path = struct(); svg = class (svg, 'svg'); if !isempty (name) if exist(name,"file") == 2 name = file_in_path(path(), name); else error("svg:BadArguemnt", "File #s doesn't exist",name); end paths = loadpaths(svg, name); svg.Path = paths; data = loadsvgdata(svg, name); svg.Data = data; svg.Data.normalized = false; elseif !ischar(name) print_usage ; endif endfunction %!test %! dc = svg('drawing5.svg'); %! dc.getpath(); %! dc.pathid(); %! dc.getpath('path3756'); %! %! dc = svg('drawing.svg'); %! ids = dc.pathid(); %! dc.getpath({ids{[1 3]}}); %!test %! dc = svg('drawing6.svg'); %! ids = dc.pathid(); %! P = dc.path2polygon(ids{1}); %!test %! dc = svg('drawing6.svg'); %! dc.plot(); %! dc.plot('color','r','linewidth',2); ����geometry/inst/io/@svg/normalize.m�������������������������������������������������������������������0000644�0001750�0001750�00000005674�12035504503�016721� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{SVGn} = normalize (@var{SVG}) ## normalizes and SVG. ## @end deftypefn function [SVGn bb] = normalize (obj) SVGn = obj; bb = []; if ! obj.Data.normalized ids = fieldnames (obj.Path); npath = numel(ids); v = zeros(npath,2); bb = zeros(1,4); for ip = 1:npath v(ip,:) = shapecentroid(obj.Path.(ids{ip}).data); p = shape2polygon(obj.Path.(ids{ip}).data); bb = mergeBoxes(bb, [min(p) max(p)]([1 3 2 4])); end if npath > 1 v = mean(v)(:); else v = v.'; end ## check whether document and bounding box agree. bbHeight = bb(2)-bb(1); bbWidth = bb(4)-bb(2); if obj.Data.height != bbHeight warning("svg:normalize:Sanitycheck",... ["Height of SVG #g and height boundingbox #g don't match.\n" ... "Using bounding box.\n"],obj.Data.height,bbHeight) end if obj.Data.width != bbWidth warning("svg:normalize:Sanitycheck",... ["Width of SVG #g and width boundingbox #g don't match.\n" ... "Using bounding box.\n"],obj.Data.width,bbWidth) end ## Move paths such that center of SVG is at 0,0 ## Put coordinates in the usual frame ## Scale such that diagonal of bounding box is 1 Dnorm = sqrt (bbWidth ^ 2 + bbHeight ^ 2); S = (1 / Dnorm) * eye (2); bb = zeros(1,4); for ip = 1:npath SVGn.Path.(ids{ip}).data = shapetransform(obj.Path.(ids{ip}).data,-v); # Put to middle SVGn.Path.(ids{ip}).data = ... shapetransform(SVGn.Path.(ids{ip}).data,[0; -bbHeight/2]); # Reflect y SVGn.Path.(ids{ip}).data = ... shapetransform(SVGn.Path.(ids{ip}).data,[1 0;0 -1]); # Put to bottom SVGn.Path.(ids{ip}).data = ... shapetransform(SVGn.Path.(ids{ip}).data,[0; bbHeight/2]); # Scale SVGn.Path.(ids{ip}).data = ... shapetransform(SVGn.Path.(ids{ip}).data,S); p = shape2polygon(SVGn.Path.(ids{ip}).data); bb = mergeBoxes(bb, [min(p) max(p)]([1 3 2 4])); end bbHeight = bb(2)-bb(1); bbWidth = bb(4)-bb(2); SVGn.Data.height = bbHeight; SVGn.Data.width = bbWidth; SVGn.Data.normalized = true; end end ��������������������������������������������������������������������geometry/inst/io/@svg/width.m�����������������������������������������������������������������������0000644�0001750�0001750�00000001546�12035504503�016032� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} function_name () ## @end deftypefn function o = width(obj,varargin) o = obj.Data.width; endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/inkex.py����������������������������������������������������������������������0000644�0001750�0001750�00000020200�11767211422�016217� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python """ inkex.py A helper module for creating Inkscape extensions Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ import sys, copy, optparse, random, re import gettext from math import * _ = gettext.gettext #a dictionary of all of the xmlns prefixes in a standard inkscape doc NSS = { u'sodipodi' :u'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd', u'cc' :u'http://creativecommons.org/ns#', u'ccOLD' :u'http://web.resource.org/cc/', u'svg' :u'http://www.w3.org/2000/svg', u'dc' :u'http://purl.org/dc/elements/1.1/', u'rdf' :u'http://www.w3.org/1999/02/22-rdf-syntax-ns#', u'inkscape' :u'http://www.inkscape.org/namespaces/inkscape', u'xlink' :u'http://www.w3.org/1999/xlink', u'xml' :u'http://www.w3.org/XML/1998/namespace' } #a dictionary of unit to user unit conversion factors uuconv = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, 'm':3543.3070866, 'km':3543307.0866, 'pc':15.0, 'yd':3240 , 'ft':1080} def unittouu(string): '''Returns userunits given a string representation of units in another system''' unit = re.compile('(%s)$' % '|'.join(uuconv.keys())) param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') p = param.match(string) u = unit.search(string) if p: retval = float(p.string[p.start():p.end()]) else: retval = 0.0 if u: try: return retval * uuconv[u.string[u.start():u.end()]] except KeyError: pass return retval def uutounit(val, unit): return val/uuconv[unit] try: from lxml import etree except: sys.exit(_('The fantastic lxml wrapper for libxml2 is required by inkex.py and therefore this extension. Please download and install the latest version from http://cheeseshop.python.org/pypi/lxml/, or install it through your package manager by a command like: sudo apt-get install python-lxml')) def debug(what): sys.stderr.write(str(what) + "\n") return what def errormsg(msg): """Intended for end-user-visible error messages. (Currently just writes to stderr with an appended newline, but could do something better in future: e.g. could add markup to distinguish error messages from status messages or debugging output.) Note that this should always be combined with translation: import gettext _ = gettext.gettext ... inkex.errormsg(_("This extension requires two selected paths.")) """ sys.stderr.write((unicode(msg) + "\n").encode("UTF-8")) def check_inkbool(option, opt, value): if str(value).capitalize() == 'True': return True elif str(value).capitalize() == 'False': return False else: raise optparse.OptionValueError("option %s: invalid inkbool value: %s" % (opt, value)) def addNS(tag, ns=None): val = tag if ns!=None and len(ns)>0 and NSS.has_key(ns) and len(tag)>0 and tag[0]!='{': val = "{%s}%s" % (NSS[ns], tag) return val class InkOption(optparse.Option): TYPES = optparse.Option.TYPES + ("inkbool",) TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER) TYPE_CHECKER["inkbool"] = check_inkbool class Effect: """A class for creating Inkscape SVG Effects""" def __init__(self, *args, **kwargs): self.document=None self.ctx=None self.selected={} self.doc_ids={} self.options=None self.args=None self.OptionParser = optparse.OptionParser(usage="usage: %prog [options] SVGfile",option_class=InkOption) self.OptionParser.add_option("--id", action="append", type="string", dest="ids", default=[], help="id attribute of object to manipulate") def effect(self): pass def getoptions(self,args=sys.argv[1:]): """Collect command line arguments""" self.options, self.args = self.OptionParser.parse_args(args) def parse(self,file=None): """Parse document in specified file or on stdin""" try: try: stream = open(file,'r') except: stream = open(self.svg_file,'r') except: stream = sys.stdin self.document = etree.parse(stream) stream.close() def getposinlayer(self): #defaults self.current_layer = self.document.getroot() self.view_center = (0.0,0.0) layerattr = self.document.xpath('//sodipodi:namedview/@inkscape:current-layer', namespaces=NSS) if layerattr: layername = layerattr[0] layer = self.document.xpath('//svg:g[@id="%s"]' % layername, namespaces=NSS) if layer: self.current_layer = layer[0] xattr = self.document.xpath('//sodipodi:namedview/@inkscape:cx', namespaces=NSS) yattr = self.document.xpath('//sodipodi:namedview/@inkscape:cy', namespaces=NSS) doc_height = unittouu(self.document.getroot().get('height')) if xattr and yattr: x = xattr[0] y = yattr[0] if x and y: self.view_center = (float(x), doc_height - float(y)) # FIXME: y-coordinate flip, eliminate it when it's gone in Inkscape def getselected(self): """Collect selected nodes""" for i in self.options.ids: path = '//*[@id="%s"]' % i for node in self.document.xpath(path, namespaces=NSS): self.selected[i] = node def getElementById(self, id): path = '//*[@id="%s"]' % id el_list = self.document.xpath(path, namespaces=NSS) if el_list: return el_list[0] else: return None def getParentNode(self, node): for parent in self.document.getiterator(): if node in parent.getchildren(): return parent break def getdocids(self): docIdNodes = self.document.xpath('//@id', namespaces=NSS) for m in docIdNodes: self.doc_ids[m] = 1 def getNamedView(self): return self.document.xpath('//sodipodi:namedview', namespaces=NSS)[0] def createGuide(self, posX, posY, angle): atts = { 'position': str(posX)+','+str(posY), 'orientation': str(sin(radians(angle)))+','+str(-cos(radians(angle))) } guide = etree.SubElement( self.getNamedView(), addNS('guide','sodipodi'), atts ) return guide def output(self): """Serialize document into XML on stdout""" self.document.write(sys.stdout) def affect(self, args=sys.argv[1:], output=True): """Affect an SVG document with a callback effect""" self.svg_file = args[-1] self.getoptions(args) self.parse() self.getposinlayer() self.getselected() self.getdocids() self.effect() if output: self.output() def uniqueId(self, old_id, make_new_id = True): new_id = old_id if make_new_id: while new_id in self.doc_ids: new_id += random.choice('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') self.doc_ids[new_id] = 1 return new_id def xpathSingle(self, path): try: retval = self.document.xpath(path, namespaces=NSS)[0] except: errormsg(_("No matching node for expression: %s") % path) retval = None return retval # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/simplepath.py�����������������������������������������������������������������0000644�0001750�0001750�00000015642�11767211422�017265� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python """ simplepath.py functions for digesting paths into a simple list structure Copyright (C) 2005 Aaron Spike, aaron@ekips.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ import re, math def lexPath(d): """ returns and iterator that breaks path data identifies command and parameter tokens """ offset = 0 length = len(d) delim = re.compile(r'[ \t\r\n,]+') command = re.compile(r'[MLHVCSQTAZmlhvcsqtaz]') parameter = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') while 1: m = delim.match(d, offset) if m: offset = m.end() if offset >= length: break m = command.match(d, offset) if m: yield [d[offset:m.end()], True] offset = m.end() continue m = parameter.match(d, offset) if m: yield [d[offset:m.end()], False] offset = m.end() continue #TODO: create new exception raise Exception, 'Invalid path data!' ''' pathdefs = {commandfamily: [ implicitnext, #params, [casts,cast,cast], [coord type,x,y,0] ]} ''' pathdefs = { 'M':['L', 2, [float, float], ['x','y']], 'L':['L', 2, [float, float], ['x','y']], 'H':['H', 1, [float], ['x']], 'V':['V', 1, [float], ['y']], 'C':['C', 6, [float, float, float, float, float, float], ['x','y','x','y','x','y']], 'S':['S', 4, [float, float, float, float], ['x','y','x','y']], 'Q':['Q', 4, [float, float, float, float], ['x','y','x','y']], 'T':['T', 2, [float, float], ['x','y']], 'A':['A', 7, [float, float, float, int, int, float, float], ['r','r','a',0,'s','x','y']], 'Z':['L', 0, [], []] } def parsePath(d): """ Parse SVG path and return an array of segments. Removes all shorthand notation. Converts coordinates to absolute. """ retval = [] lexer = lexPath(d) pen = (0.0,0.0) subPathStart = pen lastControl = pen lastCommand = '' while 1: try: token, isCommand = lexer.next() except StopIteration: break params = [] needParam = True if isCommand: if not lastCommand and token.upper() != 'M': raise Exception, 'Invalid path, must begin with moveto.' else: command = token else: #command was omited #use last command's implicit next command needParam = False if lastCommand: if lastCommand.isupper(): command = pathdefs[lastCommand][0] else: command = pathdefs[lastCommand.upper()][0].lower() else: raise Exception, 'Invalid path, no initial command.' numParams = pathdefs[command.upper()][1] while numParams > 0: if needParam: try: token, isCommand = lexer.next() if isCommand: raise Exception, 'Invalid number of parameters' except StopIteration: raise Exception, 'Unexpected end of path' cast = pathdefs[command.upper()][2][-numParams] param = cast(token) if command.islower(): if pathdefs[command.upper()][3][-numParams]=='x': param += pen[0] elif pathdefs[command.upper()][3][-numParams]=='y': param += pen[1] params.append(param) needParam = True numParams -= 1 #segment is now absolute so outputCommand = command.upper() #Flesh out shortcut notation if outputCommand in ('H','V'): if outputCommand == 'H': params.append(pen[1]) if outputCommand == 'V': params.insert(0,pen[0]) outputCommand = 'L' if outputCommand in ('S','T'): params.insert(0,pen[1]+(pen[1]-lastControl[1])) params.insert(0,pen[0]+(pen[0]-lastControl[0])) if outputCommand == 'S': outputCommand = 'C' if outputCommand == 'T': outputCommand = 'Q' #current values become "last" values if outputCommand == 'M': subPathStart = tuple(params[0:2]) pen = subPathStart if outputCommand == 'Z': pen = subPathStart else: pen = tuple(params[-2:]) if outputCommand in ('Q','C'): lastControl = tuple(params[-4:-2]) else: lastControl = pen lastCommand = command retval.append([outputCommand,params]) return retval def formatPath(a): """Format SVG path data from an array""" return "".join([cmd + " ".join([str(p) for p in params]) for cmd, params in a]) def translatePath(p, x, y): for cmd,params in p: defs = pathdefs[cmd] for i in range(defs[1]): if defs[3][i] == 'x': params[i] += x elif defs[3][i] == 'y': params[i] += y def scalePath(p, x, y): for cmd,params in p: defs = pathdefs[cmd] for i in range(defs[1]): if defs[3][i] == 'x': params[i] *= x elif defs[3][i] == 'y': params[i] *= y elif defs[3][i] == 'r': # radius parameter params[i] *= x elif defs[3][i] == 's': # sweep-flag parameter if x*y < 0: params[i] = 1 - params[i] elif defs[3][i] == 'a': # x-axis-rotation angle if y < 0: params[i] = - params[i] def rotatePath(p, a, cx = 0, cy = 0): if a == 0: return p for cmd,params in p: defs = pathdefs[cmd] for i in range(defs[1]): if defs[3][i] == 'x': x = params[i] - cx y = params[i + 1] - cy r = math.sqrt((x**2) + (y**2)) if r != 0: theta = math.atan2(y, x) + a params[i] = (r * math.cos(theta)) + cx params[i + 1] = (r * math.sin(theta)) + cy # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 ����������������������������������������������������������������������������������������������geometry/inst/io/@svg/plot.m������������������������������������������������������������������������0000644�0001750�0001750�00000002505�12035504503�015665� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } plot () ## Plots and SVG object. ## ## @end deftypefn function h = plot(obj, varargin) # Get path ids ids = fieldnames(obj.Path); npath = numel(ids); t = linspace (0, 1, 64); args={}; if !isempty (varargin) args = varargin; end for i = 1:npath x = []; y = []; data = obj.Path.(ids(i)).data; for j = 1:numel(data) x = cat (2, x, polyval (data{j}(1,:),t)); y = cat (2, y, polyval (data{j}(2,:),t)); end h = plot(x,y,args{:}); if i == 1 hold on end end hold off axis tight axis equal endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/loadpaths.m�������������������������������������������������������������������0000644�0001750�0001750�00000005327�12035676207�016706� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . function Paths = loadpaths (obj, svg, varargin) here = which ("@svg/loadpaths"); here = fileparts (here); script = fullfile (here, 'parsePath.py'); ## Call python script if exist (svg,'file') # read from file [st str]=system (sprintf ('python %s %s', script, svg)); else # inline SVG [st str]=system (sprintf ('python %s < %s', script, svg)); end ## Parse ouput strpath = strsplit (str(1:end-1), '$', true); npaths = numel (strpath); ## Convert path data to polynoms for ip = 1:npaths eval (strpath{ip}); ## FIXME: intialize struct with cell field svgpath2.cmd = svgpath(1).cmd; svgpath2.data = {svgpath.data}; nD = length(svgpath2.cmd); pathdata = cell (nD-1,1); point_end=[]; ## If the path is closed, last command is Z and we set initial point == final if svgpath2.cmd(end) == 'Z' nD -= 1; point_end = svgpath2.data{1}; svgpath2.data(end) = []; end ## Initial point points(1,:) = svgpath2.data{1}; for jp = 2:nD switch svgpath2.cmd(jp) case 'L' ## Straigth segment to polygon points(2,:) = svgpath2.data{jp}; pp = [(points(2,:)-points(1,:))' points(1,:)']; clear points points(1,:) = [polyval(pp(1,:),1) polyval(pp(2,:),1)]; case 'C' ## Cubic bezier to polygon points(2:4,:) = reshape (svgpath2.data{jp}, 2, 3).'; pp = cbezier2poly (points); clear points points(1,:) = [polyval(pp(1,:),1) polyval(pp(2,:),1)]; end pathdata{jp-1} = pp; end if ~isempty(point_end) ## Straight segment to close the path points(2,:) = point_end; pp = [(points(2,:)-points(1,:))' points(1,:)']; if all ( abs(pp(:,1)) < sqrt(eps) ) # Final point of last segment is already initial point pathdata(end) = []; else pathdata{end} = pp; end end ## TODO # pathdata = shapetransform(pathdata); Paths.(svgpathid).data = pathdata; end endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/parsePath.py������������������������������������������������������������������0000644�0001750�0001750�00000004212�11732661142�017035� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python ## Copyright (c) 2012 Juan Pablo Carbajal ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . import inkex, simplepath import sys #import getopt def parsePaths (filen=None): svg = inkex.Effect () svg.parse (filen) paths = svg.document.xpath ('//svg:path', namespaces=inkex.NSS) for path in paths: D = simplepath.parsePath (path.attrib['d']) cmdlst = []; parlst = []; for cmd,params in D: cmdlst.append(cmd) parlst.append(params) print 'svgpath = struct("cmd","{0}","data",{{{1}}});' \ .format(''.join(cmdlst),str(parlst).replace('[[','[').replace(']]',']')) print 'svgpathid = "{0}"; $'.format(path.attrib['id']) # ---------------------------- if __name__=="__main__": ''' try: optlist,args = getopt.getopt(sys.argv[1:],"thdp") except getopt.GetoptError: usage() sys.exit(2) doHelp = 0 c = Context() c.doPrint = 1 for opt in optlist: if opt[0] == "-d": c.debug = 1 if opt[0] == "-p": c.plot = 1 if opt[0] == "-t": c.triangulate = 1 if opt[0] == "-h": doHelp = 1 if not doHelp: pts = [] fp = sys.stdin if len(args) > 0: fp = open(args[0],'r') for line in fp: fld = line.split() x = float(fld[0]) y = float(fld[1]) pts.append(Site(x,y)) if len(args) > 0: fp.close() if doHelp or len(pts) == 0: usage() sys.exit(2) ''' svg = sys.argv[1] parsePaths(svg) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/parseSVGData.py���������������������������������������������������������������0000644�0001750�0001750�00000002324�11732661142�017374� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env python ## Copyright (c) 2012 Juan Pablo Carbajal ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . import inkex import sys #import getopt def parseSVGData (filen=None): svg = inkex.Effect () svg.parse (filen) root = svg.document.xpath ('//svg:svg', namespaces=inkex.NSS) print 'data = struct("height",{0},"width",{1},"id","{2}");' \ .format(root[0].attrib['height'],root[0].attrib['width'], root[0].attrib['id']) # ---------------------------- if __name__=="__main__": svg = sys.argv[1] parseSVGData(svg) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/display.m���������������������������������������������������������������������0000644�0001750�0001750�00000001543�12035504503�016355� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . function display (obj) fields = fieldnames (obj); for i = 1 : numel(fields) printf ("#s\n", fields{i}); obj.(fields{i}) end endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/subsref.m���������������������������������������������������������������������0000644�0001750�0001750�00000004717�12035504503�016367� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} function_name () ## @end deftypefn function varargout = subsref (obj, idx) persistent __method__ method4field typeNotImplemented if isempty(__method__) __method__ = struct(); __method__.plot = @(o,varargin) plot (o, varargin{:}); __method__.getpath = @(o,varargin) getpath (o, varargin{:}); __method__.pathid = @(o,varargin) pathid(o,varargin{:}); __method__.path2polygon = @(o,varargin) path2polygon (o, varargin{:}); __method__.normalize = @(o,varargin) normalize (o, varargin{:}); __method__.height = @(o,varargin) height(o, varargin{:}); __method__.width = @(o,varargin) width(o,varargin{:}); # Error strings method4field = "Class #s has no field #s. Use #s() for the method."; typeNotImplemented = "#s no implemented for class #s."; end if ( !strcmp (class (obj), 'svg') ) error ("Object must be of the svg class but '#s' was used", class (obj) ); elseif ( idx(1).type != '.' ) error ("Invalid index for class #s", class (obj) ); endif method = idx(1).subs; if ~isfield(__method__, method) error('Unknown method #s.',method); else fhandle = __method__.(method); end if strcmp(method,'normalize') warning("svg:Devel",["Not returning second output argument of #s" ... " use method(obj) API to get it"],method); end if numel (idx) == 1 # can't access properties, only methods error (method4field, class (obj), method, method); end if strcmp (idx(2).type, '()') args = idx(2).subs; if isempty(args) out = fhandle (obj); else out = fhandle (obj, args{:}); end varargout{1} = out; else error (typeNotImplemented,[method idx(2).type], class (obj)); end endfunction �������������������������������������������������geometry/inst/io/@svg/loadsvgdata.m�����������������������������������������������������������������0000644�0001750�0001750�00000002253�12035676207�017213� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . function data = loadsvgdata (obj, svg, varargin) here = which ("@svg/loadsvgdata"); here = fileparts (here); script = fullfile (here, 'parseSVGData.py'); ## Call python script if exist (svg,'file') # read from file [st str]=system (sprintf ('python %s %s', script, svg)); else # inline SVG [st str]=system (sprintf ('python %s < %s', script, svg)); end ## Parse ouput strdata = strsplit (str(1:end-1), '$', true); eval (strdata); endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/getpath.m���������������������������������������������������������������������0000644�0001750�0001750�00000003762�12035504503�016351� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{paths} = } getpath (@var{ids}) ## Returns paths in @var{ids}. ## ## @end deftypefn function paths = getpath(obj, varargin) if !isempty(varargin) ids = varargin; if iscell (ids) && numel(ids) == 1 && iscell(ids{1}) # dealing with ids given as cell ids = ids{1}; if !all ( cellfun (@ischar, ids) ) print_usage end elseif !all ( cellfun (@ischar, ids) ) print_usage end else paths = obj.Path; return end tf = ismember (ids, fieldnames (obj.Path)); cellfun (@(s) printf("'#s' is not a valid path id.\n", s) , {ids{!tf}}); paths = []; if any (tf) stuff = {ids{tf}}; for i = 1: numel(stuff) paths{i} = obj.Path.(ids{i}).data; endfor # Variation # paths = cellfun(@(s) obj.Path.(s).data, stuff,'UniformOutput',false); # Another variation # paths = cellfun(@(s) getfield(obj,'Path').(s).data, stuff,'UniformOutput',false); # Yet another # paths = cellfun(@(s) getfield(obj.Path,s).data, stuff,'UniformOutput',false); # Yet yet another # dummy = @(s) obj.Path.(s).data; # paths = cellfun(dummy, stuff,'UniformOutput',false); if numel(paths) == 1 paths = paths{1}; end end endfunction ��������������geometry/inst/io/@svg/path2polygon.m����������������������������������������������������������������0000644�0001750�0001750�00000003255�12035504503�017340� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} @var{P} = path2polygon (@var{id}) ## Converts the SVG path to an array of polygons. ## ## @end deftypefn function P = path2polygon (obj,varargin) narg = numel(varargin); if narg == 1 id = varargin{1}; n = 32; elseif narg == 2 id = varargin{1}; n = varargin{2}; else error("svg:path2polygon:InvalidArgument", "Wrong number of arguments."); end P = shape2polygon(getpath(obj, id)); endfunction #{ pd = obj.Path.(id).data; P = cellfun(@(x)convertpath(x,n),pd,'UniformOutput',false); P = cell2mat(P); end function p = convertpath(x,np) n = size(x,2); switch n case 2 p = zeros(2,2); # Straight segment p(:,1) = polyval (x(1,:), [0; 1]); p(:,2) = polyval (x(2,:), [0; 1]); case 4 p = zeros(np,2); # Cubic bezier t = linspace (0, 1, np).'; p(:,1) = polyval (x(1,:),t); p(:,2) = polyval (x(2,:),t); end end #} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/io/@svg/height.m����������������������������������������������������������������������0000644�0001750�0001750�00000001550�12035504503�016156� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2012 Juan Pablo Carbajal ## ## This program is free software; you can redistribute it and/or modify it under ## the terms of the GNU General Public License as published by the Free Software ## Foundation; either version 3 of the License, or (at your option) any later ## version. ## ## This program is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ## details. ## ## You should have received a copy of the GNU General Public License along with ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} function_name () ## @end deftypefn function o = height(obj,varargin) o = obj.Data.height; endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/���������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12130276034�015322� 5����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygonCentroid.m����������������������������������������������������������0000644�0001750�0001750�00000006010�12035504503�020653� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[ @var{pt}, @var{area} ] = } polygonCentroid (@var{points}) ## @deftypefnx {Function File} {[ @dots{} ]= } polygonCentroid (@var{ptx},@var{pty}) ## Compute the centroid (center of mass) of a polygon. ## ## Computes the center of mass of a polygon defined by @var{points}. @var{points} is a ## N-by-2 matrix. The two columns can be given separately using @var{ptx} and @var{pty} ## for the x and y component respectively. ## ## The area of the polygon is returned in the second output argument. ## ## Adapted from @url{http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/} ## ## @seealso{polygons2d, polygonArea, drawPolygon} ## @end deftypefn function [pt A] = polygonCentroid(varargin) if nargin==1 var = varargin{1}; px = var(:,1); py = var(:,2); elseif nargin==2 px = varargin{1}; py = varargin{2}; end # Algorithme P. Bourke (vectorized) inext = [2:N 1]; cros = (px.*py(inext) - px(inext).*py); sx_ = sum ( (px + px(inext)) .* cros); sy_ = sum ( (py + py(inext)) .* cros); A = sum(cros) / 2; pt_ = [sx_ sy_]/A/6; # sx = 0; # sy = 0; # N = length(px); # for i=1:N-1 # sx = sx + (px(i)+px(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); # sy = sy + (py(i)+py(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); # end # sx = sx + (px(N)+px(1))*(px(N)*py(1) - px(1)*py(N)); # sy = sy + (py(N)+py(1))*(px(N)*py(1) - px(1)*py(N)); # pt = [sx sy]/6/polygonArea(px, py) endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygon2shape.m������������������������������������������������������������0000644�0001750�0001750�00000005256�12035504503�020301� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{shape} = } polygon2shape (@var{polygon}) ## Converts a polygon to a shape with edges defined by smooth polynomials. ## ## @var{polygon} is a N-by-2 matrix, each row representing a vertex. ## @var{shape} is a N-by-1 cell, where each element is a pair of polynomials ## compatible with polyval. ## ## In its current state, the shape is formed by polynomials of degree 1. Therefore ## the shape representation costs more memory except for colinear points in the ## polygon. ## ## @seealso{shape2polygon, simplifypolygon, polyval} ## @end deftypefn function shape = polygon2shape (polygon) # Filter colinear points polygon = simplifypolygon (polygon); np = size(polygon,1); # polygonal shapes are memory inefficient!! # TODO filter the regions where edge angles are canging slowly and fit # polynomial of degree 3; pp = nan (2*np,2); # Transform edges into polynomials of degree 1; # pp = [(p1-p0) p0]; pp(:,1) = diff(polygon([1:end 1],:)).'(:); pp(:,2) = polygon.'(:); shape = mat2cell(pp, 2*ones (1,np), 2); endfunction %!test %! pp = [0 0; 1 0; 1 1; 0 1]; %! s = polygon2shape (pp); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/reversePolygon.m�����������������������������������������������������������0000644�0001750�0001750�00000003723�12035504503�020527� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{poly2} = } reversePolygon (@var{poly}) ## Reverse a polygon, by iterating vertices from the end ## ## POLY2 = reversePolygon(POLY) ## POLY2 has same vertices as POLY, but in different order. The first ## vertex of the polygon is still the same. ## ## @seealso{reversePolyline} ## @end deftypefn function rev = reversePolygon(poly) rev = poly([1 end:-1:2], :); endfunction ���������������������������������������������geometry/inst/polygons2d/curvature.m����������������������������������������������������������������0000644�0001750�0001750�00000014215�12035504503�017522� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{kappa} = } curvature (@var{t}, @var{px}, @var{py},@var{method},@var{degree}) ## @deftypefnx {Function File} {@var{kappa} = } curvature (@var{t}, @var{poly},@var{method},@var{degree}) ## @deftypefnx {Function File} {@var{kappa} = } curvature (@var{px}, @var{py},@var{method},@var{degree}) ## @deftypefnx {Function File} {@var{kappa} = } curvature (@var{points},@var{method},@var{degree}) ## @deftypefnx {Function File} {[@var{kappa} @var{poly} @var{t}] = } curvature (@dots{}) ## Estimate curvature of a polyline defined by points. ## ## First compute an approximation of the curve given by PX and PY, with ## the parametrization @var{t}. Then compute the curvature of approximated curve ## for each point. ## @var{method} used for approximation can be only: 'polynom', with specified degree. ## Further methods will be provided in a future version. ## @var{t}, @var{px}, and @var{py} are N-by-1 array of the same length. The points ## can be specified as a single N-by-2 array. ## ## If the argument @var{t} is not given, the parametrization is estimated using ## function @code{parametrize}. ## ## If requested, @var{poly} contains the approximating polygon evlauted at the ## parametrization @var{t}. ## ## @seealso{parametrize, polygons2d} ## @end deftypefn function [kappa, varargout] = curvature(varargin) # default values degree = 5; t=0; # parametrization of curve tc=0; # indices of points wished for curvature # ================================================================= # Extract method and degree ------------------------------ nargin = length(varargin); varN = varargin{nargin}; varN2 = varargin{nargin-1}; if ischar(varN2) # method and degree are specified method = varN2; degree = varN; varargin = varargin(1:nargin-2); elseif ischar(varN) # only method is specified, use degree 6 as default method = varN; varargin = varargin{1:nargin-1}; else # method and degree are implicit : use 'polynom' and 6 method = 'polynom'; end # extract input parametrization and curve. ----------------------- nargin = length(varargin); if nargin==1 # parameters are just the points -> compute caracterization. var = varargin{1}; px = var(:,1); py = var(:,2); elseif nargin==2 var = varargin{2}; if size(var, 2)==2 # parameters are t and POINTS px = var(:,1); py = var(:,2); t = varargin{1}; else # parameters are px and py px = varargin{1}; py = var; end elseif nargin==3 var = varargin{2}; if size(var, 2)==2 # parameters are t, POINTS, and tc px = var(:,1); py = var(:,2); t = varargin{1}; else # parameters are t, px and py t = varargin{1}; px = var; py = varargin{3}; end elseif nargin==4 # parameters are t, px, py and tc t = varargin{1}; px = varargin{2}; py = varargin{3}; tc = varargin{4}; end # compute implicit parameters -------------------------- # if t and/or tc are not computed, use implicit definition if t==0 t = parametrize(px, py, 'norm'); end # if tc not defined, compute curvature for all points if tc==0 tc = t; else # else convert from indices to parametrization values tc = t(tc); end # ================================================================= # compute curvature for each point of the curve if strcmp(method, 'polynom') # compute coefficients of interpolation functions x0 = polyfit(t, px, degree); y0 = polyfit(t, py, degree); # compute coefficients of first and second derivatives. In the case of a # polynom, it is possible to compute coefficient of derivative by # multiplying with a matrix. derive = diag(degree:-1:0); xp = circshift(x0*derive, [0 1]); yp = circshift(y0*derive, [0 1]); xs = circshift(xp*derive, [0 1]); ys = circshift(yp*derive, [0 1]); # compute values of first and second derivatives for needed points xprime = polyval(xp, tc); yprime = polyval(yp, tc); xsec = polyval(xs, tc); ysec = polyval(ys, tc); # compute value of curvature kappa = (xprime.*ysec - xsec.*yprime)./ ... power(xprime.*xprime + yprime.*yprime, 3/2); if nargout > 1 varargout{1} = [polyval(x0,tc(:)) polyval(y0,tc(:))]; if nargout > 2 varargout{2} = tc; end end else error('unknown method'); end endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygonSubcurve.m����������������������������������������������������������0000644�0001750�0001750�00000006354�12130272503�020713� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2003-2011 David Legland ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{poly2} =} polygonSubcurve (@var{polygon}, @var{pos0},@var{pos1}) ## Extract a portion of a polygon ## ## Create a new polyline, by keeping vertices located between positions ## @var{pos0} and @var{pos1}, and adding points corresponding to positions @var{pos0} and ## @var{pos1} if they are not already vertices. ## ## Example: ## @example ## Nv = 100; ## poly = circleAsPolygon ([10 20 30], Nv); ## poly2 = polygonSubcurve (poly, 15, 65); ## drawPolyline (poly2); ## @end example ## ## @seealso{polygons2d, polylineSubcurve} ## @end deftypefn function res = polygonSubcurve(poly, t0, t1) # number of vertices Nv = size(poly, 1); if t0 ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } suppportFunction (@var{polygon}) ## @deftypefnx {Function File} {@var{h} = } suppportFunction (@var{polygon}, @var{n}) ## @deftypefnx {Function File} {@var{h} = } suppportFunction (@var{polygon}, @var{v}) ## Compute support function of a polygon ## ## H = supportFunction(POLYGON, N) ## uses N points for suport function approximation ## ## H = supportFunction(POLYGON) ## assume 24 points for approximation ## ## H = supportFunction(POLYGON, V) ## where V is a vector, uses vector V of angles to compute support ## function. ## ## @seealso{convexification} ## @end deftypefn function h = supportFunction(polygon, varargin) N = 24; u = (0:2*pi/N:2*pi*(1-1/N)).'; if length(varargin)==1 var = varargin{1}; if length(var)==1 N = var; u = (0:2*pi/N:2*pi*(1-1/N)).'; else u = var(:); end end h = zeros(size(u)); for i=1:length(u) v = repmat([cos(u(i)) sin(u(i))], [size(polygon, 1), 1]); h(i) = max(dot(polygon, v, 2)); end endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygonSelfIntersections.m�������������������������������������������������0000644�0001750�0001750�00000006251�12035504503�022556� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pts} = } polygonSelfIntersections (@var{poly}) ## @deftypefnx {Function File} {[@var{pts} @var{pos1} @var{pos2}] = } polygonSelfIntersections (@var{poly}) ## Find-self intersection points of a polygon ## ## Return the position of self intersection points ## ## Also return the 2 positions of each intersection point (the position ## when meeting point for first time, then position when meeting point ## for the second time). ## ## Example ## @example ## # use a '8'-shaped polygon ## poly = [10 0;0 0;0 10;20 10;20 20;10 20]; ## polygonSelfIntersections(poly) ## ans = ## 10 10 ## @end example ## ## @seealso{polygons2d, polylineSelfIntersections} ## @end deftypefn function varargout = polygonSelfIntersections(poly, varargin) tol = 1e-14; # ensure the last point equals the first one if sum(abs(poly(end, :)-poly(1,:)) < tol) ~= 2 poly = [poly; poly(1,:)]; end # compute intersections by calling algo for polylines [points pos1 pos2] = polylineSelfIntersections(poly); # It may append that first vertex of polygon is detected as intersection, # the following tries to detect this n = size(poly, 1) - 1; inds = (pos1 == 0 & pos2 == n) | (pos1 == n & pos2 == 0); points(inds, :) = []; pos1(inds) = []; pos2(inds) = []; # remove multiple intersections [points I J] = unique(points, 'rows', 'first'); ##ok pos1 = pos1(I); pos2 = pos2(I); ## Post-processing # process output arguments if nargout <= 1 varargout = {points}; elseif nargout == 3 varargout = {points, pos1, pos2}; end endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygonArea.m��������������������������������������������������������������0000644�0001750�0001750�00000006467�12035504503�017774� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{area} = } polygonArea (@var{points}) ## @deftypefnx {Function File} {@var{area} = } polygonArea (@var{px},@var{py}) ## Compute the signed area of a polygon. ## ## Compute area of a polygon defined by @var{points}. @var{points} is a N-by-2 ## matrix containing coordinates of vertices. ## ## Vertices of the polygon are supposed to be oriented Counter-Clockwise ## (CCW). In this case, the signed area is positive. ## If vertices are oriented Clockwise (CW), the signed area is negative. ## ## If polygon is self-crossing, the result is undefined. ## ## If @var{points} is a cell, each element is considered a polygon and the area ## of each one is returned in the matrix @var{area}. The matrix has the same shape ## as the cell. ## ## References: ## Algorithm adapted from P. Bourke web page ## http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/ ## ## @seealso{polygons2d, polygonCentroid, drawPolygon} ## @end deftypefn function area = polygonArea(varargin) var = varargin{1}; # in case of polygon sets, computes several areas if iscell (var) area = cellfun (@func, var); # area = zeros(length(var), 1); # for i = 1:length(var) # area(i) = polygonArea(var{i}, varargin{2:end}); # end # return; # end else # extract coordinates if nargin == 1 area = func(var) elseif nargin == 2 px = varargin{1}; py = varargin{2}; # indices of next vertices N = length(px); iNext = [2:N 1]; # compute area (vectorized version) area = sum(px .* py(iNext) - px(iNext) .* py) / 2; end end endfunction function a = func (c) N = length (c); iNext = [2:N 1]; a = sum (c(:,1) .* c(iNext,2) - c(iNext,1) .* c(:,2)) / 2; endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/simplifypolygon.m����������������������������������������������������������0000644�0001750�0001750�00000005455�12106721347�020762� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{spoly} = } simplifypolygon (@var{poly}) ## Simplify a polygon using the Ramer-Douglas-Peucker algorithm. ## ## @var{poly} is a N-by-2 matrix, each row representing a vertex. ## ## @seealso{simplifypolyline, shape2polygon} ## @end deftypefn function polygonsimp = simplifypolygon (polygon, varargin) polygonsimp = simplifypolyline (polygon,varargin{:}); # Remove parrallel consecutive edges PL = polygonsimp(1:end-1,:); PC = polygonsimp(2:end,:); PR = polygonsimp([3:end 1],:); a = PL - PC; b = PR - PC; tf = find (isParallel(a,b))+1; polygonsimp (tf,:) = []; endfunction %!test %! P = [0 0; 1 0; 0 1]; %! P2 = [0 0; 0.1 0; 0.2 0; 0.25 0; 1 0; 0 1; 0 0.7; 0 0.6; 0 0.3; 0 0.1]; %! assert(simplifypolygon (P2),P,min(P2(:))*eps) %!demo %! %! P = [0 0; 1 0; 0 1]; %! P2 = [0 0; 0.1 0; 0.2 0; 0.25 0; 1 0; 0 1; 0 0.7; 0 0.6; 0 0.3; 0 0.1]; %! Pr = simplifypolygon (P2); %! %! cla %! drawPolygon(P,'or;Reference;'); %! hold on %! drawPolygon(P2,'x-b;Redundant;'); %! drawPolygon(Pr,'*g;Simplified;'); %! hold off %! %! # -------------------------------------------------------------------------- %! # The two polygons describe the same figure, a triangle. Extra points are %! # removed form the redundant one. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/drawPolyline.m�������������������������������������������������������������0000644�0001750�0001750�00000011154�12114701140�020144� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2003-2011 David Legland ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{} =} drawPolyline (@var{}, @var{}) ##DRAWPOLYLINE Draw a polyline specified by a list of points ## ## drawPolyline(COORD); ## packs coordinates in a single [N*2] array. ## ## drawPolyline(PX, PY); ## specifies coordinates in separate arrays. PX and PY must be column ## vectors with the same length. ## ## drawPolyline(..., TYPE); ## where TYPE is either 'closed' or 'open', specifies if last point must ## be connected to the first one ('closed') or not ('open'). ## Default is 'open'. ## ## drawPolyline(..., PARAM, VALUE); ## specify plot options as described for plot command. ## ## H = drawPolyline(...) also return a handle to the list of line objects. ## ## Example: ## @example ## # Draw a curve representing an ellipse ## t = linspace(0, 2*pi, 100)'; ## px = 10*cos(t); py = 5*sin(t); ## drawPolyline([px py], 'closed'); ## axis equal; ## ## # The same, with different drawing options ## drawPolyline([px py], 'closed', 'lineWidth', 2, 'lineStyle', '--'); ## @end example ## ## @seealso{polygons2d, drawPolygon} ## @end deftypefn function varargout = drawPolyline(varargin) # default values closed = false; # If first argument is a cell array, draw each curve individually, # and eventually returns handle of each plot. var = varargin{1}; if iscell(var) h = []; for i=1:length(var(:)) h = [h ; drawPolyline(var{i}, varargin{2:end})]; end if nargout>0 varargout{1}=h; end return; end # extract curve coordinate if size(var, 2)==1 # first argument contains x coord, second argument contains y coord px = var; if length(varargin)==1 error('Wrong number of arguments in drawPolyline'); end py = varargin{2}; varargin = varargin(3:end); else # first argument contains both coordinate px = var(:, 1); py = var(:, 2); varargin = varargin(2:end); end # check if curve is closed or open if ~isempty(varargin) var = varargin{1}; if strncmpi(var, 'close', 5) closed = true; varargin = varargin(2:end); elseif strncmpi(var, 'open', 4) closed = false; varargin = varargin(2:end); end end # if curve is closed, add first point at the end of the list if closed px = [px; px(1)]; py = [py; py(1)]; end # plot the curve, with eventually optional parameters h = plot(px, py, varargin{:}); # format output arguments if nargout>0 varargout{1}=h; end endfunction %!demo %! t = linspace (0, 2*pi, 100)'; %! px = 10*cos (t); py = 5*sin (t); %! %! subplot (1,2,1) %! drawPolyline ([px py], 'closed'); %! axis equal; %! %! subplot (1,2,2) %! drawPolyline([px py], 'closed', 'lineWidth', 2, 'lineStyle', '--'); %! axis equal; %! # ------------------------------------------------- %! # Draw a curve representing an ellipse with two drawing options ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygonLoops.m�������������������������������������������������������������0000644�0001750�0001750�00000010427�12130272503�020205� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{loops} = } polygonLoops (@var{poly}) ## Divide a possibly self-intersecting polygon into a set of simple loops ## ## @var{poly} is a polygone defined by a series of vertices, ## @var{loops} is a cell array of polygons, containing the same vertices of the ## original polygon, but no loop self-intersect, and no couple of loops ## intersect each other. ## ## Example: ## @example ## poly = [0 0;0 10;20 10;20 20;10 20;10 0]; ## loops = polygonLoops(poly); ## figure(1); hold on; ## drawPolygon(loops); ## polygonArea(loops) ## @end example ## ## @seealso{polygons2d, polygonSelfIntersections} ## @end deftypefn function loops = polygonLoops(poly) ## Initialisations # compute intersections [inters pos1 pos2] = polygonSelfIntersections(poly); # case of a polygon without self-intersection if isempty(inters) loops = {poly}; return; end # array for storing loops loops = cell(0, 1); positions = sortrows([pos1 pos2;pos2 pos1]); ## First loop pos0 = 0; loop = polygonSubcurve(poly, pos0, positions(1, 1)); pos = positions(1, 2); positions(1, :) = []; while true # index of next intersection point ind = find(positions(:,1)>pos, 1, 'first'); # if not found, break if isempty(ind) break; end # add portion of curve loop = [loop; polygonSubcurve(poly, pos, positions(ind, 1))]; ##ok # look for next intersection point pos = positions(ind, 2); positions(ind, :) = []; end # add the last portion of curve loop = [loop;polygonSubcurve(poly, pos, pos0)]; # remove redundant vertices loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = []; if sum(diff(loop([1 end], :))==0)==2 loop(end, :) = []; end # add current loop to the list of loops loops{1} = loop; ## Other loops Nl = 1; while ~isempty(positions) loop = []; pos0 = positions(1, 2); pos = positions(1, 2); while true # index of next intersection point ind = find(positions(:,1)>pos, 1, 'first'); # add portion of curve loop = [loop;polygonSubcurve(poly, pos, positions(ind, 1))]; ##ok # look for next intersection point pos = positions(ind, 2); positions(ind, :) = []; # if not found, break if pos==pos0 break; end end # remove redundant vertices loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = []; ##ok if sum(diff(loop([1 end], :))==0)==2 loop(end, :) = []; ##ok end # add current loop to the list of loops Nl = Nl + 1; loops{Nl} = loop; end endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/parametrize.m��������������������������������������������������������������0000644�0001750�0001750�00000007253�12035504503�020031� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{par} = } parametrize (@var{poly}) ## @deftypefnx {Function File} {@var{par} = } parametrize (@var{px},@var{py}) ## @deftypefnx {Function File} {@var{par} = } parametrize (@dots{},@var{normalize}) ## ## Parametrization of a curve, based on edges length ## ## Returns a parametrization of the curve defined by the serie of points, ## based on euclidean distance between two consecutive points. ## POLY is a N-by-2 array, representing coordinates of vertices. The ## result PAR is N-by-1, and contains the cumulative length of edges until ## corresponding vertex. The function also accepts the polygon as two inputs ## @var{px} and @var{py} representinx coordinates x and y respectively. ## When optional argument @var{normalize} is non-empty @var{par} is rescaled ## such that the last element equals 1, i.e. @code{@var{par}(end)==1}. ## ## Example ## @example ## # Parametrize a circle approximation ## poly = circleToPolygon([0 0 1], 200); ## p = parametrize(poly); ## p(end) ## ans = ## 6.2829 ## p = parametrize(poly,'norm'); ## p(end) ## ans = ## 1 ## p = parametrize(poly,true); ## p(end) ## ans = ## 1 ## @end example ## ## @seealso{polygons2d, polylineLength} ## @end deftypefn function par = parametrize(varargin) ## Process inputs # extract vertex coordinates if size(varargin{1}, 2) > 1 # vertices in a single array pts = varargin{1}; normalize = numel(varargin) > 1; elseif size(varargin{1}, 2) == 1 && numel(varargin) >= 2 # points as separate arrays pts = [varargin{1} varargin{2}]; normalize = numel(varargin) > 2; end ## Parametrize polyline # compute cumulative sum of euclidean distances between consecutive # vertices, setting distance of first vertex to 0. if size(pts, 2) == 2 # process points in 2D par = [0 ; cumsum(hypot(diff(pts(:,1)), diff(pts(:,2))))]; else # process points in arbitrary dimension par = [0 ; cumsum(sqrt(sum(diff(pts).^2, 2)))]; end # eventually rescale between 0 and 1 if normalize par = par / par(end); end endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/drawPolygon.m��������������������������������������������������������������0000644�0001750�0001750�00000010076�12035504503�020010� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} = } drawPolygon (@var{coord}) ## @deftypefnx {Function File} {@var{h} = } drawPolygon (@var{px}, @var{py}) ## @deftypefnx {Function File} {@var{h} = } drawPolygon (@var{polys}) ## Draw a polygon specified by a list of points. ## ## drawPolygon(COORD); ## Packs coordinates in a single [N*2] array. ## ## drawPolygon(PX, PY); ## Specifies coordinates in separate arrays. ## ## drawPolygon(POLYS) ## Packs coordinate of several polygons in a cell array. Each element of ## the array is a Ni*2 double array. ## ## H = drawPolygon(...); ## Also return a handle to the list of line objects. ## ## ## @seealso{polygons2d, drawCurve} ## @end deftypefn function varargout = drawPolygon(varargin) # check input if isempty(varargin) error('need to specify a polygon'); end var = varargin{1}; ## Manage cell arrays of polygons # case of a set of polygons stored in a cell array if iscell(var) N = length(var); h = zeros(N, 1); for i = 1:N state = ishold(gca); hold on; # check for empty polygons if ~isempty(var{i}) h(i) = drawPolygon(var{i}, varargin{2:end}); end if ~state hold off end end if nargout > 0 varargout = {h}; end return; end ## Parse coordinates and options # Extract coordinates of polygon vertices if size(var, 2) > 1 # first argument is a polygon array px = var(:, 1); py = var(:, 2); varargin(1) = []; else # arguments 1 and 2 correspond to x and y coordinate respectively if length(varargin) < 2 error('Should specify either a N-by-2 array, or 2 N-by-1 vectors'); end px = varargin{1}; py = varargin{2}; varargin(1:2) = []; end # set default line format if isempty(varargin) varargin = {'b-'}; end # check case of polygons with holes if sum(isnan(px(:))) > 0 polygons = splitPolygons([px py]); h = drawPolygon(polygons); if nargout > 0 varargout = {h}; end return; end ## Draw the polygon # ensure last point is the same as the first one px(size(px, 1)+1, :) = px(1,:); py(size(py, 1)+1, :) = py(1,:); # draw the polygon outline h = plot(px, py, varargin{:}); # format output arg if nargout > 0 varargout = {h}; end endfunction ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/splitPolygons.m������������������������������������������������������������0000644�0001750�0001750�00000005051�12035504503�020366� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{polygons} = } splitPolygons (@var{polygon}) ## Convert a NaN separated polygon list to a cell array of polygons. ## ## @var{polygon} is a N-by-2 array of points, with possibly couples of NaN values. ## The functions separates each component separated by NaN values, and ## returns a cell array of polygons. ## ## @seealso{polygons2d} ## @end deftypefn function polygons = splitPolygons(polygon) if iscell(polygon) # case of a cell array polygons = polygon; elseif sum(isnan(polygon(:)))==0 # single polygon -> no break polygons = {polygon}; else # find indices of NaN couples inds = find(sum(isnan(polygon), 2)>0); # number of polygons N = length(inds)+1; polygons = cell(N, 1); # iterate over NaN-separated regions to create new polygon inds = [0;inds;size(polygon, 1)+1]; for i=1:N polygons{i} = polygon((inds(i)+1):(inds(i+1)-1), :); end end endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygonPoint.m�������������������������������������������������������������0000644�0001750�0001750�00000005601�12130272503�020200� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2003-2011 David Legland ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## ## The views and conclusions contained in the software and documentation are ## those of the authors and should not be interpreted as representing official ## policies, either expressed or implied, of the copyright holders. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{point} =} polygonPoint (@var{poly}, @var{pos}) ## Extract a point from a polygon ## @seealso{polygons2d, polylinePoint} ## @end deftypefn function point = polygonPoint(poly, pos) # eventually copy first point at the end to ensure closed polygon if sum(poly(end, :)==poly(1,:))~=2 poly = [poly; poly(1,:)]; end # number of points to compute Np = length(pos(:)); # number of vertices in polygon Nv = size(poly, 1)-1; # allocate memory results point = zeros(Np, 2); # iterate on points for i=1:Np # compute index of edge (between 0 and Nv) ind = floor(pos(i)); # special case of last point of polyline if ind==Nv point(i,:) = poly(end,:); continue; end # format index to ensure being on polygon ind = min(max(ind, 0), Nv-1); # position on current edge t = min(max(pos(i)-ind, 0), 1); # parameters of current edge x0 = poly(ind+1, 1); y0 = poly(ind+1, 2); dx = poly(ind+2,1)-x0; dy = poly(ind+2,2)-y0; # compute position of current point point(i, :) = [x0+t*dx, y0+t*dy]; end endfunction �������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/medialAxisConvex.m���������������������������������������������������������0000644�0001750�0001750�00000013235�12035504503�020746� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{n} @var{e}] = } medialAxisConvex (@var{polygon}) ## Compute medial axis of a convex polygon ## ## @var{polygon} is given as a set of points [x1 y1;x2 y2 ...], returns ## the medial axis of the polygon as a graph. ## @var{n} is a set of nodes. The first elements of @var{n} are the vertices of the ## original polygon. ## @var{e} is a set of edges, containing indices of source and target nodes. ## Edges are sorted according to order of creation. Index of first vertex ## is lower than index of last vertex, i.e. edges always point to newly ## created nodes. ## ## Notes: ## - Is not fully implemented, need more development (usually crashes for ## polygons with more than 6-7 points...) ## - Works only for convex polygons. ## - Complexity is not optimal: this algorithm is O(n*log n), but linear ## algorithms exist. ## ## @seealso{polygons2d, bisector} ## @end deftypefn function [nodes, edges] = medialAxisConvex(points) # eventually remove the last point if it is the same as the first one if points(1,:) == points(end, :) nodes = points(1:end-1, :); else nodes = points; end # special case of triangles: # compute directly the gravity center, and simplify computation. if size(nodes, 1)==3 nodes = [nodes; mean(nodes, 1)]; edges = [1 4;2 4;3 4]; return end # number of nodes, and also of initial rays N = size(nodes, 1); # create ray of each vertex rays = zeros(N, 4); rays(1, 1:4) = bisector(nodes([2 1 N], :)); rays(N, 1:4) = bisector(nodes([1 N N-1], :)); for i=2:N-1 rays(i, 1:4) = bisector(nodes([i+1, i, i-1], :)); end # add indices of edges producing rays (indices of first vertex, second # vertex is obtained by adding one modulo N). rayEdges = [[N (1:N-1)]' (1:N)']; pint = intersectLines(rays, rays([2:N 1], :)); #ti = linePosition(pint, rays); #ti = min(linePosition(pint, rays), linePosition(pint, rays([2:N 1], :))); ti = distancePointLine(pint, ... createLine(points([N (1:N-1)]', :), points((1:N)', :))); # create list of events. # terms are : R1 R2 X Y t0 # R1 and R2 are indices of involved rays # X and Y is coordinate of intersection point # t0 is position of point on rays events = sortrows([ (1:N)' [2:N 1]' pint ti], 5); # initialize edges edges = zeros(0, 2); # ------------------- # process each event until there is no more # start after index of last vertex, and process N-3 intermediate rays for i=N+1:2*N-3 # add new node at the rays intersection nodes(i,:) = events(1, 3:4); # add new couple of edges edges = [edges; events(1,1) i; events(1,2) i]; # find the two edges creating the new emanating ray n1 = rayEdges(events(1, 1), 1); n2 = rayEdges(events(1, 2), 2); # create the new ray line1 = createLine(nodes(n1, :), nodes(mod(n1,N)+1, :)); line2 = createLine(nodes(mod(n2,N)+1, :), nodes(n2, :)); ray0 = bisector(line1, line2); # set its origin to emanating point ray0(1:2) = nodes(i, :); # add the new ray to the list rays = [rays; ray0]; rayEdges(size(rayEdges, 1)+1, 1:2) = [n1 n2]; # find the two neighbour rays ind = sum(ismember(events(:,1:2), events(1, 1:2)), 2)==0; ir = unique(events(ind, 1:2)); ir = ir(~ismember(ir, events(1,1:2))); # create new intersections pint = intersectLines(ray0, rays(ir, :)); #ti = min(linePosition(pint, ray0), linePosition(pint, rays(ir, :))) + events(1,5); ti = distancePointLine(pint, line1); # remove all events involving old intersected rays ind = sum(ismember(events(:,1:2), events(1, 1:2)), 2)==0; events = events(ind, :); # add the newly formed events events = [events; ir(1) i pint(1,:) ti(1); ir(2) i pint(2,:) ti(2)]; # and sort them according to 'position' parameter events = sortrows(events, 5); end # centroid computation for last 3 rays nodes = [nodes; mean(events(:, 3:4))]; edges = [edges; [unique(events(:,1:2)) ones(3, 1)*(2*N-2)]]; endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polylineSelfIntersections.m������������������������������������������������0000644�0001750�0001750�00000011347�12035504503�022724� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{pts} = } polylineSelfIntersections (@var{poly}) ## Find self-intersections points of a polyline ## ## Return the position of self intersection points ## ## Also return the 2 positions of each intersection point (the position ## when meeting point for first time, then position when meeting point ## for the second time). ## ## Example ## @example ## # use a gamma-shaped polyline ## poly = [0 0;0 10;20 10;20 20;10 20;10 0]; ## polylineSelfIntersections(poly) ## ans = ## 10 10 ## ## # use a 'S'-shaped polyline ## poly = [10 0;0 0;0 10;20 10;20 20;10 20]; ## polylineSelfIntersections(poly) ## ans = ## 10 10 ## @end example ## ## @seealso{polygons2d, intersectPolylines, polygonSelfIntersections} ## @end deftypefn function varargout = polylineSelfIntersections(poly, varargin) ## Initialisations # determine whether the polyline is closed closed = false; if ~isempty(varargin) closed = varargin{1}; if ischar(closed) if strcmp(closed, 'closed') closed = true; elseif strcmp(closed, 'open') closed = false; end end end # if polyline is closed, ensure the last point equals the first one if closed if sum(abs(poly(end, :)-poly(1,:))<1e-14)~=2 poly = [poly; poly(1,:)]; end end # arrays for storing results points = zeros(0, 2); pos1 = zeros(0, 1); pos2 = zeros(0, 1); # number of vertices Nv = size(poly, 1); ## Main processing # index of current intersection ip = 0; # iterate over each couple of edge ( (N-1)*(N-2)/2 iterations) for i=1:Nv-2 # create first edge edge1 = [poly(i, :) poly(i+1, :)]; for j=i+2:Nv-1 # create second edge edge2 = [poly(j, :) poly(j+1, :)]; # check conditions on bounding boxes if min(edge1([1 3]))>max(edge2([1 3])) continue; end if max(edge1([1 3]))max(edge2([2 4])) continue; end if max(edge1([2 4])) points(ind,:) = []; pos1(ind) = []; pos2(ind) = []; end ## Post-processing # process output arguments if nargout<=1 varargout{1} = points; elseif nargout==3 varargout{1} = points; varargout{2} = pos1; varargout{3} = pos2; end endfunction �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/simplifypolyline.m���������������������������������������������������������0000644�0001750�0001750�00000013317�12106721347�021122� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{pline2} @var{idx}] = } simplifypolyline (@var{pline}) ## @deftypefnx {Function File} {@dots{} = } simplifypolyline (@dots{},@var{property},@var{value},@dots{}) ## Simplify or subsample a polyline using the Ramer-Douglas-Peucker algorithm, ## a.k.a. the iterative end-point fit algorithm or the split-and-merge algorithm. ## ## The @var{pline} as a N-by-2 matrix. Rows correspond to the ## verices (compatible with @code{polygons2d}). The vector @var{idx} constains ## the indexes on vetices in @var{pline} that generates @var{pline2}, i.e. ## @code{pline2 = pline(idx,:)}. ## ## @strong{Parameters} ## @table @samp ## @item 'Nmax' ## Maximum number of vertices. Default value @code{1e3}. ## @item 'Tol' ## Tolerance for the error criteria. Default value @code{1e-4}. ## @item 'MaxIter' ## Maximum number of iterations. Default value @code{10}. ## @item 'Method' ## Not implemented. ## @end table ## ## Run @code{demo simplifypolyline} to see an example. ## ## @seealso{curve2polyline, curveval} ## @end deftypefn function [pline idx] = simplifypolyline (pline_o, varargin) ## TODO do not print warnings if user provided Nmax or MaxIter. # --- Parse arguments --- # parser = inputParser (); parser.FunctionName = "simplifypolyline"; parser = addParamValue (parser,'Nmax', 1e3, @(x)x>0); toldef = 1e-4;#max(sumsq(diff(pline_o),2))*2; parser = addParamValue (parser,'Tol', toldef, @(x)x>0); parser = addParamValue (parser,'MaxIter', 100, @(x)x>0); parser = parse(parser,varargin{:}); Nmax = parser.Results.Nmax; tol = parser.Results.Tol; MaxIter = parser.Results.MaxIter; clear parser toldef msg = ["simplifypolyline: Maximum number of points reached with maximum error %g." ... " Increase %s if the result is not satisfactory."]; # ------ # [N dim] = size(pline_o); idx = [1 N]; for iter = 1:MaxIter # Find the point with the maximum distance. [dist ii] = maxdistance (pline_o, idx); tf = dist > tol; n = sum(tf); if all(!tf); break; end idx(end+1:end+n) = ii(tf); idx = sort(idx); if length(idx) >= Nmax ## TODO remove extra points warning('geometry:MayBeWrongOutput', sprintf(msg,max(dist),'Nmax')); break; end end if iter == MaxIter warning('geometry:MayBeWrongOutput', sprintf(msg,max(dist),'MaxIter')); end pline = pline_o(idx,:); endfunction function [dist ii] = maxdistance (p, idx) ## Separate the groups of points according to the edge they can divide. func = @(x,y) x:y; idxc = arrayfun (func, idx(1:end-1), idx(2:end), "UniformOutput",false); points = cellfun (@(x)p(x,:), idxc, "UniformOutput",false); ## Build the edges edges = [p(idx(1:end-1),:) p(idx(2:end),:)]; edges = mat2cell (edges, ones(1,size(edges,1)), 4)'; ## Calculate distance between the points and the corresponding edge [dist ii] = cellfun(@dd, points,edges,idxc); endfunction function [dist ii] = dd (p,e,idx) [d pos] = distancePointEdge(p,e); [dist ii] = max(d); ii = idx(ii); endfunction %!demo %! t = linspace(0,1,100).'; %! y = polyval([1 -1.5 0.5 0],t); %! pline = [t y]; %! %! figure(1) %! clf %! plot (t,y,'-r;Original;','linewidth',2); %! hold on %! %! tol = [8 2 1 0.5]*1e-2; %! colors = jet(4); %! %! for i=1:4 %! pline_ = simplifypolyline(pline,'tol',tol(i)); %! msg = sprintf('-;#g;',tol(i)); %! h = plot (pline_(:,1),pline_(:,2),msg); %! set(h,'color',colors(i,:),'linewidth',2,'markersize',4); %! end %! hold off %! %! # --------------------------------------------------------- %! # Four approximations of the initial polyline with decreasing tolerances. %!demo %! P = [0 0; 3 1; 3 4; 1 3; 2 2; 1 1]; %! func = @(x,y) linspace(x,y,5); %! P2(:,1) = cell2mat( ... %! arrayfun (func, P(1:end-1,1),P(2:end,1), ... %! 'uniformoutput',false))'(:); %! P2(:,2) = cell2mat( ... %! arrayfun (func, P(1:end-1,2),P(2:end,2), ... %! 'uniformoutput',false))'(:); %! %! P2s = simplifypolyline (P2); %! %! plot(P(:,1),P(:,2),'s',P2(:,1),P2(:,2),'o',P2s(:,1),P2s(:,2),'-ok'); %! %! # --------------------------------------------------------- %! # Simplification of a polyline in the plane. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/reversePolyline.m����������������������������������������������������������0000644�0001750�0001750�00000003665�12035504503�020700� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{poly2} = } reversePolyline (@var{poly}) ## Reverse a polyline, by iterating vertices from the end ## ## POLY2 = reversePolyline(POLY) ## POLY2 has same vertices as POLY, but POLY2(i,:) is the same as ## POLY(END-i+1,:). ## ## @seealso{reversePolygon} ## @end deftypefn function rev = reversePolyline(poly) rev = poly(end:-1:1, :); endfunction ���������������������������������������������������������������������������geometry/inst/polygons2d/distancePointPolygon.m�����������������������������������������������������0000644�0001750�0001750�00000004271�12035504503�021657� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dist} = } distancePointPolygon (@var{point},@var{poly}) ## Compute shortest distance between a point and a polygon ## ## @seealso{polygons2d, points2d, distancePointPolyline, distancePointEdge, projPointOnPolyline} ## @end deftypefn function varargout = distancePointPolygon(point, poly) # eventually copy first point at the end to ensure closed polygon if sum(poly(end, :)==poly(1,:))~=2 poly = [poly; poly(1,:)]; end # call to distancePointPolyline minDist = distancePointPolyline(point, poly); # process output arguments if nargout<=1 varargout{1} = minDist; end endfunction ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/expandPolygon.m������������������������������������������������������������0000644�0001750�0001750�00000006736�12035504503�020342� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{loops} = } expandPolygon (@var{poly}, @var{dist}) ## Expand a polygon by a given (signed) distance ## ## Associates to each edge of the polygon @var{poly} the parallel line located ## at distance @var{dist} from the current edge, and compute intersections with ## neighbor parallel lines. The resulting polygon is simplified to remove ## inner "loops", and can be disconnected. ## The result is a cell array, each cell containing a simple linear ring. ## ## This is a kind of dilation, but behaviour on corners is different. ## This function keeps angles of polygons, but there is no direct relation ## between length of 2 polygons. ## ## It is also possible to specify negative distance, and get all points ## inside the polygon. If the polygon is convex, the result equals ## morphological erosion of polygon by a ball with radius equal to the ## given distance. ## ## @seealso{polygons2d} ## @end deftypefn function loops = expandPolygon(poly, dist) # eventually copy first point at the end to ensure closed polygon if sum(poly(end, :)==poly(1,:))~=2 poly = [poly; poly(1,:)]; end # number of vertices of the polygon N = size(poly, 1)-1; # find lines parallel to polygon edges located at distance DIST lines = zeros(N, 4); for i=1:N side = createLine(poly(i,:), poly(i+1,:)); lines(i, 1:4) = parallelLine(side, dist); end # compute intersection points of consecutive lines lines = [lines;lines(1,:)]; poly2 = zeros(N, 2); for i=1:N poly2(i,1:2) = intersectLines(lines(i,:), lines(i+1,:)); end # split result polygon into set of loops (simple polygons) loops = polygonLoops(poly2); # keep only loops whose distance to original polygon is correct distLoop = zeros(length(loops), 1); for i=1:length(loops) distLoop(i) = distancePolygons(loops{i}, poly); end loops = loops(abs(distLoop-abs(dist)) ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dist} = } distancePointPolyline (@var{point},@var{poly}) ## Compute shortest distance between a point and a polyline ## Example: ## @example ## pt1 = [30 20]; ## pt2 = [30 5]; ## poly = [10 10;50 10;50 50;10 50]; ## distancePointPolyline([pt1;pt2], poly) ## ans = ## 10 ## 5 ## @end example ## ## @seealso{polygons2d, points2d,distancePointEdge, projPointOnPolyline} ## @end deftypefn function varargout = distancePointPolyline(point, poly, varargin) # number of points Np = size(point, 1); # allocate memory for result minDist = inf * ones(Np, 1); ## construct the set of edges edges = [poly(1:end-1, :) poly(2:end, :)]; ## compute distance between current each point and all edges dist = distancePointEdge(point, edges); ## get the minimum distance minDist = min(dist, [], 2); ## original loopy verion: # process each point # for p = 1:Np # # construct the set of edges # edges = [poly(1:end-1, :) poly(2:end, :)]; # # compute distance between current each point and all edges # dist = distancePointEdge(point(p, :), edges); # # update distance if necessary # minDist(p) = min(dist); # end # process output arguments if nargout<=1 varargout{1} = minDist; end endfunction ���������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/distancePolygons.m���������������������������������������������������������0000644�0001750�0001750�00000004007�12035504503�021025� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{dist} = } distancePolygons (@var{poly1},@var{poly2}) ## Compute the shortest distance between 2 polygons ## ## @end deftypefn function dist = distancePolygons(poly1, poly2) # compute distance of each vertex of a polygon to the other polygon dist1 = min(distancePointPolygon(poly1, poly2)); dist2 = min(distancePointPolygon(poly2, poly1)); # keep the minimum of the two distances dist = min(dist1, dist2); endfunction �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/polygons2d/polygons2d.m���������������������������������������������������������������0000644�0001750�0001750�00000021775�12130270223�017606� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {} polygons2d () ## Description of functions operating on 2D polygons ## ## The 'polygons' module contains functions operating on shapes composed ## of a vertex list, like polygons or polylines. ## ## We call 'polyline' the curve defined by a series of vertices. ## A polyline can be either closed or open, depending on whether the last ## vertex is connected to the first one or not. This can be given as an ## option is some functions in the module. ## A 'polygon' is the planar domain delimited by a closed polyline. We ## sometimes want to consider 'complex polygons', whose boundary is ## composed of several disjoint domains. The domain defined by a single ## closed polyline is called 'simple polygon'. ## We call 'curve' a polyline with many vertices, such that the polyline ## can be considered as a discrete approximation of a "real" curve. ## ## A simple polygon or polyline is represented by a N-by-2 array, each row ## of the array representing the coordinates of a vertex. ## Simple polygons are assumed to be closed, so there is no need to repeat ## the first vertex at the end. ## As both polygons and polylines can be represented by a list of vertex ## coordinates, some functions also consider the vertex list itself. Such ## functions are prefixed by 'pointSet'. Also, many functions prefixed by ## 'polygon' or 'polyline' works also on the other type of shape. ## ## For multiple-connected polygons, the different connected boundaries are ## separated by a row [NaN NaN]. ## ## For some functions, the orientation of the polygon can be relevant: CCW ## stands for 'Conter-Clockwise' (positive orientation), CW stands for ## 'Clockwise'. ## ## Polylines are parametrized in the following way: ## * the i-th vertex is located at position i-1 ## * points of the i-th edge have positions ranging linearly from i-1 to i ## The parametrization domain for an open polyline is from 0 to Nv-1, and ## from 0 to Nv for a closed polyline (positions 0 and Nv correspond to ## the same point). ## ## Example: ## # Simple polygon: ## P1 = [1 1;2 1;2 2;1 2]; ## drawPolygon(P1); ## axis([0 5 0 5]); ## # Multiple polygon: ## P2 = [10 10;40 10;40 40;10 40;NaN NaN;20 20;20 30;30 30;30 20]; ## figure;drawPolygon(P2); axis([0 50 0 50]); ## ## ## Point Sets ## pointSetBounds - Bounding box of a set of points ## pointSetsAverage - Compute the average of several point sets ## minimumCaliperDiameter - Minimum caliper diameter of a set of points ## findPoint - Find index of a point in an set from its coordinates ## ## Polylines ## polylinePoint - Extract a point from a polyline ## polylineLength - Return length of a polyline given as a list of points ## polylineCentroid - Compute centroid of a curve defined by a series of points ## polylineSubcurve - Extract a portion of a polyline ## reversePolyline - Reverse a polyline, by iterating vertices from the end ## isPointOnPolyline - Test if a point belongs to a polyline ## projPointOnPolyline - Compute position of a point projected on a polyline ## distancePointPolyline - Compute shortest distance between a point and a polyline ## distancePolylines - Compute the shortest distance between 2 polylines ## intersectPolylines - Find the common points between 2 polylines ## polylineSelfIntersections - Find self-intersections points of a polyline ## ## Curves (polylines with lot of vertices) ## parametrize - Parametrization of a curve, based on edges length ## curvature - Estimate curvature of a polyline defined by points ## cart2geod - Convert cartesian coordinates to geodesic coord. ## geod2cart - Convert geodesic coordinates to cartesian coord. ## curveMoment - Compute inertia moment of a 2D curve ## curveCMoment - Compute centered inertia moment of a 2D curve ## curveCSMoment - Compute centered scaled moment of a 2D curve ## ## Polygons ## polygonPoint - Extract a point from a polygon ## polygonSubcurve - Extract a portion of a polygon ## reversePolygon - Reverse a polygon, by iterating vertices from the end ## projPointOnPolygon - Compute position of a point projected on a polygon ## splitPolygons - Convert a NaN separated polygon list to a cell array of polygons ## clipPolygon - Clip a polygon with a rectangular box ## clipPolygonHP - Clip a polygon with a Half-plane defined by a directed line ## intersectLinePolygon - Intersection points between a line and a polygon ## intersectRayPolygon - Intersection points between a ray and a polygon ## polygonSelfIntersections - Find-self intersection points of a polygon ## convexHull - Convex hull of a set of points ## polygonLoops - Divide a possibly self-intersecting polygon into a set of simple loops ## expandPolygon - Expand a polygon by a given (signed) distance ## medialAxisConvex - Compute medial axis of a convex polygon ## ## Measures on Polygons ## isPointInPolygon - Test if a point is located inside a polygon ## polygonContains - Test if a point is contained in a multiply connected polygon ## polygonCentroid - Compute the centroid (center of mass) of a polygon ## polygonArea - Compute the signed area of a polygon ## polygonLength - Perimeter of a polygon ## polygonNormalAngle - Compute the normal angle at a vertex of the polygon ## polygonBounds - Compute the bounding box of a polygon ## distancePointPolygon - Compute shortest distance between a point and a polygon ## distancePolygons - Compute the shortest distance between 2 polygons ## ## Triangles ## isPointInTriangle - Test if a point is located inside a triangle ## triangleArea - Area of a triangle ## ## Functions from stochastic geometry ## steinerPoint - Compute steiner point (weighted centroid) of a polygon ## steinerPolygon - Create a Steiner polygon from a set of vectors ## supportFunction - Compute support function of a polygon ## convexification - Compute the convexification of a polygon ## ## Input, Output and conversions ## readPolygon - Read a polygon stored in a file ## polygonToRow - Convert polygon coordinates to a row vector ## rowToPolygon - Create a polygon from a row vector ## rectAsPolygon - Convert a (centered) rectangle into a series of points ## ## Drawing functions ## drawPolyline - Draw a polyline specified by a list of points ## drawPolygon - Draw a polygon specified by a list of points ## fillPolygon - Fill a polygon specified by a list of points ## ## ## Credits: ## * function intersectPolylines uses the 'interX' contribution from "NS" ## (file exchange 22441, called 'curve-intersections') ## ## ----- ## Author: David Legland ## e-mail: david.legland@@grignon.inra.fr ## created the 07/11/2005. ## Homepage: @url{http://matgeom.sourceforge.net/} ## @url{http://www.pfl-cepia.inra.fr/index.php?page=geom2d} ## Copyright INRA - Cepia Software Platform. ## ## @end deftypefn function polygons2d () help('polygons2d'); endfunction ���geometry/inst/octclip/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12130276034�014657� 5����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/octclip/oc_polybool.m�����������������������������������������������������������������0000644�0001750�0001750�00000017236�12035504503�017365� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2011, José Luis García Pallero, ## ## This file is part of OctCLIP. ## ## OctCLIP is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or (at ## your option) any later version. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## @deftypefn{Function File}{[@var{X},@var{Y},@var{nPol},@var{nInt},@var{nPert}] =}oc_polybool(@var{sub},@var{clip},@var{op}) ## @deftypefnx{Function File}{[@var{X},@var{Y},@var{nPol},@var{nInt},@var{nPert}] =}oc_polybool(@var{sub},@var{clip}) ## ## This function performs boolean operations between two polygons using the ## Greiner-Hormann algorithm (http://davis.wpi.edu/~matt/courses/clipping/). ## ## @var{sub} is a two column matrix containing the X and Y coordinates of the ## vertices for the subject polygon. ## ## @var{clip} is a two column matrix containing the X and Y coordinates of the ## vertices for the clipper polygon. ## ## @var{op} is a text string containing the operation to perform between ## @var{sub} and @var{clip}. Possible values are: ## ## @itemize @bullet ## @item @var{'AND'} ## Intersection of @var{sub} and @var{clip} (value by default). ## @item @var{'OR'} ## Union of @var{subt} and @var{clip}. ## @item @var{'AB'} ## Operation @var{sub} - @var{clip}. ## @item @var{'BA'} ## Operation of @var{clip} - @var{sub}. ## @end itemize ## ## For the matrices @var{sub} and @var{clip}, the first point is not needed to ## be repeated at the end (but is permitted). Pairs of (NaN,NaN) coordinates in ## @var{sub} and/or @var{clip} are ommitted. ## ## @var{X} is a column vector containing the X coordinates of the vertices of ## the resultant polygon(s). ## ## @var{Y} is a column vector containing the Y coordinates of the vertices of ## the resultant polygon(s). ## ## @var{nPol} is the number of output polygons. ## ## @var{nInt} is the number of intersections between @var{sub} and @var{clip}. ## ## @var{nPert} is the number of perturbed points of the @var{clip} polygon in ## any particular case (points in the oborder of the other polygon) occurs see ## http://davis.wpi.edu/~matt/courses/clipping/ for details. ## @end deftypefn function [X,Y,nPol,nInt,nPert] = oc_polybool(sub,clip,op) try functionName = 'oc_polybool'; minArg = 2; maxArg = 3; #******************************************************************************* #NUMBER OF INPUT ARGUMENTS CHECKING #******************************************************************************* #number of input arguments checking if (narginmaxArg) error(['Incorrect number of input arguments (#d)\n\t ',... 'Correct number of input arguments = #d or #d'],... nargin,minArg,maxArg); end #check if we omit the op argument if nargin==minArg #by default, use AND op = 'AND'; end #******************************************************************************* #INPUT ARGUMENTS CHECKING #******************************************************************************* #checking input arguments [op] = checkInputArguments(sub,clip,op); catch #error message error('\n\tIn function #s:\n\t -#s ',functionName,lasterr); end #******************************************************************************* #COMPUTATION #******************************************************************************* try #calling oct function [X,Y,nPol,nInt,nPert] = _oc_polybool(sub,clip,op); catch #error message error('\n\tIn function #s:\n\tIn function #s ',functionName,lasterr); end #******************************************************************************* #AUXILIARY FUNCTION #******************************************************************************* function [outOp] = checkInputArguments(sub,clip,inOp) #sub must be matrix type if ismatrix(sub) #a dimensions [rowSub,colSub] = size(sub); else error('The first input argument is not numeric'); end #clip must be matrix type if ismatrix(clip) #b dimensions [rowClip,colClip] = size(clip); else error('The second input argument is not numeric'); end #checking dimensions if (colSub~=2)||(colClip~=2) error('The columns of input arguments must be 2'); end #operation must be a text string if ~ischar(inOp) error('The third input argument is not a text string'); else #upper case outOp = toupper(inOp); #check values if (~strcmp(outOp,'AND'))&&(~strcmp(outOp,'OR'))&& ... (~strcmp(outOp,'AB'))&&(~strcmp(outOp,'BA')) error('The third input argument is not correct'); end end #*****END OF FUNCIONS***** #*****FUNCTION TESTS***** #tests for input arguments %!error(oc_polybool) %!error(oc_polybool(1,2,3,4)) %!error(oc_polybool('string',2,3)) %!error(oc_polybool(1,'string',3)) %!error(oc_polybool(1,2,3)) #demo program %!demo %! #subject polygon %! clSub = [9.0 7.5 %! 9.0 3.0 %! 2.0 3.0 %! 2.0 4.0 %! 8.0 4.0 %! 8.0 5.0 %! 2.0 5.0 %! 2.0 6.0 %! 8.0 6.0 %! 8.0 7.0 %! 2.0 7.0 %! 2.0 7.5 %! 9.0 7.5]; %! #clipper polygon %! clClip = [2.5 1.0 %! 7.0 1.0 %! 7.0 8.0 %! 6.0 8.0 %! 6.0 2.0 %! 5.0 2.0 %! 5.0 8.0 %! 4.0 8.0 %! 4.0 2.0 %! 3.0 2.0 %! 3.0 8.0 %! 2.5 8.0 %! 2.5 1.0]; %! #limits for the plots %! clXLim = [1.5 11.75]; %! clYLim = [0.5 8.50]; %! #compute intersection %! [clXI,clYI] = oc_polybool(clSub,clClip,'and'); %! #compute union %! [clXU,clYU] = oc_polybool(clSub,clClip,'or'); %! #compute A-B %! [clXA,clYA] = oc_polybool(clSub,clClip,'ab'); %! #compute B-A %! [clXB,clYB] = oc_polybool(clSub,clClip,'ba'); %! #plot window for intersection %! subplot(2,2,1); %! plot(clXI,clYI,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),... %! clClip(:,1),clClip(:,2)); %! axis('equal'); %! xlim(clXLim); %! ylim(clYLim); %! title('OctCLIP intersection'); %! legend('Intersection','Subject polygon','Clipper polygon',... %! 'location','southeast'); %! #plot window for union %! subplot(2,2,2); %! plot(clXU,clYU,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),... %! clClip(:,1),clClip(:,2)); %! axis('equal'); %! xlim(clXLim); %! ylim(clYLim); %! title('OctCLIP union'); %! legend('Union','Subject polygon','Clipper polygon','location','southeast'); %! #plot window for A-B %! subplot(2,2,3); %! plot(clXA,clYA,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),... %! clClip(:,1),clClip(:,2)); %! axis('equal'); %! xlim(clXLim); %! ylim(clYLim); %! title('OctCLIP A-B'); %! legend('A-B','Subject polygon','Clipper polygon','location','southeast'); %! #plot window for B-A %! subplot(2,2,4); %! plot(clXB,clYB,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),... %! clClip(:,1),clClip(:,2)); %! axis('equal'); %! xlim(clXLim); %! ylim(clYLim); %! title('OctCLIP B-A'); %! legend('B-A','Subject polygon','Clipper polygon','location','southeast'); %! #input message %! disp('Press ENTER to continue ...'); %! pause(); %! #kill and close the plot window %! clf(); %! close(); #*****END OF TESTS***** ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/meshes3d/�����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12130276034�014735� 5����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/meshes3d/drawMesh.m�������������������������������������������������������������������0000644�0001750�0001750�00000013026�12035701351�016666� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} drawMesh (@var{vertices}, @var{faces}) ## @deftypefnx {Function File} {@var{h} =} drawMesh (@var{mesh}) ## @deftypefnx {Function File} {@var{h} =} drawMesh (@dots{}, @var{color}) ## @deftypefnx {Function File} {@var{h} =} drawMesh (@dots{}, @var{name},@var{value}) ## Draw a 3D mesh defined by vertices and faces ## ## drawMesh(VERTICES, FACES) ## Draws the 3D mesh defined by vertices VERTICES and the faces FACES. ## vertices is a [NVx3] array containing coordinates of vertices, and FACES ## is either a [NFx3] or [NFx4] array containing indices of vertices of ## the triangular or rectangular faces. ## FACES can also be a cell array, in the content of each cell is an array ## of indices to the vertices of the current face. Faces can have different ## number of vertices. ## ## drawMesh(MESH) ## Where mesh is a structure with fields 'vertices' and 'faces', draws the ## given mesh. ## ## drawMesh(..., COLOR) ## Use the specified color to render the mesh faces. ## ## drawMesh(..., NAME, VALUE) ## Use one or several pairs of parameter name/value to specify drawing ## options. Options are the same as the 'patch' function. ## ## ## H = drawMesh(...); ## Also returns a handle to the created patch. ## ## WARNING: This function doesn't work with gnuplot (as of version 4.1) ## ## Example: ## @example ## [v f] = createSoccerBall; ## drawMesh(v, f); ## @end example ## ## @seealso{polyhedra, meshes3d, patch} ## @end deftypefn function varargout = drawMesh(vertices, faces, varargin) if strcmpi (graphics_toolkit(),"gnuplot") error ("geometry:Incompatibility", ... ["This function doesn't work with gnuplot (as of version 4.1)." ... "Use graphics_toolkit('fltk').\n"]); end ## Initialisations # Check if the input is a mesh structure if isstruct(vertices) # refresh options if nargin > 1 varargin = [{faces} varargin]; end # extract data to display faces = vertices.faces; vertices = vertices.vertices; end # process input arguments switch length(varargin) case 0 # default color is red varargin = {'facecolor', [1 0 0]}; case 1 # use argument as color for faces varargin = {'facecolor', varargin{1}}; otherwise # otherwise keep varargin unchanged end # overwrites on current figure hold on; # if vertices are 2D points, add a z=0 coordinate if size(vertices, 2)==2 vertices(1,3)=0; end ## Use different processing depending on the type of faces if isnumeric(faces) # array FACES is a NC*NV indices array, with NV : number of vertices of # each face, and NC number of faces h = patch('vertices', vertices, 'faces', faces, varargin{:}); elseif iscell(faces) # array FACES is a cell array h = zeros(length(faces(:)), 1); for f=1:length(faces(:)) # get vertices of the cell face = faces{f}; # Special processing in case of multiple polygonal face: # each polygonal loop is separated by a NaN. if sum(isnan(face))~=0 # find indices of loops breaks inds = find(isnan(face)); # replace NaNs by index of first vertex of each polygon face(inds(2:end)) = face(inds(1:end-1)+1); face(inds(1)) = face(1); face(length(face)+1)= face(inds(end)+1); end # draw current face cnodes = vertices(face, :); h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), [1 0 0]); end # set up drawing options set(h, varargin{:}); else error('second argument must be a face array'); end ## Process output arguments # format output parameters if nargout>0 varargout{1}=h; end endfunction %!demo %! close all %! graphics_toolkit ("fltk"); %! [v f] = createCubeOctahedron; %! drawMesh(v, f); %! view (3) %!demo %! close all %! graphics_toolkit ("gnuplot"); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/meshes3d/createCube.m�����������������������������������������������������������������0000644�0001750�0001750�00000006166�12130275640�017170� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{v},@var{e},@var{f}] =} createCube () ## @deftypefnx {Function File} {[@var{v},@var{f}] =} createCube () ## @deftypefnx {Function File} {@var{mesh} =} createCube () ## Create a 3D mesh representing the unit cube ## ## [V E F] = createCube ## Create a unit cube, as a polyhedra representation. ## c has the form [V E F], where V is a 8-by-3 array with vertices ## coordinates, E is a 12-by-2 array containing indices of neighbour ## vertices, and F is a 6-by-4 array containing vertices array of each ## face. ## ## [V F] = createCube; ## Returns only the vertices and the face vertex indices. ## ## MESH = createCube; ## Returns the data as a mesh structure, with fields 'vertices', 'edges' ## and 'faces'. ## ## Example ## @example ## [n e f] = createCube; ## drawMesh(n, f); ## @end example ## ## @seealso{meshes3d, drawMesh, createOctahedron, createTetrahedron, ## createDodecahedron, createIcosahedron, createCubeOctahedron} ## @end deftypefn function varargout = createCube() x0 = 0; dx= 1; y0 = 0; dy= 1; z0 = 0; dz= 1; nodes = [... x0 y0 z0; ... x0+dx y0 z0; ... x0 y0+dy z0; ... x0+dx y0+dy z0; ... x0 y0 z0+dz; ... x0+dx y0 z0+dz; ... x0 y0+dy z0+dz; ... x0+dx y0+dy z0+dz]; edges = [1 2;1 3;1 5;2 4;2 6;3 4;3 7;4 8;5 6;5 7;6 8;7 8]; # faces are oriented such that normals point outwards faces = [1 3 4 2;5 6 8 7;2 4 8 6;1 5 7 3;1 2 6 5;3 7 8 4]; # format output varargout = formatMeshOutput(nargout, nodes, edges, faces); endfunction %!demo %! [n e f] = createCube; %! drawMesh(n, f); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/meshes3d/meshes3d_Contents.m����������������������������������������������������������0000644�0001750�0001750�00000013044�12035676207�020517� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} meshes3d_Contents () ## MESHES3D 3D Surface Meshes ## Version 1.0 21-Mar-2011 . ## ## Creation, vizualization, and manipulation of 3D surface meshes or ## polyhedra. ## ## Meshes and Polyhedra are represented by a couple of variables @{V, F@}: ## V: Nv-by-3 array of vertices: [x1 y1 z1; @dots{} ; xn yn zn]; ## F: is either a NF-by-3 or NF-by-4 array containing reference for ## vertices of each face, or a NF-by-1 cell array, where each cell is an ## array containing a variable number of node indices. ## For some functions, the array E of edges is needed. It consists in a ## NE-by-2 array containing indices of source and target vertices. ## ## The library provides function to create basic polyhedric meshes (the 5 ## platonic solids, plus few others), as well as functions to perform ## basic computations (surface area, normal angles, face centroids @dots{}). ## The 'MengerSponge' structure is an example of mesh that is not simply ## connected (multiple tunnels in the structure). ## ## The drawMesh function is mainly a wrapper to the Matlab 'patch' ## function, allowing passing arguments more quickly. ## ## Example ## @example ## # create a soccer ball mesh and display it ## [n e f] = createSoccerBall; ## drawMesh(n, f, 'faceColor', 'g', 'linewidth', 2); ## axis equal; ## @end example ## ## ## General functions ## meshFace - Return the vertex indices of a face in a mesh ## computeMeshEdges - Computes edges array from face array ## meshEdgeFaces - Compute index of faces adjacent to each edge of a mesh ## faceCentroids - Compute centroids of a mesh faces ## faceNormal - Compute normal vector of faces in a 3D mesh ## ## Measures on meshes ## meshSurfaceArea - Surface area of a polyhedral mesh ## trimeshSurfaceArea - Surface area of a triangular mesh ## meshEdgeLength - Lengths of edges of a polygonal or polyhedral mesh ## meshDihedralAngles - Dihedral at edges of a polyhedal mesh ## polyhedronNormalAngle - Compute normal angle at a vertex of a 3D polyhedron ## polyhedronMeanBreadth - Mean breadth of a convex polyhedron ## ## Basic processing ## triangulateFaces - Convert face array to an array of triangular faces ## meshReduce - Merge coplanar faces of a polyhedral mesh ## minConvexHull - Return the unique minimal convex hull of a set of 3D points ## polyhedronSlice - Intersect a convex polyhedron with a plane. ## checkMeshAdjacentFaces - Check if adjacent faces of a mesh have similar orientation ## clipMeshVertices - Clip vertices of a surfacic mesh and remove outer faces ## clipConvexPolyhedronHP - Clip a convex polyhedron by a plane ## ## Typical polyhedra ## polyhedra - Index of classical polyhedral meshes ## createCube - Create a 3D mesh representing the unit cube ## createOctahedron - Create a 3D mesh representing an octahedron ## createCubeOctahedron - Create a 3D mesh representing a cube-octahedron ## createIcosahedron - Create a 3D mesh representing an Icosahedron. ## createDodecahedron - Create a 3D mesh representing a dodecahedron ## createTetrahedron - Create a 3D mesh representing a tetrahedron ## createRhombododecahedron - Create a 3D mesh representing a rhombododecahedron ## createTetrakaidecahedron - Create a 3D mesh representing a tetrakaidecahedron ## ## Less typical polyhedra ## createSoccerBall - Create a 3D mesh representing a soccer ball ## createMengerSponge - Create a cube with an inside cross removed ## steinerPolytope - Create a steiner polytope from a set of vectors ## ## Drawing functions ## drawFaceNormals - Draw normal vector of each face in a mesh ## drawMesh - Draw a 3D mesh defined by vertices and faces ## @end deftypefn function meshes3d_Contents () help meshes3d_Contents endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/meshes3d/private/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12130276034�016407� 5����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/meshes3d/private/parseMeshData.m������������������������������������������������������0000644�0001750�0001750�00000005702�12035504503�021311� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{mesh} =} parseMeshData (@var{vertices},@var{edges},@var{faces}) ## @deftypefnx {Function File} {@var{mesh} =} parseMeshData (@var{vertices},@var{faces}) ## @deftypefnx {Function File} {[@var{vertices},@var{edges},@var{faces}] =} parseMeshData (@var{mesh}) ## @deftypefnx {Function File} {[@var{vertices},@var{faces}] =} parseMeshData (@var{mesh}) ## Conversion of data representation for meshes ## ## MESH = parseMeshData(VERTICES, EDGES, FACES) ## MESH = parseMeshData(VERTICES, FACES) ## [VERTICES EDGES FACES] = parseMeshData(MESH) ## [VERTICES FACES] = parseMeshData(MESH) ## ## ## @seealso{meshes3d, formatMeshOutput} ## @end deftypefn function varargout = parseMeshData(varargin) # initialize edges edges = []; # Process input arguments if nargin == 1 # input is a data structure mesh = varargin{1}; vertices = mesh.vertices; faces = mesh.faces; if isfield(mesh, 'edges') edges = mesh.edges; end elseif nargin == 2 # input are vertices and faces vertices = varargin{1}; faces = varargin{2}; elseif nargin == 3 # input are vertices, edges and faces vertices = varargin{1}; edges = varargin{2}; faces = varargin{3}; else error('Wrong number of arguments'); end varargout = formatMeshOutput(nargout, vertices, edges, faces); endfunction ��������������������������������������������������������������geometry/inst/meshes3d/private/formatMeshOutput.m���������������������������������������������������0000644�0001750�0001750�00000006655�12035504503�022126� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{output} =} formatMeshOutput (@var{nbargs}, @var{vertices},@var{edges},@var{faces}) ## @deftypefnx {Function File} {@var{output} =} formatMeshOutput (@var{nbargs}, @var{vertices},@var{faces}) ## Format mesh output depending on nargout ## ## OUTPUT = formatMeshOutput(@var{nbargs}, VERTICES, EDGES, FACES) ## Utilitary function to convert mesh data . ## If @var{nbargs} is 0 or 1, return a matlab structure with fields vertices, ## edges and faces. ## If @var{nbargs} is 2, return a cell array with data VERTICES and FACES. ## If @var{nbargs} is 3, return a cell array with data VERTICES, EDGES and ## FACES. ## ## OUTPUT = formatMeshOutput(@var{nbargs}, VERTICES, FACES) ## Same as before, but do not intialize EDGES in output. NARGOUT can not ## be equal to 3. ## ## Example ## # Typical calling sequence (for a very basic mesh of only one face) ## v = [0 0; 0 1;1 0;1 1]; ## e = [1 2;1 3;2 4;3 4]; ## f = [1 2 3 4]; ## ## varargout = formatMeshOutput(nargout, v, e, f); ## ## @seealso{meshes3d, parseMeshData} ## @end deftypefn function res = formatMeshOutput(nbArgs, vertices, edges, faces) if nargin < 4 faces = edges; edges = []; end switch nbArgs case {0, 1} # output is a data structure with fields vertices, edges and faces mesh.vertices = vertices; mesh.edges = edges; mesh.faces = faces; res = {mesh}; case 2 # keep only vertices and faces res = cell(nbArgs, 1); res{1} = vertices; res{2} = faces; case 3 # return vertices, edges and faces as 3 separate outputs res = cell(nbArgs, 1); res{1} = vertices; res{2} = edges; res{3} = faces; otherwise error('Can not manage more than 3 outputs'); end endfunction �����������������������������������������������������������������������������������geometry/inst/meshes3d/createCubeOctahedron.m�������������������������������������������������������0000644�0001750�0001750�00000006171�12035504503�021170� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{v}, @var{e}, @var{f}] =} createCubeOctahedron () ## @deftypefnx {Function File} {@var{mesh} =} createCubeOctahedron () ## Create a 3D mesh representing a cube-octahedron ## ## [V E F] = createCubeOctahedron; ## Cubeoctahedron can be seen either as a truncated cube, or as a ## truncated octahedron. ## V is the 12-by-3 array of vertex coordinates ## E is the 27-by-2 array of edge vertex indices ## F is the 1-by-14 cell array of face vertex indices ## ## [V F] = createCubeOctahedron; ## Returns only the vertices and the face vertex indices. ## ## MESH = createCubeOctahedron; ## Returns the data as a mesh structure, with fields 'vertices', 'edges' ## and 'faces'. ## ## @seealso{meshes3d, drawMesh, createCube, createOctahedron} ## @end deftypefn function varargout = createCubeOctahedron() nodes = [... 0 -1 1;1 0 1;0 1 1;-1 0 1; ... 1 -1 0;1 1 0;-1 1 0;-1 -1 0;... 0 -1 -1;1 0 -1;0 1 -1;-1 0 -1]; edges = [... 1 2; 1 4; 1 5; 1 8; ... 2 3; 2 5; 2 6; ... 3 4; 3 6; 3 7; ... 4 7; 4 8; ... 5 9; 5 10; ... 6 10; 6 11; ... 7 11; 7 12; ... 8 9; 8 12; ... 9 10; 9 12; ... 10 11; 11 12]; faces = {... [1 2 3 4], [1 5 2], [2 6 3], [3 7 4], [4 8 1], ... [5 10 6 2], [3 6 11 7], [4 7 12 8], [1 8 9 5], ... [5 9 10], [6 10 11], [7 11 12], [8 12 9], [9 12 11 10]}; # format output varargout = formatMeshOutput(nargout, nodes, edges, faces); endfunction %!demo %! [n e f] = createCubeOctahedron; %! drawMesh(n, f); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/graphs/�������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12130276034�014506� 5����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/graphs/graphs_Contents.m��������������������������������������������������������������0000644�0001750�0001750�00000016422�12035504503�020031� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} graphs_Contents () ## GRAPHS Simple Toolbox for manipulating Geometric Graphs ## Version 0.5 11-Apr-2010 . ## ## The aim of this package is to provides functions to easily create, ## modify and display geometric graphs (geometric in a sense position ## of vertices is kept in memory). ## ## Graph structure is represented by at least two arrays: ## * NODES, which contains coordinates of each vertex ## * EDGES, which contains indices of start and end vertex. ## ## Others arrays may sometimes be used: ## * FACES, which contains indices of vertices of each face (either a ## double array, or a cell array) ## * CELLS, which contains indices of faces of each cell. ## ## An alternative representation is to use a structure, with fields: ## * edges ## * faces ## * cells ## corresponding to the data described above. ## ## Note that topological description of 2D graph is entirely contained in ## EDGES array, and that NODES array is used only to display graph ## ## Caution: this type of data structure is easy to create and to manage, ## but may be very inefficient for some algorithms. ## ## Graphs are usually considered as non-oriented in this package. ## ## ## Graph creation ## knnGraph - Create the k-nearest neighbors graph of a set of points ## delaunayGraph - Graph associated to Delaunay triangulation of input points ## euclideanMST - Build euclidean minimal spanning tree of a set of points ## prim_mst - Minimal spanning tree by Prim's algorithm ## ## Create graph from images ## imageGraph - Create equivalent graph of a binary image ## boundaryGraph - Get boundary of image as a graph ## gcontour2d - Creates contour graph of a 2D binary image. ## gcontour3d - Create contour graph of a 3D binary image. ## vectorize - Transform a binary skeleton into a graph (nodes and edges) ## ## Graph information ## grNodeDegree - Degree of a node in a (undirected) graph ## grNodeInnerDegree - Inner degree of a node in a graph ## grNodeOuterDegree - Outer degree of a node in a graph ## grNeighborNodes - Find adjacent nodes of a given node ## grNeighborEdges - Find adjacent edges of a given node ## grOppositeNode - Return opposite node in an edge ## grLabel - Associate a label to each connected component of the graph ## ## Graph management (low level operations) ## grRemoveNode - Remove a node in a graph ## grRemoveNodes - Remove several nodes in a graph ## grRemoveEdge - Remove an edge in a graph. ## grRemoveEdges - Remove several edges from a graph ## ## Graph processing (general applications) ## mergeGraphs - Merge two graphs, by adding nodes, edges and faces lists. ## grMergeNodes - Merge two (or more) nodes in a graph. ## grMergeMultipleNodes - Simplify a graph by merging multiple nodes ## grMergeMultipleEdges - Remove all edges sharing the same extremities ## grSimplifyBranches - Replace branches of a graph by single edges ## ## Filtering operations on Graph ## grMean - Compute mean from neihgbours ## grMedian - Compute median from neihgbours ## grDilate - Morphological dilation on graph ## grErode - Morphological erosion on graph ## grClose - Morphological closing on graph ## grOpen - Morphological opening on graph ## ## Geodesic operations ## grPropagateDistance - Propagates distances from a vertex to other vertices ## grVertexEccentricity - Eccentricity of vertices in the graph ## graphDiameter - Diameter of a graph ## graphPeripheralVertices - Peripheral vertices of a graph ## graphCenter - Center of a graph ## graphRadius - Radius of a graph ## grFindGeodesicPath - Find a geodesic path between two nodes in the graph ## grFindMaximalLengthPath - Find a path that maximizes sum of edge weights ## ## Operations for geometric graphs ## grMergeNodeClusters - Merge cluster of connected nodes in a graph ## grMergeNodesMedian - Replace several nodes by their median coordinate ## clipGraph - Clip a graph with a rectangular area ## addSquareFace - Add a (square) face defined from its vertices to a graph ## grFaceToPolygon - Compute the polygon corresponding to a graph face ## graph2Contours - Convert a graph to a set of contour curves ## ## Voronoi Graphs ## voronoi2d - Compute a voronoi diagram as a graph structure ## boundedVoronoi2d - Return a bounded voronoi diagram as a graph structure ## centroidalVoronoi2d - Create a 2D Centroidal Voronoi Tesselation ## cvtUpdate - Update germs of a CVT with given points ## cvtIterate - Update germs of a CVT using random points with given density ## ## Graph display ## drawGraph - Draw a graph, given as a set of vertices and edges ## drawGraphEdges - Draw edges of a graph ## drawGraphFaces - Draw faces of a graph ## drawDigraph - Draw a directed graph, given as a set of vertices and edges ## drawDirectedEdges - Draw edges with arrow indicating direction ## drawEdgeLabels - Draw values associated to graph edges ## drawNodeLabels - Draw values associated to graph nodes ## drawSquareMesh - Draw a 3D square mesh given as a graph ## patchGraph - Transform 3D graph (mesh) into a patch handle ## ## @end deftypefn function graphs_Contents() help graphs_Contents endfunction ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/graphs/drawGraph.m��������������������������������������������������������������������0000644�0001750�0001750�00000021360�12035504503�016604� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} drawGraph (@var{nodes}, @var{edges}) ## @deftypefnx {Function File} drawGraph (@var{nodes}, @var{edges}, @var{faces}) ## @deftypefnx {Function File} drawGraph (@var{graph}) ## @deftypefnx {Function File} drawGraph (@dots{}, @var{snodes}) ## @deftypefnx {Function File} drawGraph (@dots{}, @var{snodes}, @var{sedges}) ## @deftypefnx {Function File} drawGraph (@dots{}, @var{snodes}, @var{sedges}, @var{sfaces}) ## @deftypefnx {Function File} {@var{h} = } drawGraph (@dots{}) ## @deftypefnx {Function File} {[@var{h} @var{he}] = } drawGraph (@dots{}) ## @deftypefnx {Function File} {[@var{h} @var{he} @var{hf}] = } drawGraph (@dots{}) ## Draw a graph, given as a set of vertices and edges ## ## DRAWGRAPH(NODES, EDGES) ## draw a graph specified by a set of nodes (array N*2 or N*3, ## corresponding to coordinate of each node), and a set of edges (an array ## Ne*2, containing for each edge the first and the second node). ## Default drawing is a red circle for nodes and a blue line for edges. ## ## DRAWGRAPH(NODES, EDGES, FACES) ## also draw faces of the graph as patches. ## ## DRAWGRAPH(GRAPH) ## passes argument in a srtucture with at least 2 fields named 'nodes' and ## 'edges', and possibly one field 'faces', corresponding to previously ## described parameters. ## GRAPH can also be a cell array, whose first element is node array, ## second element is edges array, and third element, if present, is faces ## array. ## ## ## DRAWGRAPH(..., SNODES) ## DRAWGRAPH(..., SNODES, SEDGES) ## DRAWGRAPH(..., SNODES, SEDGES, SFACES) ## specify the draw mode for each element, as in the classical 'plot' ## function. To not display some elements, uses 'none'. ## ## ## H = DRAWGRAPH(...) ## return handle to the set of edges. ## ## [HN, HE] = DRAWGRAPH(...) ## return handle to the set of nodes and to the set of edges. ## ## [HN, HE, HF] = DRAWGRAPH(...) ## Also return handle to the set of faces. ## ## @end deftypefn function varargout = drawGraph(varargin) ## initialisations # uses empty arrays by default for edges and faces e = []; f = []; # default styles for nodes, edges, and faces # nodes are drawn as red circles sn = {'linestyle', 'none', 'color', 'r', 'marker', 'o'}; # edges are drawn as blue lines se = {'linestyle', '-', 'color', 'b'}; # faces are cyan, their edges are not drawn sf = {'EdgeColor', 'none', 'Facecolor', 'c'}; ## Process input arguments # case of a call without arguments if nargin==0 help drawGraph; return; end # --------------------------------------------------------------- # First extract the graph structure var = varargin{1}; if iscell(var) # graph is stored as a cell array: first cell is nodes, second one is # edges, and third is faces n = var{1}; if length(var)>1 e = var{2}; end if length(var)>2 f = var{3}; end varargin(1) = []; elseif isstruct(var) # graph is stored as a structure, with fields 'nodes', 'edges', and # eventually 'faces'. n = var.nodes; e = var.edges; if isfield(var, 'faces') f = var.faces; end varargin(1) = []; else # graph is stored as set of variables: nodes, edges, and eventually # faces n = varargin{1}; e = varargin{2}; varargin(1:2) = []; if ~isempty(varargin) var = varargin{1}; if isnumeric(var) # faces are stored in a numeric array of indices f = var; varargin(1) = []; elseif iscell(var) if ~ischar(var{1}) # faces are stored in a cell array, each cell containing a # row vector of indices f = var; varargin(1) = []; end end end end # extract drawing style if ~isempty(varargin) sn = concatArguments(sn, varargin{1}); end if length(varargin)>1 se = concatArguments(se, varargin{2}); end if length(varargin)>2 sf = concatArguments(sf, varargin{3}); end ## main drawing processing hold on; if size(n, 2)==2 # Draw a 2 dimensional graph ---------------------- # Draw faces of the graph ------------ if ~strcmp(sf{1}, 'none') && ~isempty(f) if iscell(f) # each face is contained in a cell. hf = zeros(size(f)); for fi=1:length(f) hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:}); end else # process faces as an Nf*N array. Nf is the number of faces, # and all faces have the same number of vertices (nodes). hf = patch('Faces', f, 'Vertices', n, sf{:}); end end # Draw 2D Edges ---------------------- if ~strcmp(se{1}, 'none') && size(e, 1)>0 he = plot([n(e(:,1),1) n(e(:,2),1)]', [n(e(:,1),2) n(e(:,2),2)]', se{:}); end # Draw 2D nodes ---------------------- if ~strcmp(sn{1}, 'none') hn = plot(n(:,1), n(:,2), sn{:}); end elseif size(n, 2)==3 # Draw a 3 dimensional graph ---------------------- # use a zbuffer to avoid display pbms. set(gcf, 'renderer', 'zbuffer'); # Draw 3D Faces ---------------------- if ~strcmp(sf{1}, 'none') if iscell(f) # each face is contained in a cell. hf = zeros(size(f)); for fi=1:length(f) hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:}); end else # process faces as an Nf*N array. Nf i the number of faces, # and all faces have the same number of vertices (nodes). hf = patch('Faces', f, 'Vertices', n, sf{:}); end end # Draw 3D edges ---------------------- if ~strcmp(se{1}, 'none') && size(e, 1)>0 # he = plot3(... # [n(e(:,1),1) n(e(:,2),1)]', ... # [n(e(:,1),2) n(e(:,2),2)]', ... # [n(e(:,1),3) n(e(:,2),3)]', ... # se{:}); he = line(... [n(e(:,1),1) n(e(:,2),1)]', ... [n(e(:,1),2) n(e(:,2),2)]', ... [n(e(:,1),3) n(e(:,2),3)]', ... se{:}); end # Draw 3D nodes ---------------------- if ~strcmp(sn{1}, 'none'); hn = plot3(n(:,1), n(:,2), n(:,3), sn{:}); end end ## Format output arguments # return handle to edges if nargout==1 varargout{1} = he; end # return handle to nodes and edges if nargout==2 varargout{1} = hn; varargout{2} = he; end # return handle to nodes, edges and faces if nargout==3 varargout{1} = hn; varargout{2} = he; varargout{3} = hf; end endfunction function res = concatArguments(in1, in2) # in1 is a cell array already initialized # in2 is an argument that can be: # - empty # - the string 'none' # - another cell array if isempty(in2) res = in1; return; end if ischar(in2) if strcmp('none', in2) res = {'none'}; return; end end if iscell(in1) res = [in1(:)' in2(:)']; else res = [{in1} in2(:)]; end endfunction ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������geometry/inst/graphs/knnGraph.m���������������������������������������������������������������������0000644�0001750�0001750�00000004664�12035504503�016445� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {@var{edges} = } knnGrpah (@var{nodes}) ## Create the k-nearest neighbors graph of a set of points ## ## EDGES = knnGraph(NODES) ## ## Example ## @example ## ## nodes = rand(10, 2); ## edges = knnGraph(nodes); ## drawGraph(nodes, edges); ## ## @end example ## ## @end deftypefn function edges = knnGraph(nodes, varargin) # get number of neighbors for each node k = 2; if ~isempty(varargin) k = varargin{1}; end # init size of arrays n = size(nodes, 1); edges = zeros(k*n, 2); # iterate on nodes for i = 1:n dists = distancePoints(nodes(i,:), nodes); [dists inds] = sort(dists); ##ok for j = 1:k edges(k*(i-1)+j, :) = [i inds(j+1)]; end end # remove double edges edges = unique(sort(edges, 2), 'rows'); endfunction %!demo %! nodes = rand(10, 2); %! edges = knnGraph(nodes); %! drawGraph(nodes, edges); %! axis tight ����������������������������������������������������������������������������geometry/inst/graphs/voronoi2d.m��������������������������������������������������������������������0000644�0001750�0001750�00000004712�12035504503�016610� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{nodes} @var{edges} @var{faces}] = } voronoi2d (@var{germs}) ## Compute a voronoi diagram as a graph structure ## ## [NODES EDGES FACES] = voronoi2d(GERMS) ## GERMS an array of points with dimension 2 ## NODES, EDGES, FACES: usual graph representation, FACES as cell array ## ## Example ## @example ## ## [n e f] = voronoi2d(rand(100, 2)*100); ## drawGraph(n, e); ## ## @end example ## ## @end deftypefn function [nodes edges faces] = voronoi2d(germs) [V C] = voronoin(germs); nodes = V(2:end, :); edges = zeros(0, 2); faces = {}; for i=1:length(C) cell = C{i}; if ismember(1, cell) continue; end cell = cell-1; edges = [edges; sort([cell' cell([2:end 1])'], 2)]; ##ok faces{length(faces)+1} = cell; ##ok end edges = unique(edges, 'rows'); endfunction %!demo %! [n e f] = voronoi2d(rand(100, 2)*100); %! drawGraph(n, e); %! axis tight ������������������������������������������������������geometry/inst/graphs/delaunayGraph.m����������������������������������������������������������������0000644�0001750�0001750�00000006571�12035504503�017460� 0����������������������������������������������������������������������������������������������������ustar �juanpi��������������������������juanpi�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Copyright (C) 2004-2011 David Legland ## Copyright (C) 2004-2011 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas) ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal ## All rights reserved. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are met: ## ## 1 Redistributions of source code must retain the above copyright notice, ## this list of conditions and the following disclaimer. ## 2 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. ## ## 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 THE AUTHOR OR CONTRIBUTORS 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. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{points} @var{edges}]= } delaunayGraph (@var{points}) ## Graph associated to Delaunay triangulation of input points ## ## Compute the Delaunay triangulation of the set of input points, and ## convert to a set of edges. The output NODES is the same as the input ## POINTS. ## ## WARNING: 3d pltottig works correctly in Octave >= 3.6 ## ## Example ## @example ## ## # Draw a planar graph correpspionding to Delaunay triangulation ## points = rand(30, 2) * 100; ## [nodes edges] = delaunayGraph(points); ## figure; ## drawGraph(nodes, edges); ## ## # Draw a 3Dgraph corresponding to Delaunay tetrahedrisation ## points = rand(20, 3) * 100; ## [nodes edges] = delaunayGraph(points); ## figure; ## drawGraph(nodes, edges); ## view(3); ## ## @end example ## ## @seealso{delaunay, delaunayn} ## @end deftypefn function [points edges] = delaunayGraph(points, varargin) # compute triangulation tri = delaunayn(points, varargin{:}); # number of simplices (triangles), and of vertices by simplex (3 in 2D) nt = size(tri, 1); nv = size(tri, 2); # allocate memory edges = zeros(nt * nv, 2); # compute edges of each simplex for i = 1:nv-1 edges((1:nt) + (i-1)*nt, :) = sort([tri(:, i) tri(:, i+1)], 2); end edges((1:nt) + (nv-1)*nt, :) = sort([tri(:, end) tri(:, 1)], 2); # remove multiple edges edges = unique(edges, 'rows'); endfunction %!demo %! # Draw a planar graph correpspionding to Delaunay triangulation %! points = rand(30, 2) * 100; %! [nodes edges] = delaunayGraph(points); %! figure; %! drawGraph(nodes, edges); %! axis tight %!demo %! # WARNING 3d pltottig works correctly in Octave >= 3.6 %! # Draw a 3Dgraph corresponding to Delaunay tetrahedrisation %! points = rand(20, 3) * 100; %! [nodes edges] = delaunayGraph(points); %! figure; %! drawGraph(nodes, edges); %! view(3); %! axis tight �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������