Graficas en C++ Completo
Graficas en C++ Completo
Graficas en C++ Completo
Definicion de funciones
*/
void niciarGraficos();
void xyz();
void ProyectaPunto(float ,float ,float);
void Objeto();
void instrucciones();
/*****************************************************************/
/*
ProyectaPunto
Funcion: Localiza un punto en la pantalla 3D
*/
void ProyectaPunto(float x, float y, float z)
{
pro_X = y*cos(teta) + x*sin(teta);
pro_Y = z*cos(fi) + x*cos(teta)*sin(fi) - y*sin(fi)*sin(teta);
}
/*
niciarGraficos
Funcion: nicializa el modo grafico
Juan Carlos Gutirrez Bar!uero____________________________________________ ""*
Bismarck Salvador Traa Lpez__________________________________________UNI
*/
void niciarGraficos()
{
int Tarjeta=VGA,Modo=VGAH;
initgraph(&Tarjeta,&Modo,"");
if(graphresult()!=grOk){
printf("\nSi perdiste el archivo EGAVGA.BG no podes correr el programa :
( asi que buscalo el C:\\tc\\bgi");
getch();
exit(0);
}
}
/*
Main
Funcion: Main.
*/
void main()
{
niciarGraficos();
A=getmaxx()/2,B=getmaxy()/2;
xyz();
Objeto();
closegraph();
}
/*
xyz
Funcion: Dibuja Lineas de Guia en las coordenadas X,Y,Z
*/
void xyz()
{
float X0,Y0,X,Y,z,tam=3;
int x,y;
setcolor(8);
ProyectaPunto(0,0,0);X0 = pro_X,Y0 = pro_Y;
ProyectaPunto(tam,0,0);X = pro_X,Y = pro_Y;
line(A + X0*TAM,B - Y0*TAM,A + X*TAM,B - Y*TAM);
x=A + X*TAM,y=B - Y*TAM;
setcolor(8);
outtextxy(x,y,"x");
setcolor(8);
ProyectaPunto(0,tam,0);X = pro_X,Y = pro_Y;
line(A + X0*TAM,B - Y0*TAM,A + X*TAM,B - Y*TAM);
Juan Carlos Gutirrez Bar!uero____________________________________________ ""+
Bismarck Salvador Traa Lpez__________________________________________UNI
x= A + X*TAM,y=B - Y*TAM;
setcolor(8);
outtextxy(x,y,"y");
setcolor(8);
ProyectaPunto(0,0,tam);X = pro_X,Y = pro_Y;
line(A + X0*TAM,B - Y0*TAM,A + X*TAM,B - Y*TAM);
setcolor(8);
x=A + X*TAM,y=B - Y*TAM;
outtextxy(x,y,"z");
ProyectaPunto(0,10,0);X=pro_X,Y = pro_Y;
x=A + X*TAM,y=B - Y*TAM;
setcolor(RED);
outtextxy(x,y,"JDZx");
setcolor(8);
}
/*
Objeto
Funcion: Dibuja un objeto 3D
*/
void Objeto()
{
float angulo=-M_P/100.0;
float AA[8],BB[8],CC[12],estrellas[2],EE[8],FF[8],
xa1=3,ya1=-3,za1=-3,xa2=-3,ya2=-3,za2=-3,
xa3=-3,ya3=-3,za3=3,xa4=3,ya4=-3,za4=3,
xb1=3,yb1=3,zb1=-3,xb2=-3,yb2=3,zb2=-3,
xb3=-3,yb3=3,zb3=3,xb4=3,yb4=3,zb4=3;
float x,y;
unsigned char tecla;
int fo;
do{
ProyectaPunto(xa1,ya1,za1);AA[0]=pro_X,AA[1]=pro_Y;
ProyectaPunto(xa2,ya2,za2);AA[2] = pro_X,AA[3] = pro_Y;
ProyectaPunto(xa3,ya3,za3);AA[4] = pro_X,AA[5] = pro_Y;
ProyectaPunto(xa4,ya4,za4);AA[6] = pro_X,AA[7] = pro_Y;
/*-------------------------------------------*/
ProyectaPunto(xb1,yb1,zb1);BB[0]=pro_X,BB[1]=pro_Y;
ProyectaPunto(xb2,yb2,zb2);BB[2] = pro_X,BB[3] = pro_Y;
ProyectaPunto(xb3,yb3,zb3);BB[4] = pro_X,BB[5] = pro_Y;
ProyectaPunto(xb4,yb4,zb4);BB[6] = pro_X,BB[7] = pro_Y;
ProyectaPunto(5,8,0);CC[0]=pro_X,CC[1]=pro_Y;
ProyectaPunto(-4,-8,0);CC[4]=pro_X,CC[5]=pro_Y;
ProyectaPunto(5,-5,3);CC[6]=pro_X,CC[7]=pro_Y;
ProyectaPunto(10,5,-1);CC[8]=pro_X,CC[9]=pro_Y;
ProyectaPunto(0,0,0);CC[10]=pro_X,CC[11]=pro_Y;
setcolor(1);
Juan Carlos Gutirrez Bar!uero____________________________________________ "",
Bismarck Salvador Traa Lpez__________________________________________UNI
circle(A + CC[0]*TAM,B - CC[1]*TAM,TAM*0.52);
setcolor(2);
circle(A + CC[4]*TAM,B - CC[5]*TAM,TAM*0.25);
setcolor(3);
circle(A + CC[6]*TAM,B - CC[7]*TAM,TAM*0.8);
setcolor(4);
circle(A + CC[8]*TAM,B - CC[9]*TAM,TAM*2.5);
setcolor(YELLOW);
circle(A + CC[10]*TAM,B - CC[11]*TAM,TAM*2.2);
/*-----------------------*/
ProyectaPunto(5,0,2);estrellas[0] = pro_X,estrellas[1] = pro_Y;
putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7);
ProyectaPunto(-15-0.2,5,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y;
setcolor(8);
circle(A + estrellas[0]*TAM,B - estrellas[1]*TAM,TAM*0.2);
ProyectaPunto(-10,-3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y;
putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7);
ProyectaPunto(-10,-3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y;
putpixel(B + estrellas[1]*TAM,A - estrellas[1]*TAM,7);
ProyectaPunto(-5,3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y;
putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7);
ProyectaPunto(10,-3,-2);estrellas[0] = pro_X,estrellas[1] = pro_Y;
putpixel(A + estrellas[0]*TAM,B - estrellas[1]*TAM,7);
xyz();
line(A + AA[0]*TAM,B - AA[1]*TAM,A + AA[2]*TAM,B - AA[3]*TAM);
line(A + AA[4]*TAM,B - AA[5]*TAM,A + AA[6]*TAM,B - AA[7]*TAM);
line(A + AA[0]*TAM,B - AA[1]*TAM,A + AA[6]*TAM,B - AA[7]*TAM);
line(A + AA[2]*TAM,B - AA[3]*TAM,A + AA[4]*TAM,B - AA[5]*TAM);
line(A + AA[0]*TAM,B - AA[1]*TAM,A + BB[0]*TAM,B - BB[1]*TAM);
line(A + AA[2]*TAM,B - AA[3]*TAM,A + BB[2]*TAM,B - BB[3]*TAM);
line(A + AA[4]*TAM,B - AA[5]*TAM,A + BB[4]*TAM,B - BB[5]*TAM);
line(A + AA[6]*TAM,B - AA[7]*TAM,A + BB[6]*TAM,B - BB[7]*TAM);
line(A + BB[0]*TAM,B - BB[1]*TAM,A + BB[2]*TAM,B - BB[3]*TAM);
line(A + BB[2]*TAM,B - BB[3]*TAM,A + BB[4]*TAM,B - BB[5]*TAM);
line(A + BB[4]*TAM,B - BB[5]*TAM,A + BB[6]*TAM,B - BB[7]*TAM);
line(A + BB[6]*TAM,B - BB[7]*TAM,A + BB[0]*TAM,B - BB[1]*TAM);
tecla=ZQUERDA;
if(kbhit())
{
tecla=getch();
}
setfillstyle(1,0);
Juan Carlos Gutirrez Bar!uero____________________________________________ "#-
Bismarck Salvador Traa Lpez__________________________________________UNI
switch(tecla)
{
case DERECHA:teta-=angulo;break;
case ZQUERDA:teta+=angulo;break;
case ABAJO:fi+=angulo;break;
case ARRBA:fi-=angulo;break;
case 122:if(TAM>0)TAM-=0.2;break;
case 120:if(TAM<30)TAM+=0.2;break;
}/*endcase*/
if(!kbhit()){delay(50);}
bar(0,0,getmaxx(),getmaxy());
}while(tecla!=ESC);
}
/*Ahora un juego de la serpientes este es un programa que encontre en nternet, no se
quien es el autor, le hice algunos cambios */
#include<stdlib.h>
# include <dos.h>
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#define clear; clrscr();
#define colorfondo 0
#define colorcabeza 4
#define c 1
#define bordear 40
#define bordeab 460 /*acotamos la parte valida de pantalla*/
#define bordeiz 20
#define bordede 620
void nicio(void);
void Salir(void);
void Juego(void);
void Avanza(void);
void Crece(void);
void Libera(void);
void Pinta_serpiente(void);
void Pinta_rapido(void);
int Choque(void);
void Pinta_pantalla(void);
int Es_punto(int x,int y);
void Lee_record(void);
void Escribe_record(void);
Juan Carlos Gutirrez Bar!uero____________________________________________ "#"
Bismarck Salvador Traa Lpez__________________________________________UNI
struct bola{
int x;
int y; /*La serp no es mas que una lista doble de puntos con su x y su y*/
struct bola *sig,*ant;
};
int m,v,vel,tarj,modo,puntos,max,punt[9]={90,80,70,60,50,40,30,20,10};
int longitud=0,radio=5,xa,ya,superado=0; /*No hay mas remedio que usar todas estas
globales*/
struct bola *cabeza,*indice,*ultimo; /*Para la lista*/
void main(void)
{
detectgraph(&tarj,&modo);/*comprueba el hw y detecta la tarjeta a usar*/
nicio();
Juego();
}
void nicio(void)
{
int i;
clear;
textcolor(14);
for (i=1; i<81; i++)
{
gotoxy(i,9);
cprintf ("");
}
textcolor(1);
gotoxy(34,1); cprintf (" ");
gotoxy(34,2); cprintf (" ");
gotoxy(34,3); cprintf (" ");
gotoxy(34,4); cprintf (" ");
gotoxy(34,5); cprintf (" ");
gotoxy(33,6); cprintf ("");
gotoxy(33,7); cprintf ("");
gotoxy(34,8); cprintf ("");
gotoxy(38,9); cprintf ("");gotoxy(42,9); cprintf("");
textcolor(4);
gotoxy(40,1); cprintf("");gotoxy(40,2); cprintf("");
gotoxy(40,3); cprintf("");gotoxy(40,4); cprintf("");
gotoxy(36,4); cprintf("");gotoxy(44,4); cprintf("");
gotoxy(36,5); cprintf("");gotoxy(44,5); cprintf("");
gotoxy(39,7); cprintf("O");gotoxy(41,7); cprintf("O");
Juan Carlos Gutirrez Bar!uero____________________________________________ "##
Bismarck Salvador Traa Lpez__________________________________________UNI
textcolor(9);
gotoxy(31,10); cprintf (" ");
gotoxy(31,11); cprintf (" ");
gotoxy(31,12); cprintf (" ");
gotoxy(31,13); cprintf (" ");
gotoxy(31,14); cprintf (" ");
textcolor(15);
gotoxy(29,16); cprintf ("Diseado por Abdul Ruiz");
gotoxy(31,17); cprintf ("CopyRight (c) 2002");
getch();
gotoxy(29,19); cprintf("Espera, por favor...");
delay(5500);
clear;
cprintf("TECLAS:\n\n\r");
cprintf(" -(Ar) 5(Ar)\n\r");
cprintf("MOVMENTOS o en el t.num.\n\r");
cprintf(" <(zq) (Ab) >(Der) 1(zq) 2(Ab) 3(Der)\n\r");
cprintf("Pausa: P\n\r");
cprintf("Salir: S\n\n\r");
cprintf("Si utilizas el teclado numerico, asegurate de que este activado\n\n\n\r");
cprintf("Pulsa una tecla para empezar");
getch();
sleep(5);
clear;
cprintf ("Dime el nivel de dificultad 1(Minima)...9(Maxima): ");
do{ scanf("%d",&m); }while(m<1 || m>9);
switch(m)
{
case 1:v=9;break;case 2:v=8;break;case 3:v=7;break;case 4:v=6;break;case
5:v=5;break;
case 6:v=4;break;case 7:v=3;break;case 8:v=2;break;case 9:v=1;break;
}
}
void Juego(void)
{
int obj=0;/*Para saber si hay algo de comida en la pantalla*/
int mov=radio*2;
char t,a;/*La tecla pulsada y la anterior*/
char pito=7;
int x2,y2;
initgraph(&tarj,&modo,"c:\\tc20\\bin");/*iniciamos modo grafico*/
setbkcolor(colorfondo);/*configuramos los colores del juego*/
setcolor(colorfondo);
setfillstyle(1,c);
Juan Carlos Gutirrez Bar!uero____________________________________________ "#$
Bismarck Salvador Traa Lpez__________________________________________UNI
Lee_record();
t=77;/*ponemos una tecla (para que empiece yendo hacia la derecha)*/
superado=0;
vel=v*300;
Crece(); /*creamos la cabeza*/
cabeza->x=bordeiz+radio; /*la colocamos*/
cabeza->y=bordeab-radio;
Crece(); /*ponemos otras dos bolitas de cuerpo*/
Crece();
Pinta_pantalla();
gotoxy(35,15);
printf("ADELANTE");
delay(10000);
cleardevice();
do
{
/*si no hay objeto, cogemos una pos aleatoria*/
if(obj==0)
{
do{
do{
x2=(((rand()%((bordede/(radio*2))-1)+1))*radio*2)-radio;
}while(x2>bordede-radio || x2<bordeiz+radio);
do{
y2=(((rand()%((bordeab/(radio*2))-1)+1))*radio*2)-radio;
}while(y2>bordeab-radio || y2<bordear+radio);
}while(Es_punto(x2,y2));
obj=1;
}
/*si se pulsa una tecla*/
if(kbhit())
{
a=t; /*se guarda la anterior*/
t=getch(); /* y se coge*/
}
if(Choque())
{
printf("%c",pito); /*si se choca, pierde*/
Salir();
}
Juan Carlos Gutirrez Bar!uero____________________________________________ "#%
Bismarck Salvador Traa Lpez__________________________________________UNI
Pinta_pantalla();
if(obj==1) /*si hay objeto, lo pintamos de otro color*/
{
setfillstyle(1,12);
fillellipse(x2,y2,radio-2,radio-2);
setfillstyle(1,c);
}
switch(t) /*evalua la tecla*/
{
case 72:
case '5':
Avanza();
cabeza->y=cabeza->y-mov;
break; /*arriba */
case 75:
case '1':
Avanza();
cabeza->x=cabeza->x-mov;
break; /*izquierda */
case 77:
case '3':
Avanza();
cabeza->x=cabeza->x+mov;
break; /*derecha */
case 80:
case '2':
Avanza();
cabeza->y=cabeza->y+mov;
break; /*abajo*/
case 's':
case 'S':
/*si quiere salir, liberamos mem, cerramos el modo grafico y exit*/
Libera();
closegraph();
Escribe_record();
exit(2);
break;
case 'p':/*pausa*/
Juan Carlos Gutirrez Bar!uero____________________________________________ "#&
Bismarck Salvador Traa Lpez__________________________________________UNI
cleardevice();
Pinta_serpiente();
gotoxy(37,15);
printf("Pausa");
t=getch();
cleardevice();
Pinta_serpiente();
break;
/*si la tecla pulsada no hace nada, volvemos a poner la enterior*/
default: t=a;
}
/*si se pasa por encima del objeto, se borra y se crece*/
if(cabeza->x==x2 && cabeza->y==y2)
{
puntos+=punt[v-1];
obj=0;
printf("%c",pito);
switch(m)
{
case 1: Crece(); break;
case 2:
case 3: Crece();Crece();break;
case 4:
case 5: Crece();Crece();Crece();break;
case 6:
case 7:
case 8: Crece();Crece();Crece();Crece();Crece();break;
case 9:
Crece();Crece();Crece();Crece();Crece();Crece();break;
}
}
/*cuantas mas bolas tenga que dibujar el ordenador, mas se*/
/*ralentiza el juego, esto lo contrarestamos disminuyendo el delay*/
/*cada 30 bolitas(lo he calculado a ojo)
if((longitud)/(i*30)<0)
{
vel-=15;
i++;
}*/
delay(vel);
if(puntos>max)
{
Juan Carlos Gutirrez Bar!uero____________________________________________ "#'
Bismarck Salvador Traa Lpez__________________________________________UNI
max=puntos;
superado=1;
}
}while(1);
}
void Salir(void)
{
char opc;
/*no hace falta comentar nada*/
if(superado!=0)
{
Escribe_record();
gotoxy(11,10);
printf(" Puntuacion maxima conseguida, eres el mejor, felicidades");
}
gotoxy(11,15);
printf("Estas muerto, lo siento (R)Reintentar,()Reiniciar,(S)Salir");
do{
opc=toupper(getch()); }while(opc!='R' && opc!='' && opc!='S');
puntos=0;
switch (opc)
{
case 'R':
Libera();
Juego();
break;
case '':
closegraph();
Libera();
nicio();
Juego();
break;
case 'S':
closegraph();
Libera();
exit(1);
break;
}
}
void Avanza(void)
{
indice=ultimo;
Juan Carlos Gutirrez Bar!uero____________________________________________ "#*
Bismarck Salvador Traa Lpez__________________________________________UNI
xa=ultimo->x;
ya=ultimo->y;
/*nos quedamos con la posicion de la cola*/
/*corremos cada bola a la pos de la bola anterior*/
while(indice!=cabeza)
{
indice->x=indice->ant->x;
indice->y=indice->ant->y;
indice=indice->ant;
}
}
void Pinta_serpiente(void)
{
int i=0;
indice=cabeza;
setfillstyle(1,colorcabeza);
fillellipse(indice->x,indice->y,radio,radio);
setfillstyle(1,c);
i++;
indice=indice->sig;
/*sin comentarios*/
while(i<longitud)
{
fillellipse(indice->x,indice->y,radio,radio);
i++;
indice=indice->sig;
}
}
/*Como hemos comprobado en anteriores versiones, al pintar la serpiente entera*/
/*, si esta media mucho, se ralentizaba el juego mogollon, y sabemos que, al pintar*/
/*una bola y moverla, se queda su estela pintada, no?, coo pues pintemos solo*/
/*la primera, segunda y ultima bolita, y asi, mida lo que mida la serpiente,*/
/*solo pintaremos 3 bolas, y no se ralentiza casi nada.*/
void Pinta_rapido(void)
{
setfillstyle(1,colorcabeza);
fillellipse(cabeza->x,cabeza->y,radio,radio);
setfillstyle(1,c);
fillellipse(cabeza->sig->x,cabeza->sig->y,radio,radio);
fillellipse(ultimo->x,ultimo->y,radio,radio);
Juan Carlos Gutirrez Bar!uero____________________________________________ "#+
Bismarck Salvador Traa Lpez__________________________________________UNI
}
int Choque(void)
{
indice=cabeza->sig;
/*si la cabeza esta en la pos de alguna bola o sale de los limites,
devolvemos un 1*/
while(indice!=NULL)
{
if(cabeza->x==indice->x && cabeza->y==indice->y) return 1;
if((cabeza->y<bordear+radio)||(cabeza->x<bordeiz+radio)||(cabeza-
>x>bordede-radio)||(cabeza->y>bordeab-radio)) return 1;
indice=indice->sig;
}
return 0;
}
void Crece(void)
{
struct bola *este;
este=malloc(sizeof(struct bola));
/*pues eso, se aade una struct bola al final de la lista*/
if(cabeza==NULL)
{
ultimo=cabeza=este;
cabeza->ant=NULL;
ultimo->sig=NULL;
cabeza->x=bordeiz+radio;
cabeza->y=bordeab-radio;
}
else
{
ultimo->sig=este;
este->ant=ultimo;
ultimo=este;
ultimo->sig=NULL;
este->x=-100;
este->y=-100;
}
indice=ultimo;
longitud++;
}
Juan Carlos Gutirrez Bar!uero____________________________________________ "#,
Bismarck Salvador Traa Lpez__________________________________________UNI
void Libera(void)
{
struct bola *aux;
indice=cabeza;
/*no hace falta comentario*/
cabeza=ultimo=NULL;
while(indice!=ultimo)
{
aux=indice;
indice=indice->sig;
free(aux);
}
aux=indice;
free(aux);
longitud=0;
}
void Pinta_pantalla(void)
{
gotoxy(1,1);
printf(" Serpiente v1 Desarrollado por Abdul Ruiz Chaos\n\r");
gotoxy(10,2);
printf("Nivel : %1d Punt.Max. : %4d Puntuacion :%4d Longitud :
%4d",m,max,puntos,longitud);
Pinta_rapido(); /* dibujamos la serp */
/*"borramos" la ultima bola*/
/*este metodo es mas util, porque usando un cleardevice(), la
pantalla vibraba mucho*/
setfillstyle(1,colorfondo);
fillellipse(xa,ya,radio,radio);
setfillstyle(1,c);
/* dibujamos los bordes de la pantalla */
setcolor(15);
rectangle(bordeiz-1,bordear-1,bordede+1,bordeab+1);
setcolor(0);
}
int Es_punto(int x,int y)
{
indice=cabeza->sig;
Juan Carlos Gutirrez Bar!uero____________________________________________ "$-
Bismarck Salvador Traa Lpez__________________________________________UNI
while(indice!=NULL)
{
if(x==indice->x && y==indice->y) return 1;
indice=indice->sig;
}
return 0;
}
void Lee_record(void)
{
FLE *arch;
if((arch=fopen("chaos.ars","rb"))!=NULL)
{
fread(&max,1,sizeof(int),arch);
if(puntos>max)
{
max=puntos;
}
fclose(arch);
}
else
{
max=puntos;
}
}
void Escribe_record(void)
{
FLE *arch;
arch=fopen("chaos.ars","wb");
fwrite(&max,1,sizeof(int),arch);
fclose(arch);
}
Juan Carlos Gutirrez Bar!uero____________________________________________ "$"
Bismarck Salvador Traa Lpez__________________________________________UNI
1 Introduccin a la Geometra Computacional
1.1. Historia de la Geometra Computacional
La Geometra fue estudiada desde la antigua Grecia y Egipto. Constituan una
herramienta muy importante para resolver problemas prcticos. El primer
algoritmo que pueda considerarse completo es la construccin Eucldea, porque
fue el primero que satisfizo todos los requerimientos: es correcto, no ambiguo
y tiene un final. Este algoritmo adems da una coleccin de instrucciones y
reglas, posee un conjunto de primitivas asociadas.
Ya en 1902 se describi un conjunto de pasos para contar como realizar sobre
papel una serie de primitivas Eucldeas. Se hablaba por entonces ya del
trmino complejidad, no computacional pero s de dificultad para medir la
complicacin de su realizacin. Se puede decir que fue una aproximacin a lo
que entendemos hoy por .complejidad temporal.. No se hablaba del problema
en funcin del conjunto de entrada, pero s intentaban reducirse el nmero de
pasos a realizar para resolver un problema. Poco a poco se fueron dando
cuenta de que todo problema posee un esfuerzo mnimo de realizacin, lo que
nosotros llamamos .complejidad del algoritmo..
Ya en 1672 se demostr que cualquier construccin que pudiera realizarse slo
con regla y comps podra hacerse usando slo comps. El concepto de lnea
se ampli pasando a ser el lugar geomtrico compuesto por la unin de los
puntos de corte de dos arcos realizados con un comps.
La Geometra ha tenido momentos de especial realce, por ejemplo el
crecimiento del anlisis real, la Geometra mtrica y la teora de la convexidad,
han supuesto las herramientas matem ticas para el diseo de algoritmos
rpidos. Por un lado la distancia es un tema esencial en conceptos geomtricos
y la teora de la convexidad es analizada para obtener propiedades globales.
La Geometra Algortmica est basada en caracterizaciones de objetos
geomtricos en trminos de propiedades de subconjuntos finitos. Un
tratamiento algortmico implica eliminar el trmino infinito. Hoy da la
Geometra Computacional se utiliza como herramienta bsica, no slo en
disciplinas inmediatamente relacionadas con la Geometra. A partir de finales
de los aos 60 y 70, el incremento del uso de la computadoras en
investigacin y desarrollo, propicia usar estas mquinas para resolver
problemas clsicos que siempre fueron resueltos a base de reglas y comps.
Pero la memoria de las mquinas y el tiempo de ejecucin de stas, la mayora
de las veces compartido, exigi de pronto el conseguir mtodos que no slo
funcionaran, sino que intentaran optimizar al mximo dos recuerdos muy
importantes, sobre todo por aquel entonces: la memoria y el tiempo de CPU.
Hoy por hoy a pesar de utilizar mquinas ms potentes, tambin se plantea en
Juan Carlos Gutirrez Bar!uero____________________________________________ "$#
Bismarck Salvador Traa Lpez__________________________________________UNI
muchas ocasiones incrementar el nmero de datos a procesar, por lo que hoy
sigue siendo un problema a resolver.
Algunas aplicaciones donde la Geometra Computacional es necesaria es la
Informtica Grfica, Robtica, Sistemas de Informacin Geogrficos, etc. El
trmino nace en 1975 por Shamos y desde entonces los trabajos y los
estudios en esta disciplina han ido creciendo de forma espectacular.
1.2. Eficiencia de los algoritmos
Existen distintas formas de medir algoritmos o de clasificarlos. Un algoritmo
fcil de entender, codificar y depurar es preferible a otro que realice lo mismo
pero que no cumpla estas carcter sticas. Algo similar ocurre con respecto a la
eficiencia; un algoritmo es eficiente cuando usa adecuadamente los recursos
del ordenador y lo hace con la mayor rapidez posible. Los recursos son siempre
referidos al tiempo de ejecucin y al tiempo de CPU que necesita para
ejecutarse.
Para optar por escribir un tipo de algoritmo que cumpla con las
especificaciones anteriores tambi n es necesario saber cuantas veces va a
ejecutarse dicho algoritmo y con qu cantidad de datos. As, un algoritmo poco
eficiente con pocos datos es preferible utilizarlo a otro que necesite gran
cantidad de tiempo en disearse. Por el contrario es beneficioso en muchas
ocasiones realizar un buen diseo a pesar de utilizar gran cantidad de esfuerzo
y emplear estructuras de datos complejas, si se consigue finalmente un
mtodo de resolucin que realice buenos tiempos de ejecucin para entradas
grandes de datos. Por otra parte, cuando nuestro algoritmo pretende resolver
un problema clsico, como puede ser en Geometra Computacional, se da por
supuesto que tiene que ser eficiente con grantes cantidades de datos y adems
hay que suponer que dicho algoritmo va a ser ampliamente utilizado.
Por tanto, nuestro propsito es no slo entender y utilizar algoritmos que
funcionen en Geometra Computacional sino que tambin sean eficientes. Para
medir dicha eficiencia, hay que tener en cuenta ciertos parmetros:
Dependencia de los datos de entrada del programa.
Calidad del cdigo que genera el compilador en el programa objeto.
Las instrucciones y arquitectura de las computadoras.
Tiempo de ejecucin de dicho programa.
Como entrar en detalles de compiladores diferentes y de distintas arquitecturas
es muy amplio y adems es absolutamente cambiante, basta decir que cuanto
ms rpido mejor. Lo que haremos ser estudiar los algoritmos en funcin de
la entrada, bsicamente de su tamao, y adems en la complejidad o tiempo
que emplea el algoritmo para su ejecucin. Obviamente un algoritmo, o
programa puesto que se est ejecutando, va a ser ms rpido si tiene que
procesar diez datos que si tiene que realizar lo mismo con una entrada de
tamao cien.
Juan Carlos Gutirrez Bar!uero____________________________________________ "$$
Bismarck Salvador Traa Lpez__________________________________________UNI
Vamos a denominar T(n) al tiempo de ejecucin de un programa con tamao
n. Para no especi ficar el tiempo en segundos, puesto que depende
excesivamente de la mquina empleada, se usar una funcin expresada en
trminos de n. Por ejemplo, T(n) = cn2, siendo c una constante.
En muchas ocasiones es necesario referirse al tiempo de ejecucin esperado
del algoritmo en el peor de los casos para una entrada de tamao n. De esta
forma se puede acotar el problema con una cota superior que nos permita
conocer el margen en el que nos podemos mover. El caso medio tambin
puede ser interesante en casos donde se conozca que el peor caso se produce
con una probabilidad muy pequea.
Cuando decimos que el tiempo de ejecucin T(n) de un programa es O(n2)
significa que existen constantes enteras positivas c tales que T(n) fi cn2. Por
tanto es lo que llamamos cota superior que nos identifica el peor caso. En el
caso genrico decimos que T(n) es O( f (n)). Tambin existen cotas inferiores
para hablar del tiempo de ejecucin. Es una cota inferior o lo que es lo mismo:
el algoritmo se ejecutar al menos en el tiempo que la funcin g(n) indica. Se
dice que T(n) es (g(n)) cuando existe una constante c tal que T(n) fi cg(n).
Cuanto menor sea la representacin grfica de la funcin f (n), ms rpido se
ejecutar el algoritmo para un conjunto de entrada de tamao dado. Pero esto
no siempre es verdadero para todo n, es decir, en ocasiones el tiempo de
ejecucin se refiere a grandes cantidades de informacin y por tanto, n tiende
a infinito. As O(n2) es mejor que O(n3); O(n) es mejor que O(n2) pero peor
que O(nlogn). Por ejemplo un programa con tiempo O(100n) es ms lento para
n menor que 20 que otro que se ejecute en tiempo O(5n2). En algoritmos
tpicos de Geometra Computacional lo que se busca sobre todo son
ejecuciones en tiempo lineal O(n), o en O(nlog n).
A menos que un algoritmo tenga una velocidad de crecimiento baja, O(n) o
O(nlogn), un crecimiento modesto en la rapidez de la computadora no infiuir
gran cosa en el tamao del problema.
A pesar de todo lo expuesto anteriormente, si un algoritmo va a ser utilizado
pocas veces, el costo de escritura de una algoritmo eficiente puede que no
merezca la pena. Tampoco es necesario si siempre va a recibir un conjunto de
entrada pequeo. En algunas ocasiones un algoritmo puede permitirse el lujo
de ser algo ms lento si a cambio es ms didctico. Por otro lado, si la
eficiencia a nivel de tiempo en CPU implica un alto coste en cantidad de
almacenamiento o porque se encuentre en dispositivos de memoria masiva.
Por ltimo, en algoritmos numricos es tan importante la precisin de los
clculos como la eficiencia de stos.
Para calcular la eficiencia de un algoritmo hay que tener en cuenta ciertos
casos:
Juan Carlos Gutirrez Bar!uero____________________________________________ "$%
Bismarck Salvador Traa Lpez__________________________________________UNI
Si T1(n) y T2(n) son tiempos de ejecucin de dos fragmentos de
programa, el tiempo totalser de T1(n)+T2(n). Sin embargo, se
considera nicamente el ms lento de los dos y eltiempo de ejecucin
vendr dado por tanto por O(max( f (n);g(n)) , siendo O( f (n)) eltiempo
para T1(n) y O(g(n)) para T2(n). Tambin existen simplificaciones, por
ejemplo,O(c f (n)) se considera siempre O( f (n)).
Una asignacin u operacin aritmtica suele considerarse con tiempo
O(1).
En las proposiciones condicionales, la parte de la condicin suele
considerarse tiempoconstante si no necesita realizar llamadas a otras
funciones. El tiempo global de esta instruccin se toma de nuevo como
el mayor de las dos partes que la forman, parte then o parte else.
En un ciclo se suele determinar por el nmero de iteraciones
multiplicadas por el orden del conjunto de instrucciones del cuerpo del
bucle. Si tenemos dos bucles de n ciclos, uno dentro de otro, se
considera tiempo cuadrtico (suponiendo que el cuerpo del bucle tuviera
un tiempo contante).
Cuando se hacen llamadas a procedimientos no recursivos, se suman todos los
tiempos de ejecuci n segn las pautas anteriores, pero en procesos recursivos
se trabaja de forma distinta. Supongamos la siguiente funcin:
Para n > 2, tenemos que T(n) = c +T(n -1). El trmino T(n -1) se sustituye
por n -1:
T(n-1) = c+T(n-2), sustituyendo tenemos que T(n) = c+c+T(n-2). Siguiendo
este
proceso hasta el trmino i entonces T(n) = ic+T(n-i). Cuando i = n-1, T(n) =
nc+T(1) =
ncfi= O(n).
En el siguiente ejemplo tenemos a un algoritmo recursivo. Para el caso
general, n >1, el proceso divide el problema en dos mitades de
aproximadamente el mismo tamao. Cuando ste proceso de divisin termina
necesita un tiempo lineal para unir los resultados de las dos mitades. Este
mtodo es muy habitual en los problemas resueltos con el mtodo Divide y
Vencers.
Juan Carlos Gutirrez Bar!uero____________________________________________ "$&
Bismarck Salvador Traa Lpez__________________________________________UNI
1.3. Operaciones bsicas en Geometra Computacional
En este apartado entraremos en contacto con mtodos para la resolucin de
algunos de los problemas ms elementales en Geometra. Nos servir
igualmente para recordar conceptos a nivel computacional. Los algoritmos
aparecern mayormente escritos en lenguaje Pascal, a no ser que alguno de
ellos aparezca, no por razones prcticas sino didcticas.
1.3.1. Introduccin
A nivel de tratamiento de la informacin, en Geometra Computacional es clara
la preferencia por los tipos de datos enteros, lo que se denomina aritmtica
entera. La razn es obvia, el ordenador debe transformar todo dato de la recta
real en un tipo de dato de una computadora que tiene un espacio finito de
almacenamiento. Los datos enteros s garantizan su transformacin ntegra a
un tipo de dato almacenado en memoria, siempre que ste sea menor que una
valor dado. Sin embargo, los datos reales o en coma flotante pierden casi
siempre cierta precisin al ser guardados. Cuando una variable de tipo real
nace en la ejecucin de un programa y a su vez es utilizada como entrada para
crear otras nuevas, este proceso repetido puede hacer que el dato se aleje del
valor correcto. Por esta razn, y siempre que sea posible, es preferible hacer
uso de la aritmtica entera. Por ejemplo, para saber si dos segmentos
intersecan basta utilizar aritmtica entera, sin embargo si queremos saber
exactamente el lugar de interseccin, s era necesario
realizar algn clculo en coma flotante.
1.3.2. lgunos tipos de datos simples
Los datos geomtricos, a la hora de ser procesados por un ordenador, son
reemplazados por lo que denominamos tipos de datos. Muchos conceptos
tpicamente matemticos se denominan de forma anloga cuando se
representan internamente, as usamos el concepto de variable o de constante.
Los tipos de datos identifican el tipo de cada una de estas posibles variables o
constantes. Los tipos de datos que cualquier lenguaje de programacin soporta
cubren el espectro ms habitual, sin embargo, los de tipo geomtrico deben
ser definidos explcitamente por el programador.
En este curso utilizaremos varios de estos tipos de datos. Por ejemplo, el tipo
de dato TipoPunto, TipoPoligono, etc. En las clases de prcticas se definirn
muchos de ellos, ahora identificaremos los anteriores en Pascal para poder
trabajar con ellos a lo largo de este tema:
Juan Carlos Gutirrez Bar!uero____________________________________________ "$'
Bismarck Salvador Traa Lpez__________________________________________UNI
/************REPRESENTACION DE UN PUNTO*********************/
# define x 0;
# define y 0;
typedef enum{ FALSE, TRUE}bool;
# define DIM 2 /*Dimensin del punto*/
typedef int tpointi(DIM); /*Declaracin de un arreglo de puntos*/
/*********REPRESENTACION DE UN PUNTO***********************/
# define PMAX 100
Typedef tpointi tpolygoni[PMAX]
Por simplicidad computacional, se emplea un array con dos posiciones para un
punto, identifi cando la posicin 0 para guardar el valor de la x y la posicin 1
para el de la y. Cuando se dice que un polgono es un array de puntos,
realmente tenemos una matriz bidimensional con un total de dos columnas,
igualmente fcil de manejar computacionalmente.
Las tcnicas de tricoloreado dos tecnicas utilizadas para la representacin de
los guardas y otras entidades diferentes de las triangulaciones y vasadas en las
diagonales si desean informacin de estas acudan al libro geometry
computacional in C.
1.3.3. Clculo del rea
Una de las operaciones ms elementales en Geometra es el clculo del rea de
un tringulo, sea del tipo que sea. El mtodo para realizar este clculo no es
otro que la resolucin de un determinante 3x3, aunque no es objetivo de esta
asignatura el clculo matemtico correspondiente.
El algoritmo escrito en pseudocdigo aparece a continuacin. Por razones
argumentadas anteriormente, se opta por trabajar siempre con aritmtica
entera. La funcin AreaTriangulo2 evitar la divisin por dos y calcular el
doble del rea del tringulo, por lo hay que tener en cuenta que para obtener
el valor real del rea ser necesario hacer la divisin correspondiente.
Ahora vemos el cdigo:
Int Area2(tPointi a, tPointi c, tPointi c)
{
return : = ( ( a [ 0 ] *b[1])-(a [ 1 ] * b [ 0 ]) +
( b [ 0 ] * c [1])-(b [ 1 ] * c [ 0 ]) +
( c [ 0 ] * a[1])-(c [ 1 ] * b [ 0 ]) ) ;
}
El resultado de este clculo ser positivo siempre que los vrtices abc sean
recorridos en orden inverso a las agujas del reloj. En caso contrario el valor
ser igualmente vlido y medir el rea, pero tendr el signo negativo.
Juan Carlos Gutirrez Bar!uero____________________________________________ "$*
Bismarck Salvador Traa Lpez__________________________________________UNI
El clculo del rea de un polgono convexo es bien sencillo, basta con calcular
el rea de todos los tringulos que se pueden formar lanzando diagonales
desde cualquier vrtice, hasta el resto de los vrtices del polgono convexo.
Si el polgono no es convexo, el rea puede calcularse sumando las reas de
los tringulos resultantes o incluso restando los de aquellos que no tengan
superficie, como en el siguiente ejemplo:
El rea del polgono puede calcularse de dos modos:
Area (abd) + area (bcd)
Area(abc) - area(adc)
Este mismo principio puede extenderse a cualquier polgono, indistintamente
del tipo y nmero de vrtices que tuviera. Veamos el siguiente ejemplo: se ha
elegido un punto cualquiera p, interior o exterior al polgono y se han trazado
diagonales a todos sus vrtices. Los vrtices de ste han sido enumerados del
o al n-1 en orden inverso a las agujas del reloj. Este dato es muy importante,
porque va a ser siempre el mecanismo utilizado para numerar los vrtices
cuando trabajemos con polgonos. El nmero de tringulos obtenidos ser de
n-1, siempre partiendo del punto p y siguiendo con dos vrtices sucesivos del
modo siguiente:
Juan Carlos Gutirrez Bar!uero____________________________________________ "$+
Bismarck Salvador Traa Lpez__________________________________________UNI
El tringulo p01 se traza en sentido inverso a las agujas del reloj, lo que
implicar siempre que el rea de dicho tringulo es positiva. Se ha sealado
utilizando un smbolo + cuando el clculo se realiza en el sentido antihorario y
con - cuando el rea es negativa. Cuando el recorrido de los vrtices del
tringulo siempre en la forma pvivi+1, sea en sentido horario, por ejemplo el
tringulo p67, el rea correspondiente se resta. El resultado final, como
podemos observar en la figura, es que todas las reas de los tringulos no
contenidas en el interior del polgonos son sumadas y restadas una vez con
resultado igual a cero, es decir, el resultado finalmente es el deseado.
Por tanto, podemos hacer uso de la funcin AreaTriangulo2 tantas veces como
tringulos se vayan formando con el proceso anterior, sumando unas veces las
reas y otras restndose automticamente segn sea la salida de dicha
funcin. Como de cada tringulo se calcula el doble de su rea, finalmente ser
necesario dividir por dos el resultado final.
Como el punto P puede ser cualquier punto, sea interior o no al polgono,
podemos optar por tomar al punto del polgono s[0], o lo que es lo mismo
computacionalmente, a s[0]. El resultado lo podemos escribir a continuacin:
Veamos el cdigo:
int AreaPolygoni(tpointi s, int n)
{
float suma;
int i;
suma=0;
for(i=1;i<n-1;i++)
suma=suma+Area2(s[0],s[i],s[i+1]);
return suma;
}
1.3.!. Interseccin de segmentos
Una de las operaciones elementales en Geometra Computacional es la
interseccin de segmentos, clculo vlido para otros muchos problemas. Sin
Juan Carlos Gutirrez Bar!uero____________________________________________ "$,
Bismarck Salvador Traa Lpez__________________________________________UNI
embargo, y siguiendo con la dinmica de trabajar siempre que sea posible con
aritmtica de enteros, el algoritmo de interseccin de segmentos va utilizar
otra serie de subrutinas necesarias.
Si recordamos una de las propiedades de la funcin del clculo del rea del
tringulo, el resultado es positivo si la lectura ordenada de los vrtices nos da
un recorrido antihorario. Esta propiedad puede ser til para determinar si un
punto c est a la izquierda del segmento ab. Observemos la siguiente figura:
El tringulo imaginario abc se dibuja en orden inverso a la agujas del reloj, lo
que automticamente nos est indicando que el punto c est a la izquierda de
ab. Es necesario observar que no es lo mismo el segmento ab que el segmento
ba computacionalmente hablando. El rea del tringulo bac es negativa porque
el punto c est a la derecha del segmento ba. El subprograma correspondiente
nicamente necesita realizar una llamada a la funcin AreaTriangulo2
anteriormente vista. Aprovechamos un clculo en principio de distinta ndole,
para determinar la posicin de un punto con respecto a un segmento.
Veamos el codigo:
bool Left(tpointi a, tpointi b, tpointi c)
{
Return Area2(a,b,c)fi0; /*Si areamayor que cero retorna TRUE */
}
No es difcil entender que este mismo principio sirve para determinar si el
punto c est justamente a la derecha (la funcin anterior nos devuelve un
valor f alse). o si el rea del tringulo abc es igual a cero, lo que indica que los
tres puntos son colineales:
Juan Carlos Gutirrez Bar!uero____________________________________________ "%-
Bismarck Salvador Traa Lpez__________________________________________UNI
Veamos el codigo en C:
bool Collineal(tpointi a, tpoint b, tpoint c)
{
return Area2(a,b,c)==0;
}
Debemos insistir en que el cdigo anterior da por supuesto que todos los
clculos se realizan nicamente utilizando aritmtica de enteros. No quiere
decir sto que no pueda migrarse dicho cdigo a operaciones en coma fiotante,
pero en ese caso jams debera realizarse una operacin como esta i f a = 0
::::, puesto que no siempre el valor que nosotros consideramos como cero (o
cualquier otro valor concreto) lo entienda as un tipo de dato en coma fiotante.
Para solventar este problema es ms conveniente establecer un margen de
error permitido, y operar as: i f abs(a) < 0;001 :::, o lo que es lo mismo, si el
valor absoluto de la variable real a es menor que un valor prximo a cero.
Para saber si dos segmentos ab y cd intersectan, deberamos saber si:
1. no son colineales
2. si d est a la izquierda de ab y c est a la derecha (o al revs) y adems
3. si a est a la derecha de cd y b lo est a la izquierda (o al revs)
Nos podemos dar cuenta en la figura de que si no se cumple algunas de estas
premisas no tenemos garanta de que ambos segmentos intersecten.
El cdigo debe tener en cuenta todos los casos citados anteriormente. La
operacin vlida para implementar el .al revs., es la operacin XOR(a;b) cuya
tabla de verdad da el valor verdadero cuando a y b son distintos.
Juan Carlos Gutirrez Bar!uero____________________________________________ "%"
Bismarck Salvador Traa Lpez__________________________________________UNI
bool Intersect(tpointi a, tpoint b, tpointi c, tpointi d)
{
If (IntersectProp(a,b,c,d))
Return TRUE; /*Hay interseccin propia*/
else
If(Between (a,b,c) || Between (a,b,d) || Between (c,d,a) || Between (c,d,b)
Return TRUE; /*Hay interseccion impropia*/
else
return FALSE; /*No hay interseccion*/
}
El inconveniente del mtodo es la redundancia. Ahora realizaremos una nueva
versin del algoritmo utilizando la primitiva ntre, que ser capaz de saber si
un punto c est o no en el segmento ab. Para ellos veremos si la coordenada x
de c cae en el intervalo determinado por la coordenada x de a y b. Lo mismo
debe hacerse para la ordenada.
Veamos el codigo en C:
boll Between (tpoint a, tpointi b, tpoint c)
{
If(!Collineal(a,b,c))
Return FALSE;
If(a[x]!=b[x])
return ( (a[x]<=c[x]) && (c[x]<=b[x]) || (a[x]>=c[x] ) &&
(c[x]>=b[x]) );
else
return ( (a[y]<=c[y]) && (c[y]<=b[y]) || (a[y]>=c[y] ) &&
(c[y]>=b[y]) );
}
Esta versin del algoritmo adems cuenta con al ventaja de poder trabajar con
las intersecciones de forma propia o impropia. Una interseccin impropia
ocurre cuando un extremo de uno de los segmentos est justo en en alguna
posicin del otro. La siguiente funcin en Pascal detecta primero si existe la
posibilidad de colinealidad con la funcin ntre! Posteriormente hace el mismo
proceso que "ntersecta#egmento.
Veamos el cdigo:
bool IntersecImprop(tpoint a, tpoint b, tpointi c, tpointi d)
{
If( Between (a,b,c) || Between (a,b,d) || Between (c,d,a) || Between (c,d,b) )
return TRUE;
else
return(Left(a,b,c) || Left(a,b,d) && Left(c,d,a) || Left(c,d,b) )
}
Juan Carlos Gutirrez Bar!uero____________________________________________ "%#
Bismarck Salvador Traa Lpez__________________________________________UNI
Ahora veremos la function propia en C:
bool IntersecProp (tpoint a tpoint b, tpointi c, tpointi d)
{
If( Collineal(a,b,c) || Collineal (a,b,d) || Collineal (c,d,a) || Collineal (c,d,b) )
return FALSE;
return (Xor(Left (a,b,c), Left (a,b,d)) && Xor (Left(c,d,a),Left (c,d,b)));
}
bool Xor (bool x, bool y)
{
return !x^!y;
}
1.3.". Clculo de diagonales
El clculo de una diagonal tiene como objetivo la triangulacin de polgonos.
Una diagonal es aquel segmento que une dos vrtices del polgono de forma
que no intersecte con ningn otro eje de dicho polgono y adems sea interno
al polgono. Para saber si existe o no interseccin puede utilizarse el proceso
anterior, pero para saber si es o no interno necesitamos realizar un
procesamiento adicional. Este clculo puede realizarse en
tiempo constante porque si una diagonal es interior a un polgono P en su
vecindario (vrtices prximos), tambin lo es para todo el polgono, no siendo
necesario un procesamiento completo del polgono P.
Diremos que un segmento s es interno a P si y slo si es interno al cono cuyo
vrtice es vi y cuyos lados pasan a travs de vi-1 y vi+1. Existen dos casos, el
caso convexo en el que el resto del polgono est en la parte de menor ngulo
y el caso cncavo en cuyo caso el ngulo es mayor que . La siguiente funcin
determina si el vector que une los vrtices i y j del polgono P es interior o no
al polgono.
Veamos el codigo:
Esta funcin verifica si un vertice es convexo
boll InCone(int i, int n, tpoligoni P)
{
int i1,inl;
i1=(i+1)%n;
inl=(i+n-1)%n;
if(LeftOn(P[inl],P[i],P[i1])) /**/
return (Left(P[i],P[j],P[inl]) && Left (P[j],P[i],P[i1]));
else
return (!(LeftOn[P[i],P[i1]P[i1]) && LeftOn(P[j],P[i+,P[inl]));
}
Juan Carlos Gutirrez Bar!uero____________________________________________ "%$
Bismarck Salvador Traa Lpez__________________________________________UNI
bool LeftOn (tpointi a, tpoint b,tpoint c)
{
return Area2(a,b,c)fi0;
}
Vemos en la figura siguiente los dos casos comentados anteriormente. El caso
convexo ocurre cuando el vrtice vi+1 est a la izquierda del eje trazado por
vi-1vi. En este caso, lo vemos en la figura de la izquierda, para que se trate de
un eje interno debe ocurrir que vi-1 est a la izquierda de viv j y que vi+1 lo
est a la izquierda. El caso cncavo aparece a la derecha.
Por tanto, una diagonal es aquel segmento interior que est dentro del
polgono. Pero el segmento i j es una diagonal si no intersecta con ninguna
otro de las aristas del polgono. Este clculo necesita forzosamente un tiempo
de ejecucin lineal. La funcin $iagonalfi" se encargar de realizar este
chequeo, y que ser invocado por la funcin $iagonal cuyo cdigo resulta
bastante evidente: el segmento i j es una diagonal del polgono P de tamao n
si es interior y adems no intersecta con ninguna arista.
Veamos el cdigo:
Es/*ta function verifica la possible diagonal entre dos vertices.*/
bool Diagonal (int i, int j,int n,tpolygoni P)
{
return(InCode(i,j,n,P) && Diagonaie(i,j,n,P)());
}
/*Esta function verifica si una diagonal se intersecta con una arista del
poligono */
bool Diagonalie (int i, int j, int n, tpoligono p)
{
Int k,k1;
for(k=0; k<n; k++)
{
K1=(k+1)%n;
if( !( ( k==i) || ( K1==i ) || ( k==j) || ( k1==j ) ) )
Juan Carlos Gutirrez Bar!uero____________________________________________ "%%
Bismarck Salvador Traa Lpez__________________________________________UNI
if ( Intersect (p[i], p[j], p[k], p[k1]))
return FALSE;
}
return TRUE;
}
/*Esta function remueve el triangulo formado por la diagonal y la arista
asociada ala diagonal, para lo cual reasigna las etiquetas del polgono.*/
void ClipEar1 (int i, int n, tpoligoni p, int labels [ ])
{
Int k;
for(k=I; k<n-1 ; k++)
{
point assign (p[k+1]);
labels[k] = labels [k+1];
}
}
/*Esta funccion obtiene los vrtices de la possible diagonal */
void TriRecurse(int n, tpoligoni P, int labels [])
{
int i,i1,i2;
if(n>3)
for(i=0; i<n;i++)
{
i1=(i+1)%n;
i2=(i+2)%n;
if (Diagonal(i,i2,n,p))
{
printf("%d %d ln",labels[i2]);
ClipEar1(i1,n,p,labels);
TriRecurse(n-1,P,labels);
break;
} /*Cierre del if*/
} /*Cierre del for*/
} /**Cierre de la funcion/
1.3.#. $n e%emplo completo& triangulacin de un polgono
La triangulacin de polgonos es un clculo muy importante en muchas
aplicaciones de Geometr a Computacional. Permite, aparte de otras muchas
aplicaciones, dividir un polgono con posible cierta complejidad, en un conjunto
de tringulos fciles de procesar.
Veremos que el siguiente mtodo puede ser perfectamente vlido para lograr
la triangulacin de cualquier polgono P de tamao n. Sin embargo, y a pesar
Juan Carlos Gutirrez Bar!uero____________________________________________ "%&
Bismarck Salvador Traa Lpez__________________________________________UNI
de su simpleza, su utilizacin no es aconsejable y por ello no se ha
implementado en un leguaje de programacin. Vemos que es un mtodo
recursivo porque se llama a s mismo. La llamada recursiva se realiza cuando
se localiza una diagonal, y como en ese momento el nmero de vrtices a
procesar es uno menos, puesto que el vrtice i1 queda aislado al encontrarse
la diagonal ii2. La funcin limina%ertice se encargara de este operacin,
dejando cada vez que se llama un polgono ms pequeo.
Esta funcin triangula el poligono P de n vertices.
void Trinagulate1 (int n, tpoligoni)
{
tpoligoni.pt;
int labels[PMax];
clrscr();
for(i=0;i<n;i++)
{
PointAssign(pt[i]<P[i]);
labels[i];
}
printf("Diagonales de la triangulacion;\n");
TriRecurse(n,pt,Labels);
}
/*Esta funcin asigna al punto "a" el valor del punto "b".*/
void PointAssign(tpoint a, tpoint b)
{
int i;
for(i=0;i<DIM;i++)
a[i]=b[i];
}
La razn por la que este algoritmo no es desde luego nada interesente es por
su tiempo de ejecucin. El algoritmo trabaja en O(n3) porque realiza un total
n-3 llamadas recursivas y cada una de ellas, en el peor de los casos, necesita
un tiempo cuadrtico (la funcin diagonal es lineal, as como la ejecucin
completa del bucle).
Como veremos a lo largo de este curso, para valores de n elevados, este
algoritmo resulta
Evidentemente lento, y en Geometra Computacional todos los problemas
cuyas soluciones inmediatas sean susceptibles de mejora, son estudiados.
Como veremos en sucesivos captulos, cualquier polgono puede ser
triangulado en tiempo O(nlog n).
Los algoritmos geomtricos, al igual que los desarrollados para otras
disciplinas, debern combinar adecuadamente junto con su conjunto de
Juan Carlos Gutirrez Bar!uero____________________________________________ "%'
Bismarck Salvador Traa Lpez__________________________________________UNI
sentencias, a las estructuras de datos correctas para conseguir el objetivo
final, obtener programas eficientes.
1.!.1. Introduccin a las estructuras de datos
El estudio de las estructuras de datos y los mtodos para la organizacin de
dichos datos es uno de los aspectos clsicos ms importantes para construir
algoritmos eficientes. Los programas trabajan con informacin que permanece
en memoria principal o en algn dispositivo de memoria secundaria. La
organizacin que se le da a dichos datos es lo que denominamos estructuras
de datos!
La mayora de las estructuras de datos pueden verse como contenedores que
mantienen informacin de un determinado tipo con un cierto orden. El acceso y
manejo de los datos en un contenedor se realiza a travs de un locali&ador.
Dependiendo de la estructura del contenedor, el localizador proporcionar un
modo de acceso a los datos, por ejemplo, un ndice de un array o un puntero.
Una estructura de datos adems de proporcionar un modo de acceso, tambin
deber llevar asociado un conjunto de operadores, como insertar un nuevo
dato, actualizar uno ya existente o eliminar algn otro. Las caractersticas de
una estructura de datos va en relacin al orden de ejecucin de sus
operaciones y a los requerimientos de espacio. En cualquier caso, la estructura
de datos ms idnea depender siempre del problema que se pretenda
resolver.
Un tipo de dato es una coleccin de objetos a la que se le da una
representacin matemtica. Un tipo de dato abstracto o T$A es un tipo de
dato, ms un conjunto de operaciones que lo manejan. Las estructuras de
datos pueden considerarse como implementaciones concretas de tipos de
datos abstractos. Los TDAs (notacin anglosajona) han evolucionado hasta
convertirse en clases de objetos! Lo que inicialmente se concibi como un
concepto matemtico que se adapt a la sintaxis de los lenguajes de
programacin tradicionales, se ha ido convirtiendo en una nueva filosofa de
programacin con los nuevos lenguajes orientados a objetos.
Existen multitudes de estructuras de datos ampliamente documentadas en la
bibliografa. En este apartado repasaremos algunas de las estructuras de datos
usadas en el curso.
Dependiendo de la organizacin interna y del modo de acceso a los datos,
existen dos tipos fundamentales de contenedores, los contenedores
secuenciales o secuencias y los asociativos. Una secuencia es un contenedor
que almacena los elementos con un orden lineal determinado, realizando el
acceso a la informacin indicando la posicin donde se localiza el dato. Por el
contrario un contenedor asociativo, independientemente de su organizacin
interna, permite el acceso por clave.
Contenedores secuenciales
Juan Carlos Gutirrez Bar!uero____________________________________________ "%*
Bismarck Salvador Traa Lpez__________________________________________UNI
Las secuencias ms usuales son las listas enla&adas y los arrays. Las primeras
forman una sucesin de nodos o elementos informativos unidos unos a otros
mediante punteros. El tiempo de acceso es lineal, aunque normalmente el
acceso a los puntos extremos es constante. Los arrays son contenedores
implcitos con acceso directo. Esta ventaja de acceso en tiempo constante se
ve mermada por poseer menor fiexibilidad. Por ejemplo, la operacin de
insercin de un elemento en posiciones intermedias es de orden lineal. Sobre
cualquiera de los contenedores secuenciales anteriormente citados puede
construirse estructuras de datos muy conocidas y empleadas, las pilas (LIFO) o
las colas (fiFO). Cualquiera de ellas implementada sobre una lista puede
considerarse como una estructura de datos dinmica. Esta consideracin
tambin puede realizarse sobre arrays dinmicos.
Contenedores asociati'os
Los contenedores asociativos poseen una filosofa de manejo y una estructura
interna totalmente diferente a las secuencias. La diferencia fundamental es que
el acceso a la informacin se realiza siempre utilizando una clave y no una
posicin, que puede identificar o no de forma unvoca al dato. Las operaciones
fundamentales son de insercin, actualizacin, borrado y bsqueda por dicha
clave.
La organizacin interna de los datos depende del tipo de contenedor asocitivo,
por rbol o por tabla hash. Los primeros mantienen un rbol binario de
bsqueda o Inorden, manteniendo una relacin de orden entre nodos padre e
hijos. Normalmente, todo nodo padre es mayor que su hijo izquierdo pero
menor o igual que su hijo derecho. El tiempo de acceso en este tipo de
estructuras permite eliminar en cada consulta la mitad del grueso de la
informacin, siempre que todas las ramas del rbol permanezcan a la misma
altura. Estas estructuras de datos garantizan bsquedas en O(logn).
Las estructuras de datos consideradas de carcter general son ampliamente
utilizadas en Geometra Computacional, pero existen otros aspectos como son
la naturaleza espacial de los objetos geomtricos o sus propiedades
estructurales que requieren del manejo de estructuras de datos ms
especficas para construir algoritmos eficientes.
La eleccin de un tipo de estructura de datos o de otro va a depender del tipo
de objetivo que se persiga: captura de informacin estructural, acceso a los
datos o actualizacin eficiente de stos, optimizacin del espacio requerido o
del nmero de operaciones de E/S. En otras ocasiones, las estructuras de
datos se eligen segn la asociacin de objetos geomtricos que representen.
1.!. lgunos m(todos de programacin utili)ados en C.
La Geometra Computacional, en contraste con la disciplina clsica basada en
proporcionar teoremas matemticos, enfatiza los aspectos computacionales de
Juan Carlos Gutirrez Bar!uero____________________________________________ "%+
Bismarck Salvador Traa Lpez__________________________________________UNI
los problemas y atiende a las propiedades geomtricas para encontrar
algoritmos eficientes.
Que un problema geomtrico tenga solucin dentro de la Geometra
Computacional no basta en muchas ocasiones, se desea adems que la
solucin se encuentre en un tiempo ptimo. Existen una serie de tcnicas y
paradigmas de programacin que vienen siendo muy habituales no slo en el
campo de la Geometra Computacional. Algunos de estos mtodos como el
divide y vencer's ya haban proporcionado la solucin ptima a problemas
como la ordenacin, en otras ocasiones los mtodos de resolucin estn
ntimamente relacionados con las capacidades de la propia Geometra.
A continuacin daremos un repaso a los paradigmas de programacin ms
empleados dentro de la Geometra Computacional.
1.".1. *(todo incremental
ste puede ser considerado como uno de los mtodos ms simples e intuitivos,
tambin conocido como el mtodo iterativo. La idea sobre la que trabaja este
mtodo consiste en construir la solucin de modo iterativo, considerando que
la entrada se produce de modo incremental. Para cada una de las nuevas
entradas, el problema se resuelve convenientemente.
Supongamos que se pretende procesar una nube de n puntos en el plano #,
para resolver cualquier problema Prob(#) bajo esta tcnica. En muchas
ocasiones # deber estar ordenada bajo algn criterio con coste O(nlogn). El
algoritmo trabaja siempre de forma similar. Inicialmente Prob se resuelve de
forma trivial para fs0; s1; :::; s(-1g, los primeros ( puntos de #.
Posteriormente y uno a uno, se resolver Prob(#i) para el resto de si 2 #; i =
f(; :::;n-1g tal y como indica el Algoritmo 1, obtiendo finalmente Prob(#).
Si en un problema de tamao n, el coste de insertar un nuevo dato es O(n),
entonces el tiempo global del algoritmo ser de O(n2). Pero si aadir un nuevo
elemento a la solucin parcial del problema tiene coste constante o
logartmico, el algoritmo final se procesar en O(nlogn), la misma cota
impuesta por el algoritmo de ordenacin.
lgoritmo 1 Incremental-generalizado.
Incremental(RC,p)
1. Si p est dentro de RC
2. entonces devolver RC
3. sino
4. (Pt1,Pt2) := puntosTangentes(RC,p)
5. Eliminar aristas en RC de Pt1 a Pt2
6. Conectar Pt1 con p y p con Pt2
Juan Carlos Gutirrez Bar!uero____________________________________________ "%,
Bismarck Salvador Traa Lpez__________________________________________UNI
Ahora veremos los puntos tangentes:
1.".1.1. +nea de barrido
Esta estrategia es una particularizacin del mtodo incremental,
considerndose vlida para problemas en dos dimensiones cuando el conjunto
de entrada se produce en un cierto orden. La solucin de la mayora de estos
problemas puede ser incremental, de hecho, la implementacin de este
paradigma sigue las mismas premisas que las dadas para el mtodo
incremental citado anteriormente.
El mtodo supone que una lnea horizontal (o vertical) recorre el plano de
arriba hacia abajo (o en sentido contrario). Cada vez que dicha lnea encuentra
un tem (un punto, una lnea, etc) lo procesa modificando el conjunto de
estructuras que datos que participen en la construccin de dicho algoritmo. La
validez de esta tcnica est basada en la observacin de que la parte que
queda por encima o por debajo de la lnea de barrido se ha construido
correctamente.
Por ejemplo en el problema de interseccin de segmentos, cuando la lnea
encuentra un nuevo segmento, se realizar una insercin en alguna estructura
de datos capaz de mantenerlos ordenados de izquierda a derecha (en el caso
de que la lnea de barrido sea horizontal). Normalmente se escogen
estructuras de datos con tiempos de actualizacin y de acceso logartmico. Si
el procesamiento de dichos objetos geomtricos es constante, como es el caso
de la interseccin de dos segmentos, pueden trabarse con tiempos del orden
de O(nlog n).
Juan Carlos Gutirrez Bar!uero____________________________________________ "&-
Bismarck Salvador Traa Lpez__________________________________________UNI
Esta tcnica es empleada para diferentes problemas como la interseccin de
segmentos, particin de polgonos en subdivisiones montonas, interseccin de
semiplanos, el diagrama de Voronoi y triangulacin de Delaunay, los mtodos
de Jarvis y Graham para el clculo de la envolvente convexa, la tcnica de
localizacin de los puntos ms lejanos, y otros ms. Existen tcnicas anlogas
para dimensiones mayores.
lgoritmo 1
El algoritmo de la lnea de barrido rotatoria (Rotational #)eep *ine):
ntrada+ Un conjunto de obstculos poligonales S y un conjunto de puntos Q.
#alida+ Un grafo de visibilidad G = (V, E).
Sea W la unin de los vrtices de S y los puntos de Q, sea E el conjunto de
aristas, y sea T un rbol de bsqueda equilibrado.
1.- Para cada vrtice w de V:
2.- Ordenar todos los vrtices de W en sentido horario segn la semi-lnea P,
y, en caso de empate, ordenar segn distancia al punto p.
3.- Ordenar las aristas que intersectan con P e insertarlas en el rbol
equilibrado T.
4.- Para cada vrtice w de la lista ordenada W:
5.- Si w es visible desde p, entonces aadir la arista e=(p, w) al grafo G.
6.- Insertar en el rbol los obstculos que incidan en w y que estn en el
lado horario de P.
7.- Eliminar del rbol los obstculos que incidan en w y que estn en el lado
antihorario de P.
1.".2. ,i'ide - .encers
Juan Carlos Gutirrez Bar!uero____________________________________________ "&"
Bismarck Salvador Traa Lpez__________________________________________UNI
Esta tcnica clsica de programacin es vlida para resolver de forma eficiente
problemas Geom. tricos. Normalmente se basa en la sucesiva divisin en
partes iguales del problema original, hasta conseguir que ste posea un
tamao lo suficientemente pequeo como para poder resolverse fcilmente.
Llegado a un punto en que la divisin deja de tener sentido, los problemas se
van resolviendo recursivamente y combinando sus soluciones para obtener la
solucin final. El mtodo ms eficiente de ordenacin, el ,uic(sort, est basado
en este paradigma.
El Algoritmo 2 resume los pasos empleados para resolver el problema Prob(#)
partiendo del conjunto de datos # y realizando sucesivas divisiones por dos.
Para que el algoritmo se considere eficiente se espera que el Paso 3.a) que
divide el problema en subproblemas y el Paso 3.c) que combina las soluciones
parciales, se realice en tiempo lineal. El segundo ejemplo de ecuacin de
recurrencia de la Seccin 1.2 corresponde al mtodo Divide y Vencers.
lgoritmo 2
/aradigma de di'ide - 'encers
Juan Carlos Gutirrez Bar!uero____________________________________________ "&#
Bismarck Salvador Traa Lpez__________________________________________UNI
Juan Carlos Gutirrez Bar!uero____________________________________________ "&$
Bismarck Salvador Traa Lpez__________________________________________UNI
Es un e%emplote .oronoi.
Esta tcnica es ampliamente utilizada
y sirve de base para construir
Juan Carlos Gutirrez Bar!uero____________________________________________ "&%
Bismarck Salvador Traa Lpez__________________________________________UNI
algoritmos aleatorios. Puede emplearse para construir la envolvente convexa,
el diagrama de Voronoi, etc.
2 +a en'ol'ente con'e0a - triangulacin de polgonos
2.1. +a en'ol'ente con'e0a
2.1.1. Introduccin
El clculo de la envolvente convexa de un conjunto de puntos en espacios
eucldeos ha sido sin duda uno de los problemas a la vez ms bsicos y ms
ampliamente estudiados a lo largo de la historia de la Geometra
Computacional. Adems, los campos en los que ha resultado un clculo til
sorprenden por lo aparentemente poco relacionados con las matemticas en
general y la geometra en particular.
Un conjunto convexo del plano se define como el conjunto que verifica que el
segmento que une a dos cualesquiera de sus puntos est totalmente contenido
en l. Evidentemente, esta definicin puede ser aplicada en cualquier espacio
eucldeo n-dimensional. La idea de conjunto convexo nos lleva inmediatamente
a la de envolvente convexa, considerando a sta como el menor conjunto
convexo que contiene a dicho conjunto. Este concepto es fcil de entender en
cierto modo si consideramos a la envolvente convexa de un conjunto de puntos
en el plano, como la forma que adquirira una goma elstica envolviendo a
todos los puntos del conjunto que estn fijos sobre el plano. De nuevo esta
idea es extensible intuitivamente a otras dimensiones, y puede servir de
partida para construir algoritmos simples para el clculo de la envolvente
convexa.
Pero exiten otras definiciones vlidas: la envolvente convexa de un conjunto
de puntos en el plano es la unin de todos los tringulos determinados por
dicho conjunto de puntos.
El estudio de la envolvente convexa en dos dimensiones ha sido objeto de
especial inters. Existen una serie de caractersticas asociadas a los puntos que
Juan Carlos Gutirrez Bar!uero____________________________________________ "&&
Bismarck Salvador Traa Lpez__________________________________________UNI
forman parte de la envolvente convexa en el plano y que han servido
igualmente para definirla y construirla. Un punto , 2 # pertenece a la
envolvente convexa de #, , 2-.(#), si es posible trazar una recta pasando por
dicho punto de forma que todo el conjunto #0, #0 = #-f,g quede a un lado de
dicha recta.
Como se ha indicado con anterioridad, el clculo de la envolvente convexa ha
sido aplicado ampliamente a disciplinas en ocasiones ajenas a la Geometra
Computacional y en espacios distintos de dos dimensiones. Tal es el caso del
reconocimiento de patrones, procesamiento de imgenes, etc.
Los algoritmos propuestos para este problema son realmente numerosos. Sin
duda es uno de los planteamientos de la Geometra Computacional que ms
soluciones ha conseguido. Desde incluso antes del nacimiento oficial de esta
disciplina se conoce el trabajo de Graham en el ao 1972. Se han propuesto
estrategias siguiendo los paradigmas ms empleados como el mtodo
incremental y el divide y vencers. Todos estos algoritmos construyen la
envolvente convexa en tiempo (nlog n). El mtodo propuesto por Preparata y
Shamos en 1985 fue denominado Quickhull por su similitud con el mtodo de
ordenacin Quicksort. Otra propuesta diferente se di a conocer en 1973 como
.La marcha de Jarvis.. Este mtodo, que estudiaremos en este curso, posee un
tiempo de ejecucin cuadrtico, sin embargo supone un interesante ejemplo
basado en manejo de ngulos del cual partiremos para el tratamiento del
diagrama polar. Todos estos trabajos constituyen el conjunto clsico de
algoritmos para la resolucin de la envolvente convexa, al que habra que
aadir otras tcnicas posteriores.
La envolvente convexa posee una cota de (nlog n), es decir, no se puede
encontrar una algoritmo que trabaje en menor tiempo para todos los casos.
2.1.2. $n e%emplo de resolucin
El problema de encontrar la envolvente convexa de un conjunto de puntos
puede ser interesante porque es equivalente a encontrar todo el conjunto de
puntos extremos de dicha nube. Por tanto, puede definirse como punto
extremo a cualquier punto de la envolvente convexa, y todo punto extremo
tiene la propiedad de que es posible trazar una lnea recta a travs de l de
modo que el resto de puntos queden a un lado.
Tambin podemos decir que un punto es extremo si y slo si est dentro de
algn posible tringulo cuyos vrtices son cualesquiera de los puntos de la
nube original. Pero bajo esta definicin, necesitaramos procesar O(n3)
tringulos para cada uno de los n puntos, lo que nos proporciona un mtodo en
triempo O(n4), lo cual no es eficiente teniendo en cuenta que se trata de un
problema (nlog n).
Pero la envolvente convexa posee aplicaciones fuera del mbito de la
Geometra. Supongamos que una explotacin petrolfera extrae diferentes tipos
Juan Carlos Gutirrez Bar!uero____________________________________________ "&'
Bismarck Salvador Traa Lpez__________________________________________UNI
de componentes mezclados en distinta propocin. Si el objetivo es conseguir
los componentes A y / pero en una nueva proporcin, podemos hacer uso de
la envolvente convexa del modo siguiente. Supongamos que partimos de las
mezclas:
e1 = 10%/35%, e2 = 16%/20% y e3 = 7%/15% y queremos obtener e
f = 13%/22%. Para saber si es posible obtener este producto final e f basta
con considerar las anteriores mezclas como puntos del plano, obteniendo el
siguiente esquema:
Todo punto que caiga dentro de la envolvente convexa de todas las muestras
representadas por puntos en el plano, indica que puede ser producida. Si por
contra, cayera fuera de dicha envolvente, la combinacin final no podra
producirse. Este problema sera un problema 3D si cada mezcla tuviera tres
componentes, la solucin sera la contruccin de la envolvente convexa
tridimensional.
2.1.3 lgoritmo tri'ial 1.
Determinacin de puntos extremos
1. Para cada i hacer
2. Para cada j i hacer
3. Para cada k i j hacer
4. Para cada h i k j hacer
5. Si Ph est a la izqda de (Pi,Pj) y
6. Ph est a la izqda de (Pj,Pk) y
7. Ph est a la izqda de (Pk,Pi)
8. entonces Ph no es extremo
Complejidad: O(n
4
)
2.1.! lgoritmo tri'ial 2.
Determinacin de aristas extremas
j i
H (piA pj) >ecuacin ".2?
Donde la notacin significa que la interseccin debe estar ocupada sobre todo i
y j como i
(n).
Asumamos pues por simplicidad que ninguna de los cuatro puntos son
cocirculares, y por consiguiente cada vrtice de Voronoi es de grado tres.
Construya la grfica dual G (Seccin 4.4) para un diagrama Voronoi V (P)
como sigue: Los nodos de G son sitios de V (P), y dos nodos estn conectados
por un arco si sus polgonos correspondientes de Voronoi comparten un borde
de Voronoi (comparten un borde de longitud positiva).
Ahora observe que ste es un grafo planar: Podemos incrustar cada nodo en
su sitio, y todo el incidente de arcos para el nodo puede ser angularmente
clasificado lo mismo los bordes del polgono. Adems todas las caras de G son
tringulos, siendo propio del vrtice de Voronoi de grado tres. Este reclamo
ser hecho ms claro en un momento (la Figura 5.6).
Pero previamente mostramos que la frmula de Euler significa que un grafo
planar triangulado con n vrtices tiene 3n-6 de bordes y 2n-4 caras; Vea la
Seccin 4.1.1 Teorema 4.4.5. Porque las caras de G son propias de los
vrtices de Voronoi, y porque los bordes de G son propios de los bordes de
Voronoi (desde que cada arco de G le cruza un borde de Voronoi), hemos
mostrado que el nmero de vrtices de Voronoi, bordes, y las caras es
(n).
Si ahora removemos, entonces la suposicin que ninguno de los cuatro puntos
son cocirculares, la grfica es todava planar, pero no necesariamente
triangulado. Por ejemplo, lo dual del diagrama mostrado en Figura 5.4 (a) es
un cuadriltero. Pero tales grficas poco trianguladas tienen menos conexiones
entre dos vrtices de un grfico y caras, as es que los
% (P). Ponga a un
crculo C (x) con centro en x, con radio igual a la distancia de a o b. Este
crculo est obviamente vaco de otros sitios, pero si no fuera as, el sitio c
estara sobre o dentro del crculo, x estara en V (c) igualmente, pero
conocemos que x esta solamente V (a) y V (b).
La implicacin inversa es ms sutil. Suponga que hay un crculo vaco C (x) a
travs de a y b, con centro en x. Tenemos la intencin de poner a prueba que
ab
V(a)
D (P).
Dejamos la prueba de las otras propiedades para la intuicin, los ejercicios, y
para la Seccin. 5.7.2
Ejercicios
1. El polgono regular [fcil]. Describa la triangulacin del diagrama de
Voronoi y la triangulacin de Delaunay para los vrtices de un polgono
regular.
2. Las regiones ilimitadas. Ponga a prueba la propiedad V2: V (pi) es ilimitada
del si pi est en el buque convexo del grupo del punto. No se haga cargo de
la propiedad correspondiente de Delaunay D6, pero de otra manera
cualquier propiedad Delaunay o Voronoi puede ser empleada en la prueba.
3. El vecino ms cercano. Ponga a prueba propiedad V6: Si el pj es un vecino
prximo a pi, entonces (pi, pj) es un borde de D (P). Cualquier propiedad
Delaunay o Voronoi puede ser empleada en la prueba.
4. El vrtice de Delaunay de alto-grado. Disee un grupo de puntos, con n
arbitrario, y sin cuatro puntos cocirculares, algo semejante aqul que el
vrtice de la triangulacin Delaunay tiene grado n-1.
5. Numero promedio de bordes del polgono de Voronoi, pruebe que el
promedio de todas las regiones Voronoi para cualquier grupo de n puntos,
no excede 6.
6. Las triangulaciones de Pitteway. Una triangulacin de un grupo de P de
puntos es llamada una triangulacin Pitteway si, para cada tringulo T = (a,
b, c), cada punto en T tiene uno de a, b, o c como su vecino mas cercano
entre los puntos de P.
a. Muestre por ejemplo que no toda triangulacin de Delaunay es una
triangulacin de Pitteway.
b. Caracterizar aquellas triangulaciones de Delaunay que son
triangulaciones de Pitteway.
+os +GO:I8*O6
Las muchas aplicaciones del diagrama de Voronoi y su belleza inherente les
han instado a los investigadores a que inventen una coleccin variada de
algoritmos para computarlo. En esta Seccin 5.7.2 examinaremos cuatro
algoritmos, cada uno superficialmente, para ver que la Seccin 5.7.2 que el
diagrama Voronoi puede ser computado usando nuestro cdigo del buque
convexo.
+a interseccin de los 6emiplanos
Podramos construir cada regin de Voronoi separadamente, por la interseccin
de n-1 semiplanos segn la ecuacin (5.2). Construyendo la interseccin de n
Juan Carlos Gutirrez Bar!uero____________________________________________ ",#
Bismarck Salvador Traa Lpez__________________________________________UNI
semiplanos es dual para la tarea de construir el buque convexo de n puntos en
dos dimensiones y puede ser llevado a cabo con algoritmos similares en el
tiempo O(n log n) tiempo (Ejercicio 6.5.3 [5]). Hacer esto para cada sitio
costara a O (n
2
log n).
Construccin incremental
Suponga que el diagrama de Voronoi V para k puntos estn ya construidos, y
ahora nos gustara construir el diagrama V despus de aadir uno o mas
puntos p. Suponga que p cae dentro de los crculos asociados con varios
vrtices de Voronoi, dice C (v1),., C (vm). Entonces estos vrtices de V no
pueden ser vrtices de V, pues violan la condicin de que los crculos del
vrtice de Voronoi deben estar vacos de sitios (V5, Seccin 5.3.2). Resulta
que stos son los nicos vrtices de V que no estn arrastrados sobre V
Tambin resulta que estos vrtices estn todos localizados en un rea del
diagrama. Estas observaciones vagas pueden ser hechas precisas, y forjan uno
de los algoritmos ms limpios para construir el diagrama de Voronoi. El
algoritmo gasta O (n) tiempo por insercin de punto, para una complejidad
total de O (n
2
). A pesar de esta complejidad cuadrtica, ste ha sido el mtodo
ms popular de construir el diagrama; Ver Field (1986) para los detalles de
implementacin.
El algoritmo incremental ha sido revitalizado recientemente con aleatorizacin,
el cual tocaremos en la Seccin 5.7.4.
,i'ide - 'encers
El diagrama de Voronoi puede estar construido con un complejo algoritmo
divide y conquista en el tiempo O (n log n), primera parte detallada por
Sahmos y Hoey (1975). Fue este papel que introdujo el diagrama de Voronoi
para la comunidad de ciencia de la computacin. Esta vez la complejidad es
asintticamente ptima, pero el algoritmo es bastante difcil para implementar.
De cualquier forma puede estar hecho con atencin meticulosa para las
estructuras de datos.
Juan Carlos Gutirrez Bar!uero____________________________________________ ",$
Bismarck Salvador Traa Lpez__________________________________________UNI
Omitiremos este algoritmo histricamente importante para enfocar la atencin
en algunos desarrollos recientes emocionantes.
El algoritmo de 7ortune
Hasta la mediados de los 80, la mayora de implementaciones para computar
el diagrama de Voronoi le usaron a la O (n
2
) algoritmo incremental, aceptando
su desempeo ms lento para evitar las complejidades de la codificacin divide
y conquista. Pero en 1985, Fortune (1987) invent un algoritmo del barrido de
plano listo que es tan simple como los algoritmos incrementales pero tiene
complejidad del peor caso de O (n log n). Nosotros ahora esbozaremos la idea
principal detrs de este algoritmo.
Los algoritmos Plane-sweep(barrido de plano) (Seccin 2.2.4 ) pasan una lnea
de barrido sobre el plano, dejando en cualquier hora el problema solucionado
para la porcin del plano ya barrido y no resuelta para la porcin todava no
alcanzada. Un algoritmo Plane-sweep para construir el diagrama de Voronoi
construira el diagrama detrs de la lnea. A primera vista, esto parece
realmente mentira, como los bordes Voronoi de una regin de Voronoi V (p)
seran encontrados por la lnea de barrido antes de que la L encuentre la p del
sitio responsable para la regin. Fortune super esta imposibilidad aparente
por una idea extraordinariamente lista.
+os conos
Imagine los sitios en el plano xy del sistema de coordenadas tridimensional.
Erecto sobre cada sitio p un cono cuya cima est en p, y cuyos lados se
Juan Carlos Gutirrez Bar!uero____________________________________________ ",%
Bismarck Salvador Traa Lpez__________________________________________UNI
inclinan a 45. Si la tercera dimensin es mirada como el tiempo, entonces el
cono sobre p representa un crculo dilatndose sobre p a una velocidad nica:
Despus de t unidades tiempo, su radio es t.
Ahora considere dos conos cercanos, sobre los sitios p1 y p2. Se intersecan en
una curva en el espacio. Recordando la vista de crculos en expansin del
diagrama de Voronoi, debera ser esperado que esta curva yazca enteramente
en un plano vertical, el plano ortogonal para la bisectriz de p1p2. Vea la Figura
5.9. As que aunque la interseccin est curvada en tres dimensiones, se
proyecta para una lnea recta en el plano xy.
Es solamente un paso pequeo de aqu a que si los conos sobre todos los
sitios son opacos, y son mirados de z = -
, lo que se ve es precisamente el
diagrama Voronoi!
El corte del cono
Estamos ahora preparados para describir la idea de Fortune. Su algoritmo
barre los conos con un plano sesgado, sesgado a 45 para el plano xy. La L de
la lnea de barrido es la interseccin con el plano xy. Demos por supuesto que
la L es paralela al eje vertical y que su coordenada de la x es l(ele). Vea Figura
5.10. Imagnate que
con la
"frontera derecha (x positiva) de los conos. La interseccin de
con
cualquier cono es una parbola (una propiedad bsica de secciones cnicas), y
as la interseccin de
encuentra dos conos. De nuestro debate de la interseccin de dos conos arriba,
esto debe estar en un borde de Voronoi.
7rente parablico
Ahora finalmente podemos ver cmo solucion Fortune el problema del
problema de la lnea de barrido encontrando bordes de Voronoi antes de los
sitios generadores: Porque su plano de barrido se inclina en los mismos
bordes como los lados de los conos, L encuentra un sitio p exactamente
cuando
minc
a| a - c |, donde c
P. Podemos escribir esta relacin a b: Un vecino cercano de a es b. Note
que la definicin no es simtrica con respectos a las tareas que a a y b les
toca, sugiriendo que la relacin no sea as misma simtrica. Y de hecho ste es
ciertamente el caso: Si a b, no es necesaria que b a; Ver a Figure 5.12
Tambin nota que un punto puede tener varios vecinos igualmente cercanos
(ejemplo, punto d en la figura).
El 'ecino cercano pregunta
Dado un grupo fijo de puntos P, construir el diagrama de Voronoi en el tiempo
O (n log n). Ahora para un punto de consulta q, encontrando un vecino cercano
de q para encontrar en cul regin de Voronoi cae, pues los sitios de esas
regiones de Voronoi son precisamente sus vecinos cercanos. El problema de
hallar un punto dentro de una particin es llamada localizacin del punto. El
problema ha sido estudiado con exceso y ser discutido en el Captulo 7
(Seccin 7.11). Veremos que en este ejemplo, el tiempo O (log n) es suficiente
para cada consulta.
Todos los Vecino Cercanos
Defina al Nearest Neigbor Graph ((NNG) Graficos de vecinos mas cercanos)
para asociar un nodo con cada punto de P y un arco entre ellos si un punto es
un vecino cercano del otro. Hemos definido esto para ser un grfico orientado,
Juan Carlos Gutirrez Bar!uero____________________________________________ ",*
Bismarck Salvador Traa Lpez__________________________________________UNI
aunque la relacin no es simtrica, adecuadamente podra ser directa. Pero no
necesitaremos la versin directa aqu.
Una forma sucinta a captar la esencia del algoritmo del vecino cercano
eficiente es a travs del siguiente lema.
Lema 5.5.1 NNG
D (P)
Dejo la prueba para el ejercicio 5.5.6 [2] y [3 ]
Un algoritmo de fuerza bruta para encontrar a los vecinos cercanos para cada
punto en un grupo requerira O (n
2
), pero el lema de arriba nos deja registrar
solo los bordes O (n) de la triangulacin de Delauny y por lo tanto logra O (n
log n).
.ecino natural& Otra forma de conseguir el valor que tendra un punto
cualquier p sera el
de conocer todos aquellos vecinos naturales de p. Averiguar esta informacin
no es ms
que resolver el problema de los vecinos ms cercanos a un punto utilizando el
diagrama
de Voronoi. Aplicaciones en este sentido son la identi_cacin de tomos
vecinos en el
espacio, molculas o partculas en estructuras cristalinas y amorfas, etc. Ahora
el punto
de estudio p puede estar in_uenciado por dicho conjunto de vecinos, los cuales
tambin
puede llevar asociados distintos pesos de in_uencia
1.".2 +a triangulacin *a0imi)ando el Cngulo *nimo.
Juan Carlos Gutirrez Bar!uero____________________________________________ ",+
Bismarck Salvador Traa Lpez__________________________________________UNI
Analizar las propiedades estructurales de forma complicada es a menudo
realizado por una tcnica llamada "anlisis finito del elemento. Esto es usado,
por ejemplo, por fabricantes del automvil a modelar cuerpos del coche (Field
1986). El dominio a ser estudiado est subdividido en una malla de "elementos
finitos, y entonces las ecuaciones diferenciales relevantes modelando la
dinmica estructural sea solucionado por discretizacin sobre la particin. La
estabilidad de los procedimientos numricos usados depende de la calidad las
buenas particiones y esto pasa por que la triangulacin de Delaunay son
especialmente buenas particiones. Nosotros ahora discutiremos el sentido en el
cual la triangulacin Delauny es buena.
Una triangulacin de un grupo de puntos S es la generalizacin del objeto del
cual la triangulacin de Delauny es un ejemplo particular. Un grupo de
segmentos cuyos puntos finales estn en S, Que slo interseca a cada quien en
puntos finales, y cul divide en partes el buque convexo de S en tringulos.
Para los propsitos del anlisis finito del elemento, las triangulaciones con
tringulos " gordos son ms convenientes. Una forma para hacer esto precisa
ms es evitar tringulos con ngulos pequeos. As es natural buscar una
triangulacin que tiene el ngulo menor ms grande, esto es, para maximizar
el ngulo de ms pequeo sobre todas las triangulaciones. Esto ocurre para
hacer precisamente la triangulacin de Delauny! De hecho, una declaracin
algo ms fuerte puede ser hecha, cul nosotros ahora describimos despus de
introducir alguna notacin.
Sea T una triangulacin de un grupo de puntos S, y sea su secuencia de
angulos(
1,
2, .,
1 >
1, o
1 =
1 y
2 >
2 o
1 =
1 y
2=
2 y
3 >
, >p?
Para el MST de puntos en el plano, hay (
#
n
) bordes, as es que la complejidad
del paso de clasificacin es O (n
2
log n) si es cargada fuera en la grfica
completa. Para llamar a este registro de los bordes de la triangulacin de
Delaunay de proximidad en algn sentido, es razonable esperar que slo los
bordes de Delaunay alguna vez necesiten ser usados para construir un MST. Y
afortunadamente esto es cierto, como se muestra en el siguiente teorema.
Teorema 5.5.5 *o m?nimo ,ue se extiende a lo largo un 'rbol es un
subconjunto de triangulaci:n $elaunay: 1#T $ 2p7.
/rueba. Queremos mostrar que si ab MST, entonces ab D. Implica that
ab MST y suponga lo contrario que ab
D, ningn crculo a
travs de a y b puede estar vacos. En particular, el crculo de dimetro ab
debe de tener un sitio dentro de este.
As se supone que C est en este crculo, como se muestra en figura 5.16.
Entonces
| ac | < | ab |, y |bc|< |ab|; Estas desigualdades tienen aplicacin aun si C
est en el crculo, puesto que la C es distinta de a y b. La extraccin de ab
desconectar el rbol en dos rboles internos, con a en primera parte, 8a, y b
en el otro, 8b. Suponga sin la prdida de generalidad que e esta en Ta.
Elimine ab y aada el borde bc para hacer un rbol nuevo,
T = Ta bc +Tb. Este rbol es mas corto, as el nico nico usado ab, no podra
serminimo. Hemos alcanzado una contradiccin negando que ab est en $, as
es que debe ser ese ab D.
Juan Carlos Gutirrez Bar!uero____________________________________________ #-&
Bismarck Salvador Traa Lpez__________________________________________UNI
Esto entonces produce una mejora en el primer paso de algoritmo de Kruskal:
Primero encuentre la triangulacin de Delaunay en el tiempo O (n Long n), y
entonces clasifique slo esos bordes O (n), en el tiempo O (n logn). Resulta lo
dems de algoritmo de Kruskal puede ser implementado para poner a
funcionar en O (n log n), para que la complejidad total por encontrar el MST
para el grupo de n untos en el plano es O (n log n).
".".". El /roblema del .endedor de 'ia%es.
Uno de los problemas ms estudiados en la informtica es el problema del
vendedor de viajes: Encuentre el ms pequeo camino cerrado que visita cada
punto en un grupo dado. Tal camino se llamado (l camino Ven"e"or "e
+iajes(TS,)- imagine los puntos como ciudades que el vendedor debe visitar
en el orden arbitrario antes de devolver casa. Este problema tiene tremenda
importancia prctica, no slo para esa aplicacin si no porque muchas otras
problemticas pueden reducirse a l. Se ha probado que desafortunadamente,
el problema es duro NP, un trmino tcnico que ningn algoritmo polinmico
conoce para resolverlo (Garey y Johnson 1979); Ni parece probablemente al
momento de escribir la presente que a ser encontrada. Las combinaciones de
significado prctico y la inflexibilidad han conducido a una bsqueda para los
algoritmos de heursticas efectivos y de aproximacin. Uno de los algoritmos
de la aproximacin ms simples es basado en la triangulacin de Delaunay, Va
lo m?nimo ,ue #e extiende a lo largo el 'rbol.
La idea es ms bien algo simple, pero no obstante hace un trabajo razonable.
Encuentra al MST para el grupo de puntos, y simplemente lo lleva cabo y lo
all por la manera ilustrada en Figure 5.17. Debera estar claro que la
excursin construida por aqu tiene exactamente dos veces el largo del MST,
desde que cada borde del rbol se cruza una vez en cada direccin.
Juan Carlos Gutirrez Bar!uero____________________________________________ #-'
Bismarck Salvador Traa Lpez__________________________________________UNI
Ahora obtenemos un lmite dentrote que esta mal este doble-MST recorrido
podra ser. Sea M la longitud de +o mnimo Due se e0tiende a lo largo un
rbol y M2 la longitud de a doble-MST; claro M2 = 2M. Sea T la longitud de
El camino de un .endedor de 'ia%es r y T1 la longitud de un TSP con un
borde removido. Note que T1 se extiende a lo largo del rbol.
Las siguientes desigualidades son inmediatas:
T1 < T,
M T1,
M < T,
M2 < 2T.
Esto entones logra un lmite superior constante en la calidad del recorrido: Lo
doble-MST no est peor que dos veces la longitud de TSP.
Juan Carlos Gutirrez Bar!uero____________________________________________ #-*
Bismarck Salvador Traa Lpez__________________________________________UNI
Este resultado puede ser mejorado con heursticas diversas. Esbozar slo el
ms simple tan heurstico, lo cual se basa en la determinacin comprensible
para no volver a visitar un sitio dos veces. El recorrido del camino doble-MST
de entrada, con la modificacin que si el prximo sitio ya se ha visitado hasta
ahora por el camino, salte el sitio y considera conectarse al prximo uno a lo
largo del doble-MST recorrido. Esto hace el efecto de tomar una ruta ms
directa para recorrer MST . Si ponemos en un ndice los sitios por el orden en
que ellos se visitan a lo largo del recorrido del MST, a algunos sitios que Si
podra conectar para Sj por un segmento de la lnea recta o un atajo al
recorrido, considerando que el recorrido doble-MST sigue un camino encorvado
Si, Si+1 , ., Sj-1,Sj.. Heurstico puede ser nico acorta el camino. Un ejemplo
es mostrado 5.18. Note que el camino fue acortado.
Desafortunadamente este heuristico no garantiza un desempeo mejorado,
pero una variacin leve Conocido como las gamas "Heursticas Christofides.
Usa un grupo de segmentos llamados un "El mnimo de Euclideano
emparejando como un gua para atajos y puede garantizar un longitud del
camino no ms de (3/2) T, eso es, no ms de 50 % ms largo que lo ptimo.
Ms heursticos sofisticaron generalmente encuentran un camino dentro de un
poco porcentaje ptimo (Bentley 1992), aunque este desempeo no est
garantizado en su estado actual para el algoritmo citado anteriormente. Un
resiente descanso terico es sin dudarlo el esquema de aproximacin de
Polinomio-tiempo para el TSP, acerca de lo mejor, puede ser esperanza para
un problema completo a NP. ste es un mtodo de llegar dentro (1 + ) de
optativo para cualquier > 0, en un tiempo O (np), dnde la p son
proporcionales para 1/. Vea a Arora (1996) y Mitchell (1996).
".".# +os e%ercicios
5. l grado de @"@A. Cul es grado mnimo de salida de un nodo de un
Grafico de vecino mas cercano(NING) (la Seccin 5.5.1) de n puntos en dos 2
dimensiones? Cul es el grado mximo de un nodo? Demuestran ejemplos
que justifiquen su respuesta, e intento probar que son mximos.
2. NNG y D [Fcil] . Encuentran un ejemplos que muestre ese NNG pueden ser
un subconjunto correcto de D (p).
3. NND D. Ponga a prueba a Lema5.5.1: Si la b es una vecina prxima de a.
Entonces ab D (p).
4. Los Nmeros de tringulos en una estrangulacin. Comprobar que el
nmero de tringulos t en cualquier triangulacin de algn grupo de puntos
reparados S esat una constante toda triangulacin de S tiene la misma t.
5. El vrtice de Voronoi no un mximo local. Construya un grupo de puntos
que tiene un vrtice de Voronoi estrictamente p dentro del buque, algo
semejante que f (p) no es un mximo local, donde la f es funcin del radio
definido en la seccin 5.5.3
Juan Carlos Gutirrez Bar!uero____________________________________________ #-+
Bismarck Salvador Traa Lpez__________________________________________UNI
6. El algoritmo del crculo vaco. El detalle (en el cdigo pseudo) cmo llevar a
cabo el algoritmo del crculo vaco (Algoritmo 5.1) con el fin de que su
complejidad de tiempo es O (n log n).
7. El Grfico del Barrio relativo (RNG) de juego de puntos P1,., Pn es un
grfico cuyos nodos corresponden a los puntos, y con Pi de dos nodos y Pj
conectado por un arco ellos son para que no acerca de cualquier otro punto,
eso es, si
|Pi + Pj|
j i m 0
ma7
{ | Pi + Pm |,| Pi + Pm | }.
(Vea Jaromezyk + y Toussaint (1992).) Esta ecuacin determina una regin "
prohibida dentro de la cual ningn punto Pm puede mentir si Pi y Pj son
adyacentes en el RNG, no a diferencia del Teorema 5.3.1 Esta regin, llamada
Lune ( Pi, Pj), son la interseccin de dos discos abiertos centradas en Pi y Pj,
ambos de radio | Pi - Pj |.
a. Disee un algoritmo "de fuerza bruta para construir al RNG. No se
preocupe por eficiencia. Qu es su complejidad de tiempo?
b. Ponga a prueba a ese RNG: Cada borde del RNG es tambin borde de la
triangulacin de Delauny. (Comprese con Teorema 5.5.5).
c. Use (b) disear un algoritmo ms rpido.
8. El tamao de triangulacin de Delaunay en tres dimensiones. Tenemos que
mostrar cual es el tamao de la triangulacin de Delaunay adentro de dos
dimensiones es lineal, O (n). Mostrar que esto no se mantiene en tres
dimensiones: El tamao de D (p) puede ser cuadrtico. Defina a D (p) en tres
dimensiones exactamente, anlogamente y para la versin de Dos
dimensiones (bidimensional): Es el dual de V (p), el cual es el lugar de puntos
geomtricos que no tienen un nico vecino cercano.
Sea P un punto determinada consistente en dos partes:
a El n/2 puntos uniformemente distribuidos alrededor de un crculo en el
plano x y centrados en el origen, y
b El n/2 puntos uniformemente distribuidos en el origen del eje z
simtrico al origen..
Sostenga la opinin que el tamao de D (p) es (n2).
B. l tamaCo del gr'fico del barrio relativo 2R@A7 en dimensiones del 'rbol.
Ejercicio[7] anteriormente establecido ese RNG D (P) en dos dimensiones, y
esta relacin contiene dimensiones arbitrarias. Se ha demostrado el tamao
Juan Carlos Gutirrez Bar!uero____________________________________________ #-,
Bismarck Salvador Traa Lpez__________________________________________UNI
que tiene el RNG en dimensiones del rbol es O (n3/2) (Jaromezyk y Toussaint
1992), as es que es ms pequea que la triangulacin de Delaunay. Pero
parece que este salto superior es dbil: Jaromezyk y Kowaluk (1991) suponen
que el tamao es O (n). Confirmar esta conjetura es un problema.
10. MST
, estn ms que el r
2
arriba, cul es el r
2
debajo. Por eso estos puntos se proyectan fuera del crculo
de radio r en el plano x y. Por eso el crculo determinado adentro de los planos
x y est vaco en todos los otros sitios. Por eso forma un tringulo Delaunay.
Por eso cada cara triangular inferior del buque convexo es propia de un
tringulo Delaunay. Por eso la proyeccin del "fondo del buque convexo se
proyecta para la triangulacin Delaunay! Otra vez evacue a Figure 5.26.
Djeme explicar esta compenetracin importante otra vez de otra manera.
Comience con el plano t contiguo para el paraboloide por encima de p = (a, b).
Su punto de contacto se proyecta hacia abajo para p. Ahora muvase t arriba.
La proyeccin de su interseccin con el paraboloide es un crculo en expansin
puesto en el centro en p. Cuando los t golpes una punto q en el paraboloide
que esta por encima de un sitio, las intercepciones del crculo en expansin en
el sitio en el plano que es la proyeccin de q. As el crculo est vaco t hasta
los lmites exteriores, cundo atraviese los tres sitios cuya proyeccin forma
la cara del buque del tringulo soportada por
.
Un corolario til para el debate citado anteriormente es ste:
Juan Carlos Gutirrez Bar!uero____________________________________________ #"*
Bismarck Salvador Traa Lpez__________________________________________UNI
Corolario 5.7.1 Cuatro puntos (xi, yi), i = 1, 2, 3, 4, consisten en una mentira
del crculo si (xi, yi, xi
2
yi
2
) en un plano.
La coplanaridad de estas puntos puede ser comprobada viendo si el volumen
del tetraedro que determinan (la Ecuacin 1.15 y 4.6) es cero.
+a implicacin
8eorema ".B.2 *a triangulaci:n de $elaunay de un grupo de puntos en dos
dimensiones es precisamente la proyecci:n para el Plano x y del bu,ue
convexo inferior de lo transformado apunta en tres dimensiones, transformado
por mapeo arriba para el paraboloide & D x2 y2!
Desde que el buque convexo en tres dimensiones puede ser computado en el
tiempo O (la Seccin 4.2.2) (n log n), esto significa que la triangulacin de
Delaunay puede ser computada en el mismo tiempo lmite. Una vez que la
triangulacin Delaunay est en tus manos, es relativamente fcil computar el
diagrama Voronoi (el Ejercicio 5.7.5[2 ] ). Esto conduce a otro algoritmo O (n
log n) para construir el diagrama de Voronoi.
Como se podra esperar, esta relacin entre diagramas Voronoi y podra
abombar buques que yo una dimensin ms alta mantengo en dimensiones
arbitrarias. As ambos el diagrama Voronoi y la triangulacin Delaunay en tres
dimensiones pueden forjarse de un buque convexo en cuatro dimensiones. De
hecho, puede ser que el ms uso comn de cdigo del buque del 4D es para
construir mallas slidas de Delaunay tetradrico. En general, el diagrama de
Voronoi dual para un grupo de puntos de d-dimensional es la proyeccin del
buque " inferior de puntos en d + 1 dimensin.
+a implementacin de la 8riangulacin de ,elauna-& El cdigo O >n!?
8eorema ".B.2 el cdigo conciso permite increblemente computar la
triangulacin de Delaunay, si uno es indiferente sobre la complejidad de
tiempo En particular, si O (n
4
) es aceptable (y raramente lo es), entonces la
triangulacin de Delaunay puede ser computada con menos esas treinta lneas
de cdigo de la C! Esto es presentado en cdigo ".1 en parte como la
curiosidad, pero tambin a enfatiza cmo la comprensin profunda de
geometra puede conducir al cdigo limpio.
main()
{
int x[MAX],y[MAX],z[MAX]; /*Intreda de puntos x,y,z*/
Juan Carlos Gutirrez Bar!uero____________________________________________ #"+
Bismarck Salvador Traa Lpez__________________________________________UNI
int n; /*Numero dep puntos introducidos*/
int i,j,k,m; /*induce de cuatro puntos*/
int flag; /*localizacion normal de (i,j,k)*/
/*Intrda de puntos y computar z=x^2+y^2*/
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d %d",&x[i],&y[i]);
z[i]=x[i]*x[i]+y[i]*y[i];
}
/*por cada tres (i,j,k)*/
for(i=0;i<=n-2;i++)
for(j=0;j<=n-2;j++)
for(k=0;k<=n-2;k++)
if(j!=k)
/*computar la triangulacion normal*/
xn=(y[j]-y[i]*z[k]-z[i])-(y[k]-y[i]*z[j]-a[i]);
yn=(x[k]-x[i]*z[j]-z[u])-(x[j]-x[i]*z[k]-z[i]);
zn=(x[j]-x[i]*y[k]-y[i])-(x[k]-x[i]*y[j]-y[i]);
/*solo examina las caras del boton de la paraboloide zn <0*/
if(flag==(zn<0))
/*para otro punto m*/
for(m=0;m<n;m++)
{
/*revizar si m se acerca (i,j,k)*/
flag=flag&&
((x[m]-x[i]*xn+
(y[m]-y[i]*yn+
(z[m]-z[i]*zn<=0;
if(flag)
printf("%d\t%d\t%d\n",i,j,k);+
}
}
La estructura O (n
4
) del cdigo es evidente yo los cuatro de para lazos
anidados. Para cada triple de puntos (i, j, k), el programa revisa y ve si todos
los otros puntos m estn o por encima del plano conteniendo i, j, y k. Si es
as, (i, j, k) es salida como tringulo Delaunay. (La smil arridad para el
algoritmo del buque de dos dimensiones en Algoritmo 3.2 debera ser
evidente).
Juan Carlos Gutirrez Bar!uero____________________________________________ #",
Bismarck Salvador Traa Lpez__________________________________________UNI
8riang. de ,elauna- dual.
La prueba de por encima de plano es realizada chocheando la orientacin
exterior normal para el tringulo, (xn, yn, zn), con un vector de punto para
apuntar m.
Aunque es interesante para ver tal cdigo sucinto computar un propsito guste
la triangulacin Delaunay, es imprctica para varias razones:
1. El cdigo devuelve todos los tringulos dentro de una cara de
triangulacin Delaunay cuyo lmite consta de cuatro o ms puntos del
cocircular. As una mueca cuadrada resulta en salida cuatro de tringulo,
representando las dos triangulaciones del cuadrado. Obtener ms salida til
requerira el postprocesamiento.
2. Hay ineficiencias obvias en el cdigo (por ejemplo, la m-loop podra
quebrarse cuando un punto es descubierto debajo del plano del I, j, k).
Estos podran repararse fcilmente al precio de alargarle un poco, pero.
3. La dependencia de tiempo del n
4
es inaceptable. Pues dos prueban
carreras con n = 100 y n = 200 puntos, el tiempo de computar fue 12 y
239 segundos respectivamente, exhibiendo un ms de 24 incremento de
16 pliegues para el doble nmero de puntos. Esto indica 1,000 tan n
tomaba varios das.
8riangulacin de ,elauna- 3, cscara& O >el n2? el Cdigo
Es una tarea fcil convertir el cdigo cuadrtico desarrollado en Captulo 4
para construir el buque del 3D en el cdigo cuadrtico para construir la
triangulacin Delaunay. Toda la complejidad est en el cdigo del buque
(cdigo de casi 1,000 lneas de ) acerca del razonamiento que entr en
Teorema 5.7.2. Las modificaciones adicionales son relativamente menores.
Juan Carlos Gutirrez Bar!uero____________________________________________ ##-
Bismarck Salvador Traa Lpez__________________________________________UNI
Primer, que la rutina :ead.ertices (cdigo 4.10) debera leer en x, y y
computar z= x
2
+y
2
. En segundo lugar, despus del buque entero se forja,
un procedimiento +oFer7aces se siente llamado al lazo sobre todas las
fases e identifique cules es en la carena (cdigo 5.2). Como en cdigo
secreto 5.1, este est consumado computando las coordenadas de la z de
un vector normal para cada f de la cara. Esta computar, encarnado en
Normz, es justamente un cambio leve para Collinear (Cdigo 4.12). Si
;orm) >f? G )A entonces la cara est en la carena, y su proyeccin encima
del Plano x y es un tringulo de Delaunay.
Ilustramos con un ejemplo de n = 10 puntos cuyas coordenadas son
ostentadas en la tabla 5.1. Note que las coordenadas de la z son infundidas
arriba en la magnitud cuadrando. Esta parte pequea que el ejemplo
detiene adecuadamente dentro del rango seguro de la computar de
volumen discuti comparacin para el cdigo del buque del 3D. La salida
/ostscript del cdigo es mostrada en Figure 5.29.
Como esperada, esta implementacin O (n
2
) es mucho ms rpida que el
cdigo O (n
4
): En la misma n = 100 y n = 200 ejemplos que mientras
cdigo ms lento us 12 y 239 segundos, el cdigo ms rpido usaron 0.2 y
1.3 segundos respectivamente. Adems, la aceleracin del randomizadas
discuti en Seccin 4.5 vueltas as de en una O (n log n) esperado
algoritmo de tiempo.
".B." E%ercicio 1.
El rango de dt2.c [programacin] . Encuentro un grupo del punto cuyas
coordenadas son tan pequeas como sea posible, y para las cuales el
cdigo del dt2.c (cdigo 5.2) devuelve un resultado incorrecto debido al
derramamiento del clculo de volumen.
void LowerFaces(void)
{
tFace f=faces;
int Flower=0; /*numero total*/
do{
if(Normz(f)<0){
Flower++;
f->vertex[0]->Vnum,
f->vertex[1]->Vnum,
f->vertex[2]->Vnum);
}
f=f->next;
}while(f!=faces);
printf("%d lower faces identificada\n",Flower);
}
Juan Carlos Gutirrez Bar!uero____________________________________________ ##"
Bismarck Salvador Traa Lpez__________________________________________UNI
int Normz (tFaces f)
{
tvertex a, b, c;
a=f->vertex[0];
b=f->vertex[1];
c=f->vertex[2];
return
(b->v[x]-a->v[x])*(c->v[x]-a->v[y])-
(b->v[y]-a->v[y])-(c->v[x]-a->v[x]);
}
2. D V (P) (P) [programacin] . Modifique el cdigo del dt2.c para
computar el diagrama de Voronoi de la triangulacin de Delaunay. (Vea
ejercicio 5.5.6 [1]). Hay que repetidamente construir crculos a travs de
tres puntos dadas a, b, c. Las coordenadas de la p central = (p0, p1)
pueden ser computadas como sigue:
A = b0 - a0,
B= b1 - a1,
C = c0 - a0,
D = c1 - a1,
E = A(a0 + b0 ) + B(a1 + b1 ),
F = C(a0 + b0 ) + D(a1 + b1 ),
G = 2(A(c1 - b1 ) - B(c0 - b0 )),
p0 = (DE - BF)/G,
p1 = (AF - CE)/G.
8abla ".1 Coordenadas de sitios de Delaunay, Incluyendo z= x
2
+y
2
I X Y X
2
+y
2
0 31 -76 6737
1 -13 21 610
2 -63 -83 10858
3 -5 -66 4381
4 87 -94 16405
5 40 71 6641
6 23 -46 2645
7 64 -80 10496
8 0 -57 3249
Juan Carlos Gutirrez Bar!uero____________________________________________ ###
Bismarck Salvador Traa Lpez__________________________________________UNI
9 -14 2 200
".H Cone0in a arreglos
Tenemos que mostrar que la triangulacin de Delaunay puede ser derivada de
la transformacin paraboloide e indican que es fcil de obtener el diagrama de
Voronoi si es posible obtener el diagrama de Voronoi directamente de la
transformacin del paraboloide. Aunque todo esto se entiende que tienes que
esperar al siguiente capitulo (Seccin 6.7) y mostraremos la conexin que se
realiza utilizando las ecuaciones mas relevante.
5.8.1 Diagrama de Voronoi unidimensional
Considerando dos tangentes examinadas en la seccin 5.7.1 (ecuacin 5.4)
siendo x=a y otro siendo x=b:
z=2ax-a
2
z=2bx - b
2
Donde se intersecan resolviendo las ecuaciones simultneas la solucin sera
2ax-a
2
= 2bx - b
2
,
x(2a - 2b)=a
2
- b
2
,
x=(a+b)(a-b)
2(a-b)
x= a+b
2
De esta manera la proyeccin de las intersecciones estn adyacentes al
diagrama de Voronoi y al grupo de puntos
".H.2 ,iagrama de .oronoi bidimensinal
Juan Carlos Gutirrez Bar!uero____________________________________________ ##$
Bismarck Salvador Traa Lpez__________________________________________UNI
Considere dos tangentes planas del paraboloide analizado en la Seccion (5.7.2)
(ecuacin 5.8), donde estan a y b y otra donde esta c y b.
z = 2ax + 2by - a
2
+ b
2,
z = 2cx + 2dy - c
2
+ d
2
donde estn los intersectos? Resolviendo la ecuacin simultanea
2ax + 2by - a
2
+ b
2
= 2cx + 2dy - c
2
+ d
2
x(2a - 2c) + y(2b - 2d) = ( a
2
- c
2
) + (a
2
+ b
2
)
Esta ecuacin es precisamente la bisectriz perpendicular del segmento de (a,b)
y (c,d) ver figura 5.31.
Si observamos las tangentes opacas planas de z=+infinito (con el paraboloide
transparente) debera ser visible en la primera interseccin su primera
interseccin es la bisectriz entre los lugares que generan las tangentes planas
la proyeccin de estas primeras tangentes es precisamente el diagrama de
voronoi!
Tambin tenemos que recordar la situacin al visualizar la proyeccin de
puntos dentro del paraboloide de z=-infinito vea la triangulacin de Delaunay
la observacin de las tangentes planas del paraboloide y estos puntos de
z=+infinito vea el diagrama de Voronoi.
=ibliografa
[1] M. Berg, M. Kreveld, M. Overmars, O. Schwarzkopf. -omputational
Aeometry, Algorithms
and Applications! Springer, 1997.
[2] M. Kreveld, J. Nievergelt, T. Roos, P. Widmayer. Algorithmic Eoundations of
Aeographic
"nformation #ystems! Springer, 1997.
[3] J. O'Rourke. -omputational Aeometry in -! Cambridge University Press,
1994.
[4] F. P. Preparata y M. I. Shamos. -omputational geometry+ an introduction!
Springer-Verlag,
New York, 1985.
73
Juan Carlos Gutirrez Bar!uero____________________________________________ ##%