Vistas de página en total

Mostrando entradas con la etiqueta GRAFHICS. Mostrar todas las entradas
Mostrando entradas con la etiqueta GRAFHICS. Mostrar todas las entradas

miércoles, 2 de abril de 2014

RECTANGLE


Función para realizar rectangulos apoyandolnos en la función linea.

Macro DE LLAMADA para ampliar en GRAPHICS.MAC

GRAPHICS.MAC
;Dibuja un rectangulo
rectangle macro x0,y0,x1,y1,color
ifndef _rectangle
        extrn _rectangle:near
endif
        mov ax,x0
        push ax
        mov ax,y0
        push ax
        mov ax,x1
        push ax
        mov ax,y1
        push ax
        mov ax,color
        push ax
        call _rectangle
       
 endm 




RECTAN.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
include graphics.mac


.model compact,pascal

        public _rectangle
.data

.code
       ;algoritmo Bresenham
_rectangle proc uses ,x0,y0,x1,y1,color
        line x0,y0,x1,y0,color
        line x0,y1,x1,y1,color
        line x0,y0,x0,y1,color
        line x1,y0,x1,y1,color
        ret
_rectangle endp

end

domingo, 30 de marzo de 2014

EJEMPLO TRAZADO DE CIRCULOS

  Este programa es un ejemplo de ejecución de la librería gráfica de circulos.
   Lo más complejo de esta rutina es calcular el radio de la circunferencia a partir de dos puntos seleccionados en pantallas.
   Para ello, utilizo el teorema de pitágoras, y apoyándome en las funciones matemáticas puestas anteriormente calculo el radio.   Esto lo programé ya en la función puesta anterirometne dist_pixel.

   En este caso para que quede3 más elegante, el programa incrementa el color por cada circulo.

                       

     Se puede bajar el ejemplo compilado en el enlace





EJ_CIRCL.ASM

; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

include main.mac
include stdio.mac
include mouse.mac
include graphics.mac
include math.mac

.model compact,pascal
.stack 200

.data
x0 dw 100
y0 dw 100
x1 dw 90
y1 dw 90
radio dw 0,0

color dw 1

.code

principal proc far
        main
        modovideo 12h   ;inicia graficos
        resmouse         ;reinicia ratón
        mouse on         ; activa rarón
    
punto1:
        getmouse        ;espera  EST+ SIN PULSAR
        cmp ax,0
        jne punto1
pulsar1:      
        getmouse         ;verifica espera pulsación raton
        cmp ax,2      ;salir?
        jne sig1
        jmp fuera
sig1:      
        cmp ax,1      ;boton izquierdo?
        jne pulsar1
        getmousex
        mov x0,ax
        getmousey
        mov y0,ax
punto2:
        getmouse        ;espera soltar
        cmp ax,0
        jne punto2
pulsar2:     
        getmouse         ;verifica espera pulsación raton
        cmp ax,2      ;salir?
        jNe sg1
        JMP FUERA
SG1:      
        cmp ax,1      ;boton izquierdo?
        jne pulsar2
        getmousex
        mov x1,ax
        getmousey
        mov y1,ax
        dist_pixel x0,y0,x1,y1
     
        mov radio,ax

        mouse off
        mov ax,color        ;incremeta color en cada circulo
        inc ax
        and ax,0fh
        mov color,ax
      
        circle x0,y0,radio,color
        mouse on
      
        jmp punto1
fuera:
        modovideo t80col
        resmouse
        mouse off
        exit  0
principal endp

end

sábado, 22 de marzo de 2014

EJEMPLO TRAZADO LINEAS

   Para ir verificando que las funciones. Este es un pequeño programa que lee dos pulsaciones consecutivas del ratón, y toma las coordenadas de cada una de ellas, para trazar una recta que vaya desde el primer punto hasta el segundo.
    De esta forma podremos probar todas las posibilidades de la función recta, colocando en todas las posiciones y casos las rectas.
    Como solo es un ejemplo, no importa el color, y como en el resto de los ejemplos imprimo siemopre en color azul.


   El ejecutable podeis cargarlo directamente en  Ej_linea.exe 
   Recordad que está en gráficos de dos y necesitais en Windows7 hace falta un emulador de DOS como el DOSBOX, para ejecutarlo.


 EJ_LINEA.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.


 include main.mac
include stdio.mac
include mouse.mac
include graphics.mac

.model compact,pascal
.stack 200

.data
x0 dw 0
y0 dw 0
x1 dw 0
y1 dw 0

color dw 1

.code

principal proc far
        main
        modovideo 12h   ;inicia graficos
        resmouse         ;reinicia ratón
        mouse on         ; activa rarón
    
punto1:
        getmouse        ;espera  ESTÉ SIN PULSAR
        cmp ax,0
        jne punto1
pulsar1:      
        getmouse         ;verifica espera pulsación raton
        cmp ax,2      ;salir?
        jne sig1
        jmp fuera
sig1:      
        cmp ax,1      ;boton izquierdo?
        jne pulsar1
        getmousex
        mov x0,ax
        getmousey
        mov y0,ax
punto2:
        getmouse        ;espera soltar
        cmp ax,0
        jne punto2
pulsar2:     
        getmouse         ;verifica espera pulsación raton
        cmp ax,2      ;salir?
        je fuera
        cmp ax,1      ;boton izquierdo?
        jne pulsar2
        getmousex
        mov x1,ax
        getmousey
        mov y1,ax
             
      
        mouse off

      
        line x0,y0,x1,y1,color
        mouse on
        jmp punto1
fuera:
        modovideo t80col
        resmouse
        mouse off
        exit  0
principal endp

end





jueves, 20 de marzo de 2014

FUNCIÓN LINEA



Las dos funciones más importantes gráficas son: el circulo y la recta. A partir  de ellas podremos generar el resto de funciones.
   En las entradas anteriores he colocado la función básica de putpixel, para dibujar un punto, con la cual se podrán generar el resto de las funciones. En este caso he usado, por comodidad la Int 10h de la Bios., pero si alguien quiere puede hacer un putpixel directamente sobre memoria de pantalla. Esta modificación no influirá en el resto de las funciones ya que si se hace el putpixel de forma equivalente, el resto de las funciones seguirán siendo válidas.

    La recta es una función en principio compleja si la queremos hacer sin usar operaciones matemáticas complejas.
     Actualmente, debido a que los ordenadores son potentes, y se trabaja en alto nivel, a cualquiera que se le proponga hacer una recta mediante pixel, utilizará la ecuación de la recta y a correr. Pero si trabajamos en ensamblador, bien sea el que estamos usando, o sea un microcontrolador, de manera que deseemos trazar una línea en un papel mediante motores paso a paso, resulta problemático usar coma flotante.
     En 1965 Bresenham creó unos algoritmos de aproximación para la recta y los círculos, los cuales son capaces de trazar una recta usando solo operaciones incrementales y  operaciones básicas de  ensamblador como multiplica por 2 y sumar.
     Este es el algoritmo que he utilizado en esta función. Este algoritmo es válido solo si la pendiente es mayor de cero y menor de infinito. Es decir no sirve para rectas horizontales y verticales.
   Por lo tanto estos dos casos son tratados de forma independiente.
   Además hay que tratar el caso de trazar la recta en los dos sentidos, para lo cual lo que realizamos es una comprobación del sentido para poner los incrementos (pasox y pasoy) en +1 o -1 según convenga.
   Además el algoritmo solo sirve para un cuadrante, es decir no es lo mismo si la recta aumenta más deprisa en x que en y que si la recta aumenta más deprisa en y que en x. Por ello hay que verificar si Δx> Δy y tomar un algoritmo diferente.

   Como el algoritmo lo podréis encontrar en internet, pero nunca en ensamblador, he decidido hacer un ejercicio de interpretación muy elegante.
    Os he colocado como comentario a la derecha el código equivalente en “C”. Es decir he puesto el código en ensamblador, traduciéndolo a “C”. Esto servirá a muchos para entender el algoritmo, pero a muchos más, para saber cómo codificar en ensamblador  cada directiva de “C”.
    Esto que he hecho, para mi es super sencillo, porque yo comencé con desensamblar y luego pase a “C”, pero me imagino que para los programadores actuales, acostumbrados a lenguajes de alto nivel, es muy difícil hacerse una idea de cómo traducir el “C” a ensamblador.
    En este caso, yo he tomado el algoritmo en “C” y lo he traducido a ensamblador. Esto se puede hacer con cualquier pseudocódigo, por lo que esta entrada es una forma de enseñar este proceso.
   El conjunto de la librería estará formado por una macro, que deberá ser añadida a las cabeceras GRAPHICS.MAC,  que puse antes, y una función, que deberá ser compilada y añadida a la librería mediante TLIB. Así tendremos lista esta función para el futuro. Será usada como una instrucción más, y no tendremos que volver a compilarla, ni a preocuparnos de ella.
   Si se introduce, como yo hago, dentro de una librería, y siempre usamos esa librería, la función será transparente en  nuestras aplicaciones. Podéis ver cómo hacerlo en la pestaña COMPILAR del blog.
    Con esta función podremos realizar el rectangle y el fillrectangle, que pondré en la siguiente entrada.


    Más infornmación sobre el algoritmo  Aquí



GRAPHICS.MAC
;Dibuja una línea
line macro x0,y0,x1,y1,color
ifndef _line
        extrn _line:near
endif
        mov ax,x0
        push ax
        mov ax,y0
        push ax
        mov ax,x1
        push ax
        mov ax,y1
        push ax
        mov ax,color
        push ax
        call _line
       
 endm  





LINEA.ASM

; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.




include graphics.mac


.model compact,pascal

        public _line
.data


incE   dw 0
incNE dw 0


deltax dw 0    ;
deltay dw 0

pasox dw 0     ;paso en x
pasoy dw 0     ; paso en y

p dw 0     ;variable p procedimiento breshenham

x0 dw 0    ;parametros pasdados a linea
y0 dw 0    ;usado por todas las rutinas
x1 dw 0
y1 dw 0
color dw 0
.code
       ;algoritmo Bresenham
_line proc uses ax,px0,py0,px1,py1,pcolor
        ;paso de las variables de función a varialbes globales
        ;para uso en todas las rutinas
        mov ax,px0
        mov x0,ax
        mov ax,py0
        mov y0,ax
        mov ax,px1
        mov x1,ax
        mov ax,py1
        mov y1,ax
        mov ax,pcolor
        mov color,ax
       
       ;deltay=abs(yfinal-yinicial)
        mov ax,y1
        sub ax,y0               ; deltay=(y1-y0)
        jns  else_positivo1      ;if (deltay<0)
        neg ax                        ;{abx(deltay)
        mov pasoy,-1                  ;pasoy=-1
        jmp end_positivo1             ;}
else_positivo1:                  ;else
        mov pasoy,1                    ;pasoy=1
end_positivo1:
        mov deltay,ax           ; deltay=abs(y1-y0)
       
        ;deltax=abs(xfinal-xinicial)
        mov ax,x1
        sub ax,x0                ; deltax=(x1-x0)
        jns  elsepositivo2       ;if (deltax>0)
        neg ax                       ;{abx(deltax)
        mov pasox,-1                 ;pasox=-1
        jmp end_positivo2            ;}
elsepositivo2:                    ;else
        mov pasox,1                   ;pasox=1
end_positivo2:

        mov deltax,ax             ; deltax=abs(x1-x0)
        cmp ax,0                  ;if(deltax==0)
        jne no_vertical                  ;{
        call _linea_vertical      ;linea_vertical
        jmp fin_linea                        ;}
no_vertical:

        mov ax,deltay
        cmp ax,0                        ;if(deltay==0)
        jne no_horizontal                   ;{
        call _linea_Horizontal      ;linea_horizontal
        jmp fin_linea                      ;}
no_horizontal:
        
  ;resto de lineas mediante algoritmo Bresenham
        mov ax,deltax
        cmp ax,deltay                    ;if(deltax>deltay)
        jna alg2
        call _algoritmo1    ; algoritmo1
        jmp fin_linea
alg2:                                   ;else
        call _algoritmo2     ;algoritmo2
fin_linea:
        ret
_line endp

_linea_vertical proc uses ax bx cx dx
        mov bx,x0         ; x=x0
        mov dx,y0         ; y=y0
        mov cx,y1         ; yend=y1

while_vert:     
        cmp dx,cx               ;while (y!=yend)
        je fin_vert                  ;{
        putpixel bx,dx,color   ;pixel x,y
        add dx,pasoy                 ;y+=pasoy
        jmp while_vert
       
fin_vert:
        ret
_linea_vertical endp

_linea_horizontal proc uses ax bx cx dx
        mov bx,x0         ; x=x0
        mov dx,y0         ; y=y0
        mov cx,x1         ; xend=x1
      
while_hor:     
        cmp bx,cx               ;while (x!=xend)
        je fin_hor                  ;{
        putpixel bx,dx,color   ;pixel x,y
        add bx,pasox                 ;x+=pasox
        jmp while_hor
       
fin_hor:
        ret
_linea_horizontal endp


 ;si deltax>deltay
_algoritmo1 proc uses ax bx cx dx
        ;p=2*deltay-deltax
        mov ax,deltay         
        shl ax,1     
        mov incE,ax                 ;incE=2*deltay        
        sub ax,deltax          
        mov p,ax                    ;p=2*deltay-deltax 
         
        ;incNE=2*(deltay-deltax)
        mov ax, deltay
        sub ax,deltax
        shl ax,1
        mov incNE,ax                 ;incNE=2*(deltay-deltax)
         

        mov bx,x0         ; x=x0
        mov dx,y0         ; y=y0
        mov cx,x1         ; xend=x1

while1:     
        cmp bx,cx               ;while (x!=xend)
        je fin1                  ;{
        putpixel bx,dx,color   ;pixel x,y
        add bx,pasox                 ;x+=pasox
       
        mov ax,p
        cmp ax,0              ; if(p<0)
        jns else_if1
        add ax,incE
        mov p,ax              ;p+=incE
        jmp short end_if1
else_if1:                     ;else
        add ax,incNE
        mov p,ax             ;p+=incNE
        add dx,pasoy                ;y+=pasoy
end_if1:        
        jmp while1            ;}        
fin1:       
        ret
_algoritmo1 endp

;si deltay>deltax
 _algoritmo2 proc uses ax bx cx dx
        ;p=2*deltax-deltay
        mov ax,deltax         
        shl ax,1   
        mov incE,ax                 ;incE=2*deltay           
        sub ax,deltay          
        mov p,ax                    ;p=2*deltax-deltay 
        
        ;incNE=2*(deltax-deltay)
        mov ax, deltax
        sub ax,deltay
        shl ax,1
        mov incNE,ax                 ;incNE=2*(deltax-deltay)
         

        mov bx,x0         ; x=x0
        mov dx,y0         ; y=y0
        mov cx,y1         ; yend=y1
while2:         
        cmp dx,cx               ;while (y!=yend)
        je fin2                  ;{
        putpixel bx,dx,color   ;pixel x,y
        add dx,pasoy                ;y+=pasoy
       
        mov ax,p
        cmp ax,0              ; if(p<0)
        jns else_if2
        add ax,incE
        mov p,ax              ;p+=incE
        jmp short end_if2
else_if2:                     ;else
        add ax,incNE
        mov p,ax             ;p+=incNE
        add bx,pasox              ;x+=pasox 
end_if2:        
        jmp while2            ;}        
fin2:       
        ret
_algoritmo2 endp
end