circulos y lineas en c=64 y msx.
Moderador: CEZ
-
alex
- 16 bits

- Mensajes: 128
- Registrado: 08 Abr 2008 09:50
circulos y lineas en c=64 y msx.
Me gustaría saber como se hacen circulos y lineas en commodore 64 y en msx.
- mcleod_ideafix
- 16 bits

- Mensajes: 85
- Registrado: 05 Mar 2008 19:46
- Ubicación: Sevilla
- Contactar:
Re: circulos y lineas en c=64 y msx.
Si sabes dibujar puntos en cualquier coordenada X,Y, entonces puedes dibujar líneas y círculos.
Independientemente de que la ROM de estos micros ya lleve una rutina que los haga (habría que consultar la documentación técnica en ambos casos), para las líneas se usa el algoritmo de Bresenham (creo que se escribe así). A continuación tienes una implementación en un BASIC muy sencillo, que seguro podrás portar a ensamblador o cualquier otro dialecto BASIC. Viene del ZX81:
Para dibujar círculos hay varias técnicas: unas aproximan un círculo mediante un polígono regular de muchos lados. A mi se me ocurrió este algoritmo, que dibuja círculos muy rápidamente, incluso aunque se necesitan multiplicaciones en algunos sitios (no sé si tiene un nombre o si ya estaba inventado de antes...).
Se basa, primero en la simetría que muestra una circunferencia en los 4 ejes principales (horizontal, vertical, diagonal, diagonal inversa). Así, sólo es necesario calcular los puntos de la circunferencia entre los angulos 0 y 45 grados. Para ello nos servimos de la ecuación de la circunferencia: x^2+y^2=r^2.
Para una circunferencia de radio R, que supondremos centrada en el origen, comenzamos calculando puntos de la circunferencia a partir del punto (R,0), es decir, X=R, Y=0. Como estamos subiendo desde el angulo 0 al 45, sabemos que el siguiente punto tendrá como coordenada Y'=1, pero no sabemos a ciencia cierta cuál es su coordenada X'. Lo que está claro es que sólo puede haber dos posibilidades para esa coordenada: que X'=X o que X'=X-1. Así, para estas dos posibilidades se calcula la expresión: V=X'^2+Y^2 y se escoge aquella X' que haga |V-R^2| mínima.
Para las nuevas coordenadas X',Y' se dibujan 8 puntos, aprovechándose de la simetría de la circunferencia. El bucle acaba cuando Y>X, ya que cuando eso ocurre, el ángulo ha llegado a 45 grados.
Te paso la versión en C que escribí para el Spectrum:
Independientemente de que la ROM de estos micros ya lleve una rutina que los haga (habría que consultar la documentación técnica en ambos casos), para las líneas se usa el algoritmo de Bresenham (creo que se escribe así). A continuación tienes una implementación en un BASIC muy sencillo, que seguro podrás portar a ensamblador o cualquier otro dialecto BASIC. Viene del ZX81:
Código: Seleccionar todo
THE LINE-DRAWING SUBROUTINE
This subroutine is called by DRAW to draw an approximation to a straight line from the point X0, Y0
held in COORDS to the point X0+X, Y0+Y, where the increments X and Y are on the top of the calculator stack.
The subroutine was originally intended for the ZX80 and ZX81 8K ROM, and it is described in a BASIC program
on page 121 of the ZX81 manual. It is also illustrated here in the Circle program in the appendix.
The method is to intersperse as many horizontal or vertical steps as are needed among a basic set of diagonal steps,
using an algorithm that spaces the horizontal or vertical steps as evenly as possible.
DRAW (A,B)-(C,D)
1000 LET U=C-A
1005 REM U SHOWS HOW MANY STEPS ALONG WE NEED TO GO
1010 LET V=D-B
1015 REM V SHOWS HOW MANY STEPS UP
1020 LET D1X=SGN U
1030 LET D1Y=SGN V
1035 REM (D1X,D1Y) IS A SINGLE STEP IN A DIAGONAL DIRECTION
1040 LET D2X=SGN U
1050 LET D2Y=0
1055 REM (D2X,D2Y) IS A SINGLE STEP LEFT OR RIGHT
1060 LET M=ABS U
1070 LET N=ABS V
1080 IF M>N THEN GOTO 1130
1090 LET D2X=0
1100 LET D2Y=SGN V
1105 REM NOW (D2X,D2Y) IS A SINGLE STEP UP OR DOWN
1110 LET M=ABS V
1120 LET N=ABS U
1130 REM M IS THE LARGER OF ABS U & ABS V, N IS THE SMALLER
1140 LET S=INT (M/2)
1145 REM WE WANT TO MOVE FROM (A,B) TO (C,D) IN M STEPS USING N UP- DOWN OR RIGHT-LEFT STEPS D2, & M-N DIAGONAL STEPS D1, DISTRIBUTED AS EVENLY AS POSSIBLE
1150 FOR I=0 TO M
1160 PLOT A,B <--- aqui debes usar tu propia versión para pintar píxeles
1170 LET S=S+N
1180 IF S<M THEN GOTO 1230
1190 LET S=S-M
1200 LET A=A+D1X
1210 LET B=B+D1Y
1215 REM A DIAGONAL STEP
1220 GOTO 1250
1230 LET A=A+D2X
1240 LET B=B+D2Y
1245 REM AN UP-DOWN OR RIGHT-LEFT STEP
1250 NEXT I
1260 RETURNSe basa, primero en la simetría que muestra una circunferencia en los 4 ejes principales (horizontal, vertical, diagonal, diagonal inversa). Así, sólo es necesario calcular los puntos de la circunferencia entre los angulos 0 y 45 grados. Para ello nos servimos de la ecuación de la circunferencia: x^2+y^2=r^2.
Para una circunferencia de radio R, que supondremos centrada en el origen, comenzamos calculando puntos de la circunferencia a partir del punto (R,0), es decir, X=R, Y=0. Como estamos subiendo desde el angulo 0 al 45, sabemos que el siguiente punto tendrá como coordenada Y'=1, pero no sabemos a ciencia cierta cuál es su coordenada X'. Lo que está claro es que sólo puede haber dos posibilidades para esa coordenada: que X'=X o que X'=X-1. Así, para estas dos posibilidades se calcula la expresión: V=X'^2+Y^2 y se escoge aquella X' que haga |V-R^2| mínima.
Para las nuevas coordenadas X',Y' se dibujan 8 puntos, aprovechándose de la simetría de la circunferencia. El bucle acaba cuando Y>X, ya que cuando eso ocurre, el ángulo ha llegado a 45 grados.
Te paso la versión en C que escribí para el Spectrum:
Código: Seleccionar todo
void circle (BYTE xc, BYTE yc, BYTE r)
{
BYTE x,y;
int norma,norma1,norma2;
x=xc+r;
y=yc;
norma=r*r;
plot(x,y);
plot(2*xc-x,y);
plot(x,2*yc-y);
plot(2*xc-x,2*yc-y);
plot(xc+(y-yc),yc+(x-xc));
plot(xc-(y-yc),yc+(x-xc));
plot(xc+(y-yc),yc-(x-xc));
plot(xc-(y-yc),yc-(x-xc));
while (abs(x-xc)>=abs(y-yc))
{
y--;
norma1=(x-xc)*(x-xc)+(y-yc)*(y-yc);
norma2=(x-1-xc)*(x-1-xc)+(y-yc)*(y-yc);
if (abs(norma-norma2)<abs(norma-norma1))
x--;
plot(x,y);
plot(2*xc-x,y);
plot(x,2*yc-y);
plot(2*xc-x,2*yc-y);
plot(xc+(y-yc),yc+(x-xc));
plot(xc-(y-yc),yc+(x-xc));
plot(xc+(y-yc),yc-(x-xc));
plot(xc-(y-yc),yc-(x-xc));
}
}No hay virginidad que aguante tres martinis.


- Guillian
- 32 bits

- Mensajes: 626
- Registrado: 02 Ene 2005 02:40
Re: circulos y lineas en c=64 y msx.
En MSX puedes usar desde el BASIC:
CIRCLE(x,y),radio,color
y
LINE(x1,y1)-(x2,y2),color
Por ejemplo:
10 screen 2
20 circle(128,106),50,15
30 line(0,0)-(255,211),8
40 A$=input$(1)
CIRCLE(x,y),radio,color
y
LINE(x1,y1)-(x2,y2),color
Por ejemplo:
10 screen 2
20 circle(128,106),50,15
30 line(0,0)-(255,211),8
40 A$=input$(1)
-
alex
- 16 bits

- Mensajes: 128
- Registrado: 08 Abr 2008 09:50
Re: circulos y lineas en c=64 y msx.
Muchas gracias por las explicaciones tan detalladas.
Un saludo.
Un saludo.