Sei sulla pagina 1di 51

Primitivas - Rendering

• INTRODUCCION
• PRIMITIVAS GRAFICAS
• ESPECIFICACION DE UNA
DISCRETIZACION
• DIBUJO DE LINEAS RECTAS
• ALGORITMOS PARA CIRCULOS
Introducción
• En los sistemas raster, las imágenes vienen definidas por la intensidad de sus
pixels
Introducción
• Los objetos presentes en la imagen se componen de primitivas simples (líneas,
puntos)
• El sistema gráfico dibuja estas primitivas transformándolos en pixels ->
Rasterización

• Los métodos de conversión deben ser lo más eficientes posible


• La primitiva “Punto” es la más sencilla:
– Se coloca la intensidad deseada en la celda de memoria del frame buffer
correspondiente
– Cuando el haz de electrones pase por esa línea horizontal (scan-line), emitirá al
pasar por esa posición
Introducción
• A partir de este punto, se hará uso del modelo de dispositivo de raster.
• Para conseguir independencia de dispositivo, entonces, es necesario
adoptar un conjunto de primitivas y establecer una serie de métodos que
permitan representar dichas primitivas en nuestro dispositivo de raster
satisfaciendo un conjunto de especificaciones.
• Convertir la imagen real a la imagen en la pantalla se denomina
discretizacion.
Primitivas Graficas
• Es muy difícil escoger un conjunto de primitivas graficas que sea
adecuado para la presentación de todo tipo de entidades graficas. Sin
embargo, el siguiente subconjunto en la practica resulta suficiente:

• Puntos.- Se especifican a partir de su localización y color.


• Segmentos de recta.- Son esenciales para la mayor parte de las
entidades. Se especifican a partir de un par de puntos que representan
sus extremos.
• Circunferencias.- En algunos casos representar entidades curvadas con
segmentos poligonales puede ser inadecuado o costoso, por lo que en la
practica las circunferencias o círculos se adoptan como primitivas. Se
especifican con la posición de su centro y su radio.
• Polígonos.- Son indispensables para representar entidades sólidas. Se
representan a partir de una secuencia de puntos que determina la
poligonal de su perímetro.
Especificación de una discretizacion
• Al elegir un método de discretizacion de una primitiva grafica, es
indispensable contar con criterios que permitan evaluar y comparar las
ventajas y desventajas de las distintas alternativas. Entre todas las
especificaciones posibles, podemos mencionar las siguientes:

• Apariencia.- Normalmente se espera que un segmento de recta tenga


una “apariencia recta”, tampoco debe tener discontinuidades o puntos
espureos, debe pasar por el primer y ultimo puntos del segmento.
• Simetría e invariancia geométrica.- Debe producir resultados
equivalentes si se modifican algunas propiedades geométricas de la
primitiva. Ejemplo no debe variar si dicho segmento se traslada o si es
rotado, etc.
• Simplicidad y velocidad de computo.- Los métodos tienden a no
depender de estructuras complejas y a ser directamente implementadas
en hardware especifico de baja complejidad
Dibujo de líneas rectas
• Para dibujar líneas rectas, habrá que calcular las posiciones intermedias entre
los dos extremos
• Este problema no existía en las pantallas vectoriales o plotters
• Sin embargo, las posiciones de los pixels son valores enteros, y los puntos
obtenidos de la ecuación son reales -> existe un error (aliasing)
• A menor resolución, mayor es el efecto

• Es necesario disponer de métodos para convertir primitivas en pixels de la


forma más eficiente posible.
Dibujo de líneas rectas
Consideraciones para el dibujo de rectas:
• Hay que calcular las coordenadas de los pixels que estén lo más cerca posible
de una línea recta ideal, infinitamente delgada, superpuesta sobre la matriz de
pixels.
• Las consideraciones que un buen algoritmo debe cumplir son:
– La secuencia de pixels debe ser lo más recta posible
– Las líneas deben dibujarse con el mismo grosor e intensidad independientemente de
su inclinación
– Las líneas deben dibujarse lo más rápido posible
El algoritmo más sencillo
• La ecuación de una recta es y = mx + b
– m es la pendiente
– b es el corte con el eje y

• No es muy eficiente
• Cada paso requiere una multiplicación
flotante, una suma y un redondeo
Función usando la ecuación
void Ecuacion(int x0, int y0, int x1, int y1)
{
int dx=x1-x0,dy=y1-y0;
putpixel(x0,y0,BLUE);
float m=(float)dy/dx;
float b= y0-m*x0;
if(dx<0) dx=-1 else dx=1;
while(x0 != x1)
{
x0 +=dx;
y0=ceil(m*x0+b);
putpixel(x0,y0,BLUE);
}
}
Función mejorada
void Ecuacion(int x0, int y0, int x1, int y1)
{
int dx=x1-x0,dy=y1-y0;
putpixel(x0,y0,BLUE);
else
if(abs(dx)>abs(dy))
{
{
float m=(float)dx/dy;
float m=(float)dy/dx;
float b= x0-m*y0;
float b= y0-m*x0;
if(dy<0) dy=-1 else dy=1;
if(dx<0) dx=-1 else dx=1;
while(y0 != y1)
while(x0 != x1)
{
{
y0 +=dy;
x0 +=dx;
x0=ceil(m*y0+b);
y0=ceil(m*x0+b);
putpixel(x0,y0,BLUE);
putpixel(x0,y0,BLUE);
}
}
}
}
}
Algoritmo Básico Incremental DDA
• Podemos eliminar la multiplicación de la siguiente manera:
– Sabemos que
yi = mxi + b
– Entonces el siguiente valor sera:
yi+1 = mxi+1 + b
– Reemplazando el valor xi+1= xi +x se tiene:
yi+1=m(xi +x)+ b
– Multiplicando y reemplazando :
yi+1= mxi + b + mx
yi+1= yi + mx
– Como Δx =1, llegamos a la fórmula final

yi+1 = yi + m
• Cada pixel se calcula en función del anterior
• No hace falta calcular b
DDA donde m<1
Funcion Linea_DDA(int x0, y0, x1, y1)
inicio
dx = x1-x0
dy = y1- y0
m =(float) dy/dx
m <1, los pasos son a y = y0
largo de ‘x’. Para x=x0 hasta x1 hacer
Pintar Pixel(x,y)
x=x+1
y=y+m
Fin para
fin
Algoritmo Básico Incremental DDA
Si m>1 falla, pues quedan huecos, como se muestra
Solución:
Intercambiamos las variables x e y, sabemos que:
xi = (1/m) (yi – b)

Entonces hallamos el siguiente valor:


xi+1 = (1/m)( yi+1 – b)
Reemplazando yi+1 =yi +Δy se tiene
xi+1 = (1/m) (yi +Δy– b)
Multiplicando y reemplazando:
xi+1 = (1/m) (yi – b) + Δy/m
xi+1 = xi + Δy/m
Como Δy=1, llegamos a la fórmula final

xi+1 = xi + 1/m
DDA donde m>1
Funcion Linea_DDA(int x0, y0, x1, y1)
inicio
dx = x1-x0
dy = y1- y0
m >1, los pasos no son m = (float)dy/dx
en x. Para manejar esto, x = x0
cambiar ‘x’ por ‘y’. Para y=y0 hasta y1 hacer
Pintar Pixel(x,y)
x=x+1/m
y=y+1
Fin para
fin
Algoritmo Básico Incremental DDA
Funcion Linea_DDA(int x0, y0, x1, y1)
inicio
dx = x1-x0
dy = y1- y0
Si abs(dx) > abs(dy) entonces steps = abs(dx)
• Inconvenientes:
sino steps = abs(dy) – Existen errores de
xinc =dx / steps acumulación
yinc =dy / steps – El redondeo es muy lento
x = x0
y = y0
para k=1 hasta steps hacer
Pintar Pixel(x,y)
x=x+xinc
y=y+yinc
fin para
fin
Funcion para lineas con DDA
void Dda(int x0, int y0, int x1, int y1)
{
float x, y, xs, ys;
int dx, dy, steps;
dx = x1 - x0; dy = y1 - y0;
x = x0; y = y0;
if (abs(dx) > abs(dy)) steps = abs(dx); else steps = abs(dy);
if (steps == 0) {
putpixel( x, y,BLUE);
return;
}
xs = dx/steps; ys = dy/steps;
for (i = 0; i <= steps; i++)
{
putpixel( x, y,BLUE);
x = x + xs; y = y + ys;
}
}
Algoritmo de Bresenham
• Sólo usa aritmética entera
• Supongamos el caso 0 < m < 1 hay que decidir
qué pixel dibujamos a continuación, y
¡ sólo hay dos candidatos !

• El algoritmo debe decidir cuál de los dos pintar


• Partamos del pixel (xk, yk), y hay que decidir
entre el pixel (xk+1, yk) o (xk+1, yk+1)
• Para ello calculemos la distancia vertical entre el centro de cada pixel
y la línea real
Algoritmo de Bresenham
• La diferencia entre ambas constantes nos ayudará a decidir qué pixel
pintar
d1 – d2 = m (xk + 1) + b – yk –yk+1 + m (xk + 1) + b
d1 – d2 = 2m (xk + 1) +2 b – yk –yk -1
d1 – d2 = 2m (xk + 1) – 2yk + 2b – 1
• Multiplicando por Δx eliminamos el parámetro m, que no es entero

– pk = Δx (d1 – d2)= Δx (2 (Δy / Δx) (xk + 1) - 2 yk + 2 b - 1)


pk = 2 Δy xk - 2 Δx yk + 2 Δy + 2 b Δx - Δx
pk = 2 Δy xk - 2 Δx yk + c

donde C = 2 Δy + Δx (2b – 1)
Algoritmo de Bresenham
• Como Δx > 0, el signo de pk coincide con el de la diferencia (d1 – d2), y por
tanto:
Si pk > 0  d1 > d2
hay que pintar el pixel (xk+1, yk+1)

Si pk < 0  d1 < d2
hay que pintar el pixel (xk+1, yk)
Algoritmo de Bresenham
• La gran ventaja es que puede calcularse pk+1 a partir del anterior
pk = 2 Δy xk - 2 Δx yk + c
utilizando solamente ¡aritmética entera!.
• En el paso k + 1, el parámetro de decisión se evalúa con base en la ecuación
anterior como
pk+1 = 2 Δy xk+1 - 2 Δx yk+1 + c
• Al sustraer la ecuación de la anterior pk obtenemos
pk+1 - pk = 2 Δy xk+1 - 2 Δx yk+1 + c-2 Δy xk + 2 Δx yk - c
pk+1 - pk = 2 Δy (xk+1 - xk) - 2 Δx( yk+1 - yk)

• Pero xk+1 = xk + 1, de manera que

pk+1 = pk + 2 Δy – 2 Δx (yk+1 – yk)


• Donde el termino (yk+1 – yk) es 0 o 1, dependiendo del signo del
parámetro pk.
Algoritmo de Bresenham
• Si pk > 0  d1 > d2
hay que pintar el pixel (xk+1, yk+1) entonces yk+1 = yk +1:
pk+1 = pk + 2 Δy – 2 Δx (yk +1– yk)
pk+1 = pk + 2 Δy – 2 Δx

• Si pk < 0  d1 < d2
hay que pintar el pixel (xk+1, yk) encontes yk+1 = yk
pk+1 = pk + 2 Δy – 2 Δx (yk – yk)
pk+1 = pk + 2 Δy
Algoritmo de Bresenham
•El primer parámetro p0 se evalúa a partir de la ecuación pk
pk = Δx (2 (Δy / Δx) (xk + 1) - 2 yk + 2 b - 1)
en la posición (x0,y0),
sustituyendo con b = y0 - m x0 y
m = Δy / Δx.
p0 = Δx (2( Δy / Δx)(x0 + 1) - 2 y0 + 2 (y0 - (Δy / Δx) x0) - 1)
p0 = 2 Δy x0 + 2 Δy - 2 Δx y0 + 2 Δx y0 - 2 Δy x0 - Δx
•donde se obtiene la siguiente ecuación:

p0 = 2 Δy - Δx
Algoritmo de Bresenham

• Si m > 1, intercambiamos
las variables x e y
• Si m < 0, el cambio es
similar
Algoritmo de Bresenham
void Bresenham(int x0, int y0, int x1, int y1)
{
if(dx>dy){ else{
int x, y, dx, dy, p;
p = 2*dy - dx; p = 2*dx - dy;
int incE, incNE, stepx, stepy; incE = 2*dy; incE = 2*dx;
dx = (x1 - x0); dy = (y1 - y0); incNE = 2*(dy-dx); incNE = 2*(dx-dy);
if (dy < 0) while (x != x1){ while (y != y1){
{ x = x + stepx; y = y + stepy;
if (p < 0){ if (p < 0){
dy = -dy; stepy = -1;
p = p + incE; p = p + incE;
} else stepy = 1; } }
if (dx < 0) else { else {
{ y = y + stepy; x = x + stepx;
dx = -dx; stepx = -1; p = p + incNE; p = p + incNE;
} }
} else stepx = 1;
putpixel( x, y,BLUE); putpixel( x, y,BLUE);
x = x0; y = y0; } }
putpixel( x0, y0,BLUE); } }
}
Algoritmo del Punto Medio
• Bresenham, J.E. "Algorithm for Computer Control of a Digital Plotter". IBM
Systems Journal, 4(1), 1965, 25-30.
• Usa aritmética entera
• Supone la pendiente (m) en el rango [0, 1]
• Parte del punto inferior-izquierdo al punto superior-derecho
Algoritmo del Punto Medio
• Segmento de recta desde (x0, y0) a (xf, yf)
(x, y) : centro de un pixel
• y + e : valor exacto de la ordenada de la recta
• e : error (distancia) a la ordenada del pixel; e [-0.5, 0.5]
• m : pendiente de la recta
Algoritmo del Punto Medio
Qué pixel pintar (x+1, y) o (x+1, y+1) ?
Si y + e + m < y + 0.5 entonces se dibuja (x+1, y)
Para (x+1, y), el nuevo valor de ‘e’ será:
e = (y + e + m) – y
e = e+m

Si y + e + m >= y + 0.5 entonces se dibuja (x+1, y+1)


Para (x+1, y+1), el nuevo valor de ‘e’ será:
e = (y + e + m) – (y +1)
e = e + m -1
Algoritmo del Punto Medio
Seudo Algoritmo :
incio
e=0
y = y1
para x = x1 hasta x2
setPixel(x, y)
si e + m < 0.5 La pendiente (m) es un valor no entero!!
e=e+m
sino
y=y+1
e = e + m –1
fin si
fin para
fin
Algoritmo del Punto Medio
• Dado que m = dx / dy, entonces
e + m < 0.5
e + dy / dx < 0.5 / multiplicando por 2 * dx
2 * dx * e + 2 * dy < dx
• Sustituyendo e * dx por e’, el test pasa a ser:
2(e’ + dy) < dx
• Para la actualización del error tenemos:
ee+m
ee+m-1
• multiplicando por dx:
e * dx  e * dx + dy
e * dx  e * dx + dy - dx
• y sustituyendo e * dx por e’ :
e’  e’ + dy
e’  e’ + dy - dx
Algoritmo del Punto Medio
Seudo Algoritmo:
inicio
e’ = 0
y = y1
para x = x1 hasta x2
setPixel(x, y)
si 2(e’ + dy) < dx
Sólo valores enteros
e’ = e’ + dy
sino
y=y+1
e’ = e’ + dy –dx
fin si
fin para
fin
Algoritmo de Punto Medio
void PuntoMedio(int x0, int y0, int x1, int y1)
{
if(dx>dy){ else{
int x, y, dx, dy, p;
p = 0; p = 0;
int incE, incNE, stepx, stepy; incE = dy; incE = dx;
dx = (x1 - x0); dy = (y1 - y0); incNE =(dy-dx); incNE = (dx-dy);
if (dy < 0) while (x != x1){ while (y != y1){
{ x = x + stepx; y = y + stepy;
if (2*(p+dy) < dx){ if (2*(p+dx) < dy){
dy = -dy; stepy = -1;
p = p + incE; p = p + incE;
} else stepy = 1; } }
if (dx < 0) else { else {
{ y = y + stepy; x = x + stepx;
dx = -dx; stepx = -1; p = p + incNE; p = p + incNE;
} }
} else stepx = 1;
putpixel( x, y,BLUE); putpixel( x, y,BLUE);
x = x0; y = y0; } }
putpixel( x0, y0,BLUE); } }
}
ALGORITMOS BASICOS PARA
CIRCULOS EN 2D
Una circunferencia se define como un conjunto de puntos que se
encuentran, en su totalidad, a una distancia r de una posición
central (xc, yc).

Esta relación de distancia se expresa por medio del teorema de


Pitagoras en coordenadas cartesianas como:

(x - xc)2 + (y - yc) 2 = r2
Algoritmo básico
Círculo en el origen: X 2 + Y 2 = R 2

Se podría calcular para los puntos de


una circunferencia a lo largo del eje x
en pasos unitarios los valores
correspondientes de y en cada posición
como:
Algoritmo básico
• METODO INEFICIENTE
– Se resuelve sólo 1/4 de círculo (SIMETRIA!!)
– X se incrementa en 1 por cada paso
– Y se obtiene de la ecuación del círculo:

– Operaciones en Punto Flotante implicadas!!


– Contorno con brechas (X cercano a R)
– Dibujo de la circunferencia con huecos
Coordenadas Polares
• Otra manera de eliminar el espacio irregular consiste en calcular los
puntos a lo largo de la frontera circular utilizando las coordenadas
polares r y q.
• Al expresar la ecuación de la circunferencia en forma polar
parametrica, se obtiene el par de ecuaciones
X = R COS q
Y = R SEN q
Donde: q varía entre 0º y 90º
• No hay vacíos o brechas
• Ineficiente, por cálculos de Cos y Sen
• Para una frontera mas continua, se puede establecer el tamaño de paso
como 1/r. Esto hace que se tracen posiciones de pixel que están
aproximadamente una unidad aparte.
Simetría de 8 Lados
• Consideración para ahorrar
cálculos:
• Aprovechar las simetrías de la
circunferencia. Por cada punto
hallado se pueden ubicar siete mas.
• En este caso la circunferencia está
centrada en el origen, pero si no
fuera así, basta con restarle a (x,y)
las coordenadas del centro de la
circunferencia, aplicar las simetrías
y a los siete puntos sumarles las
coordenadas del centro
nuevamente.
Simetría de 8 Lados
• Sólo un segmento de 45 º se requiere para obtener el círculo completo
procedure SIMETRIA(X,Y:integer);
begin
write_pixel(X,Y);
write_pixel(Y,X);
write_pixel(Y,-X);
write_pixel(X,-Y);
write_pixel(-X,-Y);
write_pixel(-Y,-X);
write_pixel(-Y,X);
write_pixel(-X,Y);
end;
Algoritmo del Punto Medio
• Bresenham (1977) desarrollo un P=(xp,yp) E
generador incremental que genera
todos los puntos en un circulo.
M ME

>0
• El algoritmo de Bresenham evita los SE
cálculos de raíces cuadradas. MSE =0
<0
• Utiliza un parámetro de decisión para
determinar cual de las dos posiciones
Píxel Opciones Opciones
posibles de y esta mas próxima a la
anterior para Píxel para Píxel
actual siguiente
trayectoria de la circunferencia.

• Las posiciones de los otros siete


octantes se obtiene por simetría.
Algoritmo del Punto Medio
• Hay que determinar el píxel más cercano a la circunferencia
• Consideremos el centro del círculo en (0,0)
• Comenzaremos en el punto (0,R) e iremos desde x=0 hasta x=y, donde la
pendiente va de 0 a -1
• Sólo pintaremos el primer octante

• Sea la función:

• Este test lo ejecutaremos en los puntos medios entre los píxel que hay que
decidir
Algoritmo del Punto Medio
Mecanismo de elección del píxel a pintar:
• Uso de P (referencia)

• Si P esta dentro del circulo,


Píxel a la derecha

•Si P esta fuera del circulo,


Píxel a la derecha y abajo.

Coordenadas de P ??
Algoritmo del Punto Medio
• Supongamos ya dibujado el píxel (xk, yk)
pk = f (xk+1, yk – ½) = (xk+1)2 + (yk – ½) 2 – R2

• La gran ventaja es que puede calcularse pk+1 a partir


del anterior pk. En el paso k + 1, el parámetro de
decisión se evalúa con base en la ecuación anterior
como
pk+1 = f (xk+1 + 1, yk+1 – ½) = (xk+1 + 1) 2 + (yk+1 – ½) 2 – R2
• Al sustraer la ecuación de la anterior pk obtenemos
pk+1 - pk = (xk+1 + 1) 2 + (yk+1 – ½) 2 – R2 - (xk+1)2 - (yk – ½) 2 + R2
pk+1 - pk = xk+12+2 xk+1+12- (xk+1)2 +(yk+12 -2½yk+1+ ½2) - (yk2–2½yk+½ 2)
pk+1 - pk = 2 xk+1+1 +yk+12 -yk+1- yk2+yk
• Reordenando obtenemos
pk+1 = pk + 2xk+1 + 1 + (y k+12–yk2) – (yk+1–yk)

Donde: yk+1 es yk ó yk-1 dependiendo del signo de pk


Algoritmo del Punto Medio
Si pk < 0  hay que
pintar el pixel (xk+1, yk)  yk+1 = yk
reemplazando en pk+1 se tiene
pk+1 = pk + 2xk+1 + 1 + (y k2–yk2) – (yk–yk)
pk+1 = pk + 2xk+1 + 1
pk+1 = pk + 2xk+ 3

Si pk > 0  hay que


pintar el pixel (xk+1, yk-1)  yk+1 = yk -1
reemplazando en pk+1 se tiene
pk+1 = pk + 2xk+1 + 1 + (( y k–1 ) 2–yk2) – (yk–1–yk)
pk+1 = pk + 2xk+1 + 1 + (yk2–2yk+1 –yk2) – (yk–1–yk)
pk+1 = pk + 2xk+1 –2yk+3
pk+1 = pk + 2xk –2yk+5
Algoritmo del Punto Medio
• Empezamos en el punto (0, R).
• ¿Cuánto vale p0?
p0 = f (1, R- ½) = 12+ (R- ½) 2 -R2
p0 = 12+ R2 -2R ½ - ½ 2 -R2
p0 = 5/4 – R  no es entero!
• Sin embargo, da igual. Podemos redondearlo, porque todos los incrementos son
enteros, y sólo queremos utilizar el signo de pk, y no su valor
Algoritmo del Punto Medio
Algoritmo del Punto Medio
void CircleMidPoint(int xc, int yc, int r) Void Point( int xc, int yc, int x, int y)
{ {
int x, y, p;
Point(xc + x,yc + y);
x = 0;
y = r; Point(xc - x,yc + y);
p = 1 - r; Point(xc + x,yc - y);
PlotPoint(xc,yc,x,y); Point(xc - x,yc - y);
/* se cicla hasta trazar todo un octante */ Point(xc + y,yc + x);
while (x < y)
Point(xc - y,yc + x);
{
x = x + 1; Point(xc + y,yc - x);
if (p < 0) Point(,xc - y,yc - x);
p = p + 2*x + 3; }
else {
y = y - 1;
p = p + 2*(x - y) + 5;
}
PlotPoint(xc,yc,x,y);
}
}
ALGORITMOS PARA ELIPSES
• Expresado de forma ambigua, una elipse es una circunferencia alargada.
• Una elipse se define como el conjunto de puntos en que la suma de las
distancias desde dos posiciones fijas (focos) sea la misma para todos los puntos.

• Si las distancias de los dos focos desde cualquier punto P=(x,y) en la elipse se
representan como d1 y d2, entonces la ecuación general de una elipse puede
expresarse como
d1 + d2 = constante
ALGORITMO BASICO
• Las ecuaciones de la elipse se simplifican, en gran medida, si se orientan los
ejes mayor y menor para alinearse con los ejes de las coordenadas, como se
muestra en la siguiente figura.

• El parámetro rx por convención designa el eje mayor y el parámetro ry designa


el eje menor.
• La ecuación de la elipse puede expresarse en termino de las coordenadas del
centro de la elipse y los parámetros rx y ry, como
ALGORITMO BASICO
• Al utilizar las coordenadas polares r y q, también es posible describir la elipse
en posición estándar con las ecuaciones parametricas:
x = xc + rx cos ß
y = yc + ry sin ß
• Se puede aplicar consideraciones sobre la simetría para reducir aun mas los
cálculos.
• Una elipse en posición estándar es simétrica entre cuadrantes, no es simétrica
entre los dos octantes. De este modo que al calcular una posición de un píxel
obtenemos por simetría las tres posiciones de los otros tres cuadrantes.
Algoritmo del punto Medio
• El planteamiento que se utiliza aquí es similar a aquel empleado en el despliegue
de una circunferencia.
• Dado los parámetros rx, ry, (xc, yc), se determina los puntos (x, y) para una elipse
en posición estándar centrada en el origen y luego se altera los puntos, de modo
que la elipse este centrada en (xc, yc).
• El método de punto medio para elipse se aplica a lo largo del primer cuadrante en
dos partes, de acuerdo a una elipse con la pendiente rx < ry, como se muestra a
continuación.
Algoritmo del punto Medio
void melipse(int xc,int yc,int rx,int ry, int color){ void puntose(int xc,int yc,int x,int y, int c){
long double rx2 = rx * rx, ry2 = ry * ry; putpixel(xc+x,yc+y,c);
long double tworx2 = 2*rx2, twory2 = 2*ry2; putpixel(xc-x,yc+y,c);
long double p, x = 0, y = ry; putpixel(xc+x,yc-y,c);
putpixel(xc-x,yc-y,c);
long double px = 0, py = tworx2 * y;
}
puntose(xc,yc,x,y,color);
//region 1
//region 2
p=ceill( ry2 - ( rx2 * ry ) + ( 0.25 * rx2 ) );
p = ceill(ry2 * ( x+.5 ) * ( x+.5 ) + rx2
while(px<py){ * ( y-1 ) * ( y-1 ) - rx2 * ry2);
x++; while(y>0){
px+=twory2; y--;
if( p < 0 ) p += ry2 + px; py-= tworx2 ;
if(p>0) p+= rx2-py ;
else{ y--;
else{ x++;
py-= tworx2 ; px+= twory2;
p += ry2 + px - py; p+= rx2-py+px;
} }
puntose(xc,yc,x,y,color); puntose(xc,yc,x,y,color);
}
}
}

Potrebbero piacerti anche