Serie de algoritmos once: algoritmo de generación de círculos

 

Google

        En geometría analítica plana, la ecuación de un círculo se puede describir como (x - x 0 ) 2 + (y - y 0 ) 2 = R 2 , donde (x 0 , y 0 ) son las coordenadas del centro del círculo y R es el radio del círculo, especialmente , cuando (x 0 , y 0 ) es el punto central de las coordenadas, la ecuación del círculo se puede simplificar ax 2 + y 2 = R 2 . En los gráficos por computadora, los círculos, como las líneas rectas, también tienen el problema de mostrarse o emitirse en dispositivos de salida de matriz de puntos, por lo que también se necesita un conjunto de algoritmos de conversión de escaneo de trama. Para simplificar, primero consideramos la generación de un círculo cuyo centro está en el origen. Para un círculo cuyo centro no es el origen, el círculo en la posición correspondiente se puede obtener mediante la transformación traslacional de coordenadas.

        Antes de escanear la conversión, debe comprender las características de un círculo, es decir, el octavo par de círculos. Como se muestra en la Figura 1:

Figura (1) Octava simetría de un círculo

El círculo con el centro en el origen tiene cuatro ejes de simetría x = 0, y = 0, x = y y x = -y. Si se conoce un punto P (x, y) en el arco, se pueden obtener los siete alrededor de los cuatro ejes de simetría. Puntos de simetría: (x, -y), (-x, y), (-x, -y), (y, x), (y, -x), (-y, x), (-y, -x), esta propiedad se llama octava simetría. Por lo tanto, siempre que se pueda dibujar un octavo del arco, se puede obtener el círculo completo utilizando el principio de simetría.

Hay varias formas más fáciles de obtener la conversión de escaneo del círculo, primero introduzca el método de coordenadas rectangulares. Dada la ecuación del círculo: x 2 + y 2 = R 2 , si se toma x como la variable independiente y se resuelve y, obtenemos:

 

y =

 

Al generar un círculo, primero escanee y convierta un cuarto del círculo, deje que la variable independiente x aumente de 0 a R en pasos unitarios, y resuelva y en cada paso, y luego llame a la función de dibujo de puntos para dibujar el círculo punto por punto. Pero al hacerlo, debido a las operaciones de potencia y raíz cuadrada, y ambas son operaciones de punto flotante, la eficiencia del algoritmo no es alta. Y cuando x está cerca del valor de R (el centro del círculo está en el origen), cerca del punto (R, 0) de la circunferencia, debido a que la pendiente del círculo tiende a infinito, el número de punto flotante debe redondearse hacia arriba, haciendo que el círculo sea más grande. brecha. A continuación, introduzcamos el método de coordenadas polares. Suponiendo que el ángulo entre un punto P (x, y) y el eje x en el arco en el sistema de coordenadas rectangulares es θ, la ecuación de coordenadas polares del círculo es:

 

x = Rcosθ

y = Rsinθ

 

El círculo generado utiliza la octava simetría del círculo, de modo que el rango de valores de la variable independiente θ es (0, 45 °) para dibujar un círculo completo. Este método implica el cálculo de funciones trigonométricas y la multiplicación, lo que requiere una gran cantidad de cálculos. El método de coordenadas rectangulares y el método de coordenadas polares son algoritmos ineficaces, por lo que solo existen como métodos teóricos, estos dos métodos básicamente no se utilizan para generar círculos en gráficos por computadora. A continuación se presentan varios algoritmos prácticos de generación de círculos en gráficos por computadora.

1. Método del círculo de punto medio

        El primero es el método de dibujar un círculo en el punto medio. Considere el centro del círculo en el origen y el arco de un octavo del círculo con radio R en el primer cuadrante, que se determina en el sentido de las agujas del reloj desde el punto (0, R) al punto (R /, R /) Este arco. Suponga que un punto P I (X I , Y I ) tiene es un punto en el arco más cercano al arco real, entonces el siguiente punto Pi puede estar en uno de P1 o P2 justo a la derecha de la parte inferior derecha, como La figura (2) muestra:

Figura (2) Ejemplo del método de línea de puntos y trazos

Construya la función discriminante:

 

F (x, y) = x 2 + y 2 - R 2

 

Cuando F (x, y) = 0, significa que el punto está en el círculo. Cuando F (x, y)> 0, significa que el punto está fuera del círculo. Cuando F (x, y) <0, significa que el punto está dentro del círculo. Si M es el punto medio de P 1 y P 2 , entonces las coordenadas de M son (x i + 1, y i - 0.5). Cuando F (x i + 1, y i - 0.5) <0, el punto M está en el círculo En el interior, significa que P 1 está más cerca del arco real, y P 1 debe tomarse como el siguiente punto del círculo. Análisis De manera similar, cuando F. (X I +. 1, Y I - cuando 0.5)> 0, P 2 más cerca del arco real debe tomarse P 2 como el siguiente punto. Cuando F (x i + 1, y i - 0.5) = 0, tanto P 1 como P 2 pueden usarse como el siguiente punto del círculo, y el algoritmo acepta tomar P 2 como el siguiente punto.

现在将M点坐标(xi + 1, yi – 0.5)带入判别函数F(x, y),得到判别式d:

 

d = F(xi + 1, yi – 0.5)= (xi + 1)2 + (yi – 0.5)2 – R2

 

若d < 0,则取P1为下一个点,此时P1的下一个点的判别式为:

 

d’ = F(xi + 2, yi – 0.5)= (xi + 2)2 + (yi – 0.5)2 – R2

 

展开后将d带入可得到判别式的递推关系:

 

d’ = d + 2xi + 3

 

若d > 0,则取P2为下一个点,此时P2的下一个点的判别式为:

 

d’ = F(xi + 2, yi – 1.5)= (xi + 2)2 + (yi – 1.5)2 – R2

 

展开后将d带入可得到判别式的递推关系:

 

d’ = d + 2(xi - yi) + 5

 

特别的,在第一个象限的第一个点(0, R)时,可以推倒出判别式d的初始值d0

 

d0 = F(1, R – 0.5) = 1 – (R – 0.5)2 – R2 = 1.25 - R

 

根据上面的分析,可以写出中点画圆法的算法。考虑到圆心不在原点的情况,需要对计算出来的坐标进行了平移,下面就是通用的中点画圆法的源代码:

26 void MP_Circle(int xc , int yc , int r)

27 {

28     int x, y;

29     double d;

30 

31     x = 0;

32     y = r;

33     d = 1.25 - r;

34     CirclePlot(xc , yc , x , y);

35     while(x < y)

36     {

37         if(d < 0)

38         {

39             d = d + 2 * x + 3;

40         }

41         else

42         {

43             d = d + 2 * ( x - y ) + 5;

44             y--;

45         }

46         x++;

47         CirclePlot(xc , yc , x , y);

48     }

49 }

 参数xc和yc是圆心坐标,r是半径,CirclePlot()函数是参照圆的八分对称性完成八个点的位置计算的辅助函数。

2  改进的中点画圆法-Bresenham算法

        中点画圆法中,计算判别式d使用了浮点运算,影响了圆的生成效率。如果能将判别式规约到整数运算,则可以简化计算,提高效率。于是人们针对中点画圆法进行了多种改进,其中一种方式是将d的初始值由1.25 – R改成1 – R,考虑到圆的半径R总是大于2,因此这个修改不会响d的初始值的符号,同时可以避免浮点运算。还有一种方法是将d的计算放大两倍,同时将初始值改成3 – 2R,这样避免了浮点运算,乘二运算也可以用移位快速代替,采用3 – 2R为初始值的改进算法,又称为Bresenham算法:

52 void Bresenham_Circle(int xc , int yc , int r)

53 {

54     int x, y, d;

55 

56     x = 0;

57     y = r;

58     d = 3 - 2 * r;

59     CirclePlot(xc , yc , x , y);

60     while(x < y)

61     {

62         if(d < 0)

63         {

64             d = d + 4 * x + 6;

65         }

66         else

67         {

68             d = d + 4 * ( x - y ) + 10;

69             y--;

70         }

71         x++;

72         CirclePlot(xc , yc , x , y);

73     }

74 }

3、  正负判定画圆法

        除了中点画圆算法,还有一种画圆算法也是利用当前点产生的圆函数进行符号判别,利用负反馈调整以决定下一个点的产生来直接生成圆弧,就是正负法,下面就介绍一下正负法的算法实现。

        正负法根据圆函数:F(x, y)= x2 + y2 – R2的值,将平面区域分成圆内和圆外,如图(3)所示:

图(3)正负法判定示意图

假设圆弧的生成方向是从A到B方向,当某个点Pi被确定以后,Pi的下一个点Pi+1的取值就根据F(xi, yi)的值进行判定,判定的原则是:

 

1、当F(xi, yi)≤ 0时:取xi+1 = xi+1,yi+1 = yi。即向右走一步,从圆内走向圆外。对应图(3-a)中的从Pi到Pi+1

2、当F(xi, yi)> 0时:取xi+1 = xi,yi+1 = yi - 1。即向下走一步,从圆外走向圆内。对应图(3-b)中的从Pi到Pi+1

 

由于下一个点的取向到底是向圆内走还是向圆外走取决于F(xi, yi)的正负,因此称为正负法。对于判别式F(xi, yi)的递推公式,也要分两种情况分别推算:

 

1、当F(xi, yi)≤ 0时,Pi的下一个点Pi+1取xi+1 = xi+1,yi+1 = yi,判别式F(xi+1, yi+1)的推算过程是:

F(xi+1, yi+1)= F(xi+1,yi) = (xi+1)2+yi2-R2 = (xi2+yi2-R2)+2xi+1 = F(xi,yi)+2xi+1

 

2、当F(xi, yi)> 0时,Pi的下一个点Pi+1取xi+1 = xi,yi+1 = yi - 1,判别式F(xi+1, yi+1)的推算过程是:

F(xi+1, yi+1)= F(xi,yi-1) = xi2+(yi-1)2 - R2 = (xi2+yi2-R2) - 2yi + 1 = F(xi,yi) - 2yi+1

 

设画圆的初始点是(0,R),判定式的初始值是0,正负法生成圆的算法如下:

105 void Pnar_Circle(int xc, int yc, int r)

106 {

107     int x, y, f;

108 

109     x = 0;

110     y = r;

111     f = 0;

112     while(x <= y)

113     {

114         CirclePlot(xc, yc, x, y);

115         if(f <= 0)

116         {

117             f = f + 2 * x + 1;

118             x++;

119         }

120         else

121         {

122             f = f - 2 * y + 1;

123             y--;

124         }

125     }

126 }

        改进的中点划线算法和正负法虽然都避免了浮点运算,并且计算判别式时用到的乘法都是乘2运算,可以用移位代替,但是实际效率缺有很大差别。因为正负法并不是严格按照x方向步进的,因此就会出现在某个点的下一个点在两个位置上重复画点的问题,增加了不必要的计算。此外,从生成圆的质量看,中点画圆法和改进的中点画圆法都比正负法效果好。

4、  快速画圆法

        除了中点画圆法和正负法,本文再介绍一种圆的光栅扫描算法,就是快速画圆法。快速画圆法的生成效果和中点画圆法差不多,但是判别式的计算只用了加减法,没有用任何乘法,因此被成为快速画圆法。我找不到快速画圆法的理论依据,只是把算法的实现写出来,供有兴趣的读者参考。以下就是快速画圆法的实现算法:

128 void Fast_Circle(int xc , int yc , int r)

129 {

130     int x, y, d;

131 

132     x = 0;

133     y = r;

134     d = -r / 2;

135     CirclePlot(xc , yc , x , y);

136     if(r % 2 == 0)

137     {

138         while(x < y)

139         {

140             x++;

141             if(d < 0)

142                 d += x;

143             else

144             {

145                 y--;

146                 d += x - y;

147             }

148 

149             CirclePlot(xc , yc , x , y);

150         }

151     }

152     else

153     {

154         while(x < y)

155         {

156             x++;

157             if(d < 0)

158               d += x + 1;

159             else

160             {

161               y--;

162               d += x - y + 1;

163             }

164 

165             CirclePlot(xc , yc , x , y);

166         }

167     }

168 }

        Hay muchos algoritmos de conversión de barrido de ráster redondo. Los presentados en este artículo son simples y fáciles de entender. Además de los diversos métodos presentados en este artículo, también hay muchos algoritmos de conversión de ráster redondo, como los algoritmos de aproximación de polígono. Los lectores pueden consultar los gráficos por computadora para estudiar la realización del algoritmo.

 

 

 

 

 

Materiales de referencia:

 

[1] Geometría computacional: diseño y análisis de algoritmos Zhou Peide, Tsinghua University Press, 2005

[2] Geometría computacional: algoritmos y aplicaciones De Berger (traducido por Deng Junhui) Tsinghua University Press, 2005

[3] Gráficos por computadora Sun Jiaguang, Yang Changgui, Prensa de la Universidad de Tsinghua, 1995

 

 

 

Supongo que te gusta

Origin blog.csdn.net/orbit/article/details/7253285
Recomendado
Clasificación