Apagada docs

Aprendiendo a programar el pasado

Herramientas de usuario

Herramientas del sitio


es:basic:qbasic:ying_yang

Ying Yang dibujado a través de ecuaciones matemáticas

Puesto que en ensamblador no se dispone de primitivas para trazar círculos, necesitaba investigar cómo trazarlos usando otras funciones. Desde bachillerato sabía que la ecuación del círculo viene a ser r^2=(sen(a)^2+cos(a)^2), (dado que la hipotenusa al cuadrado es igual que la suma de los cuadrados de los catetos). Si conocer el ángulo es innecesario, solo tenemos que comprobar si las coordenadas de un punto están dentro de la suma de los cuadrados de los catetos.

El primer programa es el prototipo QBASIC del programa CSEMBL que aparece a continuación.

DEFINT A-Z
DECLARE FUNCTION insideyingyang% (x%, y%)
'Intento de dibujar el yin/yang mediante cálculo de ra¡z cuadrada.
'Programación: 9/10/95
'Cambio de colores y de sentido (arr-dch>arr-izq,etc): 10/10/95
'El yinyang de la bandera de Corea del Sur es:
'Azul (Arriba-izq),rojo (Abajo-dch), blanco (fondo).
 
pxmin = 100
pxmax = 539
pymin = 100
pymax = 379
centrox = pxmin + (pxmax - pxmin) / 2
centroy = pymin + (pymax - pymin) / 2
 
radio1 = 100 'radio1 del s¡mbolo
radio2 = radio1 / 2 'radio1 de los subc¡rculos
radio3 = 10 'radio1 de los c¡rculos conc‚ntricos a ‚stos.
subcentrox = centrox - radio1 / 2
subcentroy = centroy
fondo = 15
ying = 1
yang = 4
SCREEN 12
FOR f = pymin TO pymax
    FOR g = pxmin TO pxmax
        IF (f < centroy - radio1) THEN
            PSET (g, f), fondo
        ELSE
            IF (f > centroy + radio1) THEN
                PSET (g, f), fondo
            ELSE
                IF (g < centrox - radio1) THEN
                    PSET (g, f), fondo
                ELSE
                    IF (g > centrox + radio1) THEN
                        PSET (g, f), fondo
                    ELSE
 
                        PSET (g, f), insideyingyang(g, f)
                    END IF
                END IF
            END IF
        END IF
    NEXT
NEXT
 
'Devuelve el color para un punto dentro de un ying-yang.
FUNCTION insideyingyang (x, y)
SHARED ying, yang, fondo
SHARED centrox, centroy, radio1
SHARED subcentrox, subcentroy, radio2, radio3
cx = x - centrox
cy = y - centroy
IF (cx * cx) + (cy * cy) > (radio1 * radio1) THEN insideyingyang = fondo: EXIT FUNCTION
insideyingyang = 3
colory = 1
cx2 = ABS(subcentrox - x)
cy2 = ABS(subcentroy - y)
IF cx > 0 THEN cx2 = ABS(subcentrox + radio1 - x)
'Cambiando el mayor_o_igual de ahí abajo por menor_o_igual,
'cambia arriba_dch,abajo_izq por abajo_dch,arriba_izq y viceversa.
'El original necesita un "<=".
IF cx <= 0 THEN colory = -colory
IF (cx2 * cx2 + cy2 * cy2) > radio2 * radio2 THEN colory = SGN(cy)
IF (cx2 * cx2 + cy2 * cy2) < radio3 * radio3 THEN colory = -colory
IF colory = -1 THEN insideyingyang = ying ELSE insideyingyang = yang
END FUNCTION

Esta es la implementación del programa anterior en CSEMBLER:

;Dibujar yinyang. Usa el método pitag¢rico.
;Idea y programa Basic: 9/10/95
;Fin de la implementación CSM: 10/10/95
;NO ES UN PROGRAMA ASSEMBLER, ES PARA CUTRESSEMBLER.
;pxmin=100
mov wo [%pxmin%], 64
;pxmax=539
mov wo [%pxmax%], 21b
;pymin=100
mov wo [%pymin%], 64
;pymax=379
mov wo [%pymax%], 17b
mov ax,[%pxmax%]
sub ax,[%pxmin%]
shr ax,1
add ax,[%pxmin%]
mov [%centrox%],ax
mov ax,[%pymax%]
sub ax,[%pymin%]
shr ax,1
add ax,[%pymin%]
mov [%centroy%],ax
;radio1=100
mov ax,64
mov [%radio1%],ax
shr ax,1
mov [%radio2%],ax
mov wo [%radio3%],a
mov bx,[%centrox%]
;ax contiene radio1/2
sub bx,ax
mov [%subcentrox%],bx
mov bx,[%centroy%]
mov [%subcentroy%],bx
mov by [%fondo%],F
mov by [%yin%],1
mov by [%yang%],4
;Inicializar pantalla
mov ax,12
int 10
 
mov ax,[%pymin%]
mov [%f%],ax
:for_f
 
mov ax,[%pxmin%]
mov [%g%],ax
:for_g
 
 
mov ax,[%centroy%]
sub ax,[%radio1%]
cmp [%f%],ax
jl %dibujafondo%
mov ax,[%centroy%]
add ax,[%radio1%]
cmp [%f%],ax
jg %dibujafondo%
mov ax,[%centrox%]
sub ax,[%radio1%]
cmp [%g%],ax
jl %dibujafondo%
mov ax,[%centrox%]
add ax,[%radio1%]
cmp [%g%],ax
jg %dibujafondo%
mov ax,[%g%]
mov [%x%],ax
mov ax,[%f%]
mov [%y%],ax
call %insideyinyang%
:vuelta
;antes de llegar aquí hay que poner color en AL.
mov cx,[%g%]
mov dx,[%f%]
mov ah,0C
xor bx,bx
int 10
 
;next_g
inc wo [%g%]
mov ax,[%g%]
cmp ax,[%pxmax%]
jle %for_g%
;next_f
inc wo [%f%]
mov ax,[%f%]
cmp ax,[%pymax%]
jle %for_f%
 
mov ax,0
int 16
mov ax,3
int 10
int 20
:dibujafondo
mov al,[%fondo%]
jmp %vuelta%
 
:insideyinyang
;cx=x-centrox:
mov ax,[%x%]
sub ax,[%centrox%] 
mov [%cx%],ax
mov ax,[%y%]
;cy=x-centroy:
sub ax,[%centroy%]
mov [%cy%],ax
;cy*cy+cx*cx...
mul ax
mov bx,ax
mov ax,[%cx%]
mul ax
add bx,ax
mov ax,[%radio1%]
mul ax
cmp bx,ax
jle %inside_sigue%
;si cy*cy+cx*cx>radio1*radio1:
mov al,[%fondo%]
ret
:inside_sigue
mov wo [%colory%],1
;cx2=abs(subcentrox-x):
mov ax,[%subcentrox%]
sub ax,[%x%]
cmp ax,0
jge %inside_xge0%
neg ax
:inside_xge0
mov [%cx2%],ax
;cy2=abs(subcentroy-y):
mov ax,[%subcentroy%]
sub ax,[%y%]
cmp ax,0
jge %inside_yge0%
neg ax
:inside_yge0
mov [%cy2%],ax
;IF cx > 0 THEN cx2 = ABS(subcentrox + radio1 - x)
cmp wo [%cx%],0
jle %inside_cxle0%
mov ax,[%subcentrox%]
add ax,[%radio1%]
sub ax,[%x%]
mov [%cx2%],ax
cmp ax,0
jge %inside_cxle0%
neg wo [%cx2%]
:inside_cxle0
;Cambiando el signo de lo siguiente se cambia
;la dirección del ying y el yang (izq-arr,dch-aba>izq-aba,dch-arr).
;IF cx <= 0 THEN colory = -colory
cmp wo [%cx%],0
jg %inside_cxl0%
neg wo [%colory%]
:inside_cxl0
;IF (cx2 * cx2 + cy2 * cy2) > radio2 * radio2 THEN colory = SGN(cy)
mov ax,[%cx2%]
mul ax
mov bx,ax
mov ax,[%cy2%]
mul ax
add bx,ax
mov ax,[%radio2%]
mul ax
mov cx,ax
cmp bx,cx
jle %IFCIRC2%
cmp wo [%cy%],0
jge %sgnisge0%
mov wo [%colory%],ffff
jmp %IFCIRC2%
:sgnisge0
mov wo [%colory%],1
:IFCIRC2
;IF (cx2 * cx2 + cy2 * cy2) < radio3 * radio3 THEN colory = -colory
;bx ha de ser cx2^2+cy2^2
mov ax,[%radio3%]
mul ax
mov cx,ax
cmp bx,cx
jge %finif2%
neg wo [%colory%]
:finif2
mov al,[%yin%]
cmp wo [%colory%],ffff
jz %inside_ret%
mov al,[%yang%]
:inside_ret
ret
 
;db "________PXMIN="
:pxmin
dw 0
;db "________PXMAX="
:pxmax
dw 0
;db "________PYMIN="
:pymin
dw 0
;db "________PYMAX="
:pymax
dw 0
;db "______CENTROX="
:centrox
dw 0
;db "______CENTROY="
:centroy
dw 0
;db "_______RADIO1="
:radio1
dw 0
;db "_______RADIO2="
:radio2
dw 0
;db "_______RADIO3="
:radio3
dw 0 
;db "___SUBCENTROX="
:subcentrox
dw 0
;db "___SUBCENTROY="
:subcentroy
dw 0
;db "_________FONDO="
:fondo
db 1
;db "___________YIN="
:yin
db 0
;db "__________YANG="
:yang
db F
;db "____________F="
:f
dw 0
;db "____________G="
:g
dw 0
;db "____________X="
:x
dw 0
;db "____________Y="
:y
dw 0
;db "___________CX="
:cx
dw 0
;db "___________CY="
:cy
dw 0
;db "__________CX2="
:cx2
dw 0
;db "___________CY="
:cy2
dw 0
;db "_______COLORY="
:colory
dw 0
db "YINYANG, programado en CSEMBL. 10-10-1995"

Este listado, por último, genera el mismo patrón en modo texto:

;Dibujar yinyang. Usa el método pitagórico.
;Idea y programa Basic: 9/10/95
;Fin de la implementación CSM_GRAFICOS: 10/10/95
;IMPLEMENTACIÓN TEXTO:
;NO ES UN PROGRAMA ASSEMBLER, ES PARA CUTRESSEMBLER.
mov wo [%pxmin%], 8
mov wo [%pxmax%], 48
mov wo [%pymin%], 4
mov wo [%pymax%], 2a
mov ax,[%pxmax%]
sub ax,[%pxmin%]
shr ax,1
add ax,[%pxmin%]
mov [%centrox%],ax
mov ax,[%pymax%]
sub ax,[%pymin%]
shr ax,1
add ax,[%pymin%]
mov [%centroy%],ax
mov ax,12
mov [%radio1%],ax
shr ax,1
mov [%radio2%],ax
mov wo [%radio3%],2
mov bx,[%centrox%]
;ax contiene radio1/2
sub bx,ax
mov [%subcentrox%],bx
mov bx,[%centroy%]
mov [%subcentroy%],bx
mov by [%fondo%],F
mov by [%yin%],1
mov by [%yang%],4
;Inicializar pantalla
mov ax,3
int 10
mov ax,[%pymin%]
mov [%f%],ax
:for_f
 
mov ax,[%pxmin%]
mov [%g%],ax
:for_g
 
 
mov ax,[%centroy%]
sub ax,[%radio1%]
cmp [%f%],ax
jl %dibujafondo%
mov ax,[%centroy%]
add ax,[%radio1%]
cmp [%f%],ax
jg %dibujafondo%
mov ax,[%centrox%]
sub ax,[%radio1%]
cmp [%g%],ax
jl %dibujafondo%
mov ax,[%centrox%]
add ax,[%radio1%]
cmp [%g%],ax
jg %dibujafondo%
mov ax,[%g%]
mov [%x%],ax
mov ax,[%f%]
mov [%y%],ax
call %insideyinyang%
:vuelta
;antes de llegar aqu¡ hay que poner color en AL.
call %puntotexto%
;next_g
inc wo [%g%]
mov ax,[%g%]
cmp ax,[%pxmax%]
jle %for_g%
;next_f
inc wo [%f%]
mov ax,[%f%]
cmp ax,[%pymax%]
jle %for_f%
 
mov ax,0
int 16
;mov ax,3
;int 10
int 20
:dibujafondo
mov al,[%fondo%]
jmp %vuelta%
 
:insideyinyang
;cx=x-centrox:
mov ax,[%x%]
sub ax,[%centrox%] 
mov [%cx%],ax
mov ax,[%y%]
;cy=x-centroy:
sub ax,[%centroy%]
mov [%cy%],ax
;cy*cy+cx*cx...
mul ax
mov bx,ax
mov ax,[%cx%]
mul ax
add bx,ax
mov ax,[%radio1%]
mul ax
cmp bx,ax
jle %inside_sigue%
;si cy*cy+cx*cx>radio1*radio1:
mov al,[%fondo%]
ret
:inside_sigue
mov wo [%colory%],1
;cx2=abs(subcentrox-x):
mov ax,[%subcentrox%]
sub ax,[%x%]
cmp ax,0
jge %inside_xge0%
neg ax
:inside_xge0
mov [%cx2%],ax
;cy2=abs(subcentroy-y):
mov ax,[%subcentroy%]
sub ax,[%y%]
cmp ax,0
jge %inside_yge0%
neg ax
:inside_yge0
mov [%cy2%],ax
;IF cx > 0 THEN cx2 = ABS(subcentrox + radio1 - x)
cmp wo [%cx%],0
jle %inside_cxle0%
mov ax,[%subcentrox%]
add ax,[%radio1%]
sub ax,[%x%]
mov [%cx2%],ax
cmp ax,0
jge %inside_cxle0%
neg wo [%cx2%]
:inside_cxle0
;Cambiando el signo de lo siguiente se cambia
;la direccion del ying y el yang (izq-arr,dch-aba>izq-aba,dch-arr).
;IF cx <= 0 THEN colory = -colory
cmp wo [%cx%],0
jg %inside_cxl0%
neg wo [%colory%]
:inside_cxl0
;IF (cx2 * cx2 + cy2 * cy2) > radio2 * radio2 THEN colory = SGN(cy)
mov ax,[%cx2%]
mul ax
mov bx,ax
mov ax,[%cy2%]
mul ax
add bx,ax
mov ax,[%radio2%]
mul ax
mov cx,ax
cmp bx,cx
jle %IFCIRC2%
cmp wo [%cy%],0
jge %sgnisge0%
mov wo [%colory%],ffff
jmp %IFCIRC2%
:sgnisge0
mov wo [%colory%],1
:IFCIRC2
;IF (cx2 * cx2 + cy2 * cy2) < radio3 * radio3 THEN colory = -colory
;bx ha de ser cx2^2+cy2^2
mov ax,[%radio3%]
mul ax
mov cx,ax
cmp bx,cx
jge %finif2%
neg wo [%colory%]
:finif2
mov al,[%yin%]
cmp wo [%colory%],ffff
jz %inside_ret%
mov al,[%yang%]
:inside_ret
ret
 
:puntotexto
push es
push ax
mov bx,b800
mov es,bx
mov ax,[%f%]
push ax
;nos va a interesar luego saber si f (y) es par o impar
shr ax,1
mov cx,50
mul cx
add ax,[%g%]
shl ax,1
mov bx,ax
pop cx
and cl,1
shl cl,1
shl cl,1
;borra el atributo que se va a cambiar.
;de otra manera es complicado cambiar solo un atributo.
mov ah,F0
rol ah,cl
mov al,0
es:
and [bx],ax
pop ax
;ahora suma el carácter y la parte nueva del atributo a la  parte
;del atributo que no ha cambiado.
rol al,cl
:dfh=1/2cuadro sup.
mov ah,df
xchg al,ah
es:
or [bx],ax
pop es
ret
 
;db "________PXMIN="
:pxmin
dw 0
;db "________PXMAX="
:pxmax
dw 0
;db "________PYMIN="
:pymin
dw 0
;db "________PYMAX="
:pymax
dw 0
;db "______CENTROX="
:centrox
dw 0
;db "______CENTROY="
:centroy
dw 0
;db "_______RADIO1="
:radio1
dw 0
;db "_______RADIO2="
:radio2
dw 0
;db "_______RADIO3="
:radio3
dw 0 
;db "___SUBCENTROX="
:subcentrox
dw 0
;db "___SUBCENTROY="
:subcentroy
dw 0
;db "_________FONDO="
:fondo
db 1
;db "___________YIN="
:yin
db 0
;db "__________YANG="
:yang
db F
;db "____________F="
:f
dw 0
;db "____________G="
:g
dw 0
;db "____________X="
:x
dw 0
;db "____________Y="
:y
dw 0
;db "___________CX="
:cx
dw 0
;db "___________CY="
:cy
dw 0
;db "__________CX2="
:cx2
dw 0
;db "___________CY="
:cy2
dw 0
;db "_______COLORY="
:colory
dw 0
db "YINYANG, programado en CSEMBL. 10-10-1995"
Este sitio web utiliza cookies. Al utilizar el sitio web, usted acepta almacenar cookies en su computadora. También reconoce que ha leído y entendido nuestra Política de privacidad. Si no está de acuerdo abandone el sitio web.Más información
es/basic/qbasic/ying_yang.txt · Última modificación: 2014/03/02 12:11 por nepenthes