
En gráficos por computadora , el algoritmo de Cohen-Sutherland se utiliza para el recorte de líneas . Este algoritmo divide un espacio bidimensional en 9 regiones y luego determina de manera eficiente las líneas y porciones de líneas que son visibles en la región central de interés (la ventana gráfica ).
El algoritmo fue desarrollado en 1967 durante el trabajo de simulación de vuelo por Danny Cohen e Ivan Sutherland . [ 1 ]
El algoritmo
El algoritmo incluye, excluye o incluye parcialmente la línea en función de si:
- Ambos extremos están en la región de la ventana gráfica (OR bit a bit de los extremos = 0000): trivial accept .
- Ambos extremos comparten al menos una región no visible, lo que implica que la línea no cruza la región visible. (AND bit a bit de los extremos ≠ 0000): rechazo trivial .
- Ambos extremos se encuentran en regiones diferentes: en esta situación particular, el algoritmo encuentra uno de los dos puntos fuera de la región de visualización (siempre habrá al menos un punto fuera). A continuación, se calcula la intersección del punto fuera y el borde extendido de la región de visualización (es decir, con la ecuación paramétrica de la línea), y este nuevo punto reemplaza al punto fuera. El algoritmo se repite hasta que se produce una aceptación o un rechazo trivial.
Los números de la figura siguiente se denominan códigos de salida . Se calcula un código de salida para cada uno de los dos puntos de la línea. El código de salida tendrá 4 bits para el recorte bidimensional o 6 bits en el caso tridimensional. El primer bit se establece en 1 si el punto está por encima del área visible. Los bits del código de salida bidimensional representan: arriba, abajo, derecha e izquierda. Por ejemplo, el código de salida 1010 representa un punto situado en la esquina superior derecha del área visible.
Tenga en cuenta que los códigos de salida para los puntos finales deben recalcularse en cada iteración después de que se produzca el recorte.
El algoritmo de Cohen-Sutherland solo se puede utilizar en una ventana de recorte rectangular .
Ejemplo de implementación en C++
typedef int CódigoSalida ;const int INSIDE = 0b0000 ; const int LEFT = 0b0001 ; const int RIGHT = 0b0010 ; const int BOTTOM = 0b0100 ; const int TOP = 0b1000 ;// Calcula el código de bits para un punto (x, y) usando el rectángulo de recorte // delimitado diagonalmente por (xmin, ymin) y (xmax, ymax).// ASUMA QUE xmax, xmin, ymax e ymin son constantes globales.OutCode ComputeOutCode ( double x , double y ) { OutCode code = INSIDE ; // inicializado como estando dentro de la ventana de recorteif ( x < xmin ) // a la izquierda de la ventana de recorte code |= LEFT ; else if ( x > xmax ) // a la derecha de la ventana de recorte code |= RIGHT ; if ( y < ymin ) // debajo de la ventana de recorte code |= BOTTOM ; else if ( y > ymax ) // encima de la ventana de recorte code |= TOP ;código de retorno ; }// El algoritmo de recorte de Cohen-Sutherland recorta una línea desde // P0 = (x0, y0) hasta P1 = (x1, y1) contra un rectángulo con // diagonal desde (xmin, ymin) hasta (xmax, ymax). bool CohenSutherlandLineClip ( double & x0 , double & y0 , double & x1 , double & y1 ) { // calcula los códigos de salida para P0, P1 y cualquier punto que se encuentre fuera del rectángulo de recorte OutCode outcode0 = ComputeOutCode ( x0 , y0 ); OutCode outcode1 = ComputeOutCode ( x1 , y1 ); bool accept = false ;while ( true ) { if ( ! ( outcode0 | outcode1 )) { // OR bit a bit es 0: ambos puntos dentro de la ventana; trivialmente aceptar y salir del bucle accept = true ; break ; } else if ( outcode0 & outcode1 ) { // AND bit a bit no es 0: ambos puntos comparten una zona exterior (IZQUIERDA, DERECHA, SUPERIOR, // o INFERIOR), por lo que ambos deben estar fuera de la ventana; salir del bucle (accept es falso) break ; } else { // fallaron ambas pruebas, así que calcula el segmento de línea a recortar // desde un punto exterior hasta una intersección con el borde de recorte double x , y ;// Al menos un punto final está fuera del rectángulo de recorte; selecciónelo. OutCode outcodeOut = outcode1 > outcode0 ? outcode1 : outcode0 ;// Ahora encuentra el punto de intersección; // usa fórmulas: // pendiente = (y1 - y0) / (x1 - x0) // x = x0 + (1 / pendiente) * (ym - y0), donde ym es ymin o ymax // y = y0 + pendiente * (xm - x0), donde xm es xmin o xmax // No hay necesidad de preocuparse por la división por cero porque, en cada caso, el // bit outcode que se está probando garantiza que el denominador no sea cero if ( outcodeOut & TOP ) { // el punto está por encima de la ventana de recorte x = x0 + ( x1 - x0 ) * ( ymax - y0 ) / ( y1 - y0 ); y = ymax ; } else if ( outcodeOut & BOTTOM ) { // el punto está por debajo de la ventana de recorte x = x0 + ( x1 - x0 ) * ( ymin - y0 ) / ( y1 - y0 ); y = ymin ; } else if ( outcodeOut & RIGHT ) { // el punto está a la derecha de la ventana de recorte y = y0 + ( y1 - y0 ) * ( xmax - x0 ) / ( x1 - x0 ); x = xmax ; } else if ( outcodeOut & LEFT ) { // el punto está a la izquierda de la ventana de recorte y = y0 + ( y1 - y0 ) * ( xmin - x0 ) / ( x1 - x0 ); x = xmin ; }// Ahora movemos el punto exterior al punto de intersección para recortar // y nos preparamos para la siguiente pasada. if ( outcodeOut == outcode0 ) { x0 = x ; y0 = y ; outcode0 = ComputeOutCode ( x0 , y0 ); } else { x1 = x ; y1 = y ; outcode1 = ComputeOutCode ( x1 , y1 ); } } } return accept ; }Notas
- ↑ Principios de gráficos interactivos por computadora , págs. 124, 252, por Bob Sproull y William M. Newman, 1973, McGraw-Hill Education, edición internacional, ISBN 0-07-085535-8.
Véase también
Algoritmos utilizados para el mismo propósito:
Referencias
- James D. Foley. Gráficos por computadora: principios y práctica . Addison-Wesley Professional, 1996. pág. 113.
Enlaces externos
- Biblioteca JavaScript para el recorte de polilíneas mediante el algoritmo de Cohen-Sutherland.
- Implementación animada de JavaScript
- Implementación de Delphi
- Implementación de Stata
- Algoritmos de recorte de líneas