CPC Rulez
https://cpcrulez.fr/forum/

Mandelbrot en 1 ligne
https://cpcrulez.fr/forum/viewtopic.php?f=4&t=4622
Page 1 sur 1

Auteur :  Demoniak [ 06 Sep 2011, 10:35 ]
Sujet du message :  Mandelbrot en 1 ligne

Bon ça n'est pas du Z80, mais du basic.
Juste pour le fun (encore une fois ;-) ), une version qui tient en une seule ligne de basic :
Code :
10 MODE 0:e=-1.3:FOR y%=0 TO 199:d=-2.4:FOR x%=0 TO 159:z=0:i=0:a%=0:WHILE a%<15 AND (z*z+i*i)<4:s=(z*z)-(i*i)+d:r=(2*i*z)+e:z=s:i=r:a%=a%+1:WEND:PLOT x%*4,y%*2,a%:d=d+0.0215:NEXT:e=e+0.013:NEXT

Attention, c'est très lent...

Auteur :  Ghost [ 06 Sep 2011, 10:38 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Et en ASM ??? La seule démo proposant un calcul fractal (très lent) en ASM est une part de la 5kb demo 3 (roudoudou avait fait plus rapide en basic^^)...

J'ai toujours adoré les fractals mais vu que je suis nul en maths je n'y ai jamais rien compris...

Auteur :  Demoniak [ 06 Sep 2011, 10:50 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Le problème c'est que ça se fait en nombre "réels".
J'ai aussi une version avec des entiers, mais sur 32 bits (sinon la précision est insuffisante, et le résultat est inexploitable), donc pas directement transposable sur un Z80, même avec ses registres 16 bits.

Je vais quand même tenter la conversion en assembleur pour voir :-)

Auteur :  Ghost [ 06 Sep 2011, 11:18 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Peut être un autre Fractal tel Julia (c'est quasi pareil je crois niveau algo) ou un machin en forme de fougère est-il plus faisable ?

Auteur :  krusty [ 06 Sep 2011, 12:24 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Demoniak a écrit :
J'ai aussi une version avec des entiers, mais sur 32 bits (sinon la précision est insuffisante, et le résultat est inexploitable), donc pas directement transposable sur un Z80, même avec ses registres 16 bits.

(J'ai pas eu le courage de retaper le basic, je nvois pas c'est quoi le visuel du fractal.)

Quand tu dit que le résultat n'est pas exploitable, c'est quoi le soucis?
Tu as tellement d'erreurs de calcul que le résultat ne ressemble pas à un fractal ?
Ou ca te limite dans la zone que tu peux choisir à afficher ?


J'ai déjà fait un mandelbrot sur CPC en asm (sur 16bits, sauf surement pendant une multiplication) en utilisant la même zone que la 5kb3 que Ghost cite.
J'avais clairement des pb de précision de calcul, mais ça n'a pas réellement affecté la forme du mandelbrot.
Naturellement, c'était plus rapide que dans la 45kb, mais je ne calculais pas tous les pixels non plus ...

Ca me surprend un peu qu'une version BASIC (sans astuces de cow boy) soit plus rapide. Surout à cause de tous les appels lents aux routines systeme pour calculer et afficher.

Auteur :  Demoniak [ 06 Sep 2011, 12:43 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

krusty a écrit :
Quand tu dit que le résultat n'est pas exploitable, c'est quoi le soucis?
Tu as tellement d'erreurs de calcul que le résultat ne ressemble pas à un fractal ?
Ou ca te limite dans la zone que tu peux choisir à afficher ?

ça me limite la zone à afficher, et il y a quand même quelques petits problèmes d'affichage.
Je vais essayer quand même de retranscrire ça en assembleur Z80 pour voir le résultat

Auteur :  Kris [ 06 Sep 2011, 16:13 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Ouh la, ça rame dur c'est clair, le Z80 doit chauffer à bloc là :)
Sympa d'avoir casé tout ça en 1 ligne de basic, j'attend la version assembleur pour voir la différence.

Aller je joins le .DSK (collé sur "food for my Plus du proprietaire des lieux :) )

Auteur :  tatayoyode [ 06 Sep 2011, 17:07 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Salut,
Sympa ce thread.
A ce sujet, il y a un joli article trouvé ici et qui m'a bien plu... Je vous le fais donc partager :
http://www.siteduzero.com/tutoriel-3-344309-dessiner-la-fractale-de-mandelbrot.html
Il y a justement des explications concernant le "zonage/bornage" et "zoom" d'une fractale sous forme de pseudo-code et php (pratique pour tester...)
Vite fait et adapté en basic ça me donne un truc comme ça :
Code :
10 MODE 0
20 x1%=-2.1 
30 x2%=0.6 
40 y1%=-1.2 
50 y2%=1.2   
60 zoom=100
70 itmax%=15
80 dimgx%=(x2%-x1%)*zoom
90 dimgy%=(y2%-y1%)*zoom
100 FOR y%=0 TO dimgy%                   
110 FOR x%=0 TO dimgx%
120 cr=x%/zoom+x1%       
130 ci=y%/zoom+y1% 
140 zr=0
150 zi=0
160 i%=0   
170 WHILE i%<itmax% AND (zr*zr+zi*zi)<4   
180 tmp=zr:zr=(zr*zr-zi*zi)+cr:zi=(2*zi*tmp)+ci:i%=i%+1     
190 WEND
210 PLOT x%*4,y%*2,i%
220 NEXT:NEXT

Bien évidemment en testant, c'est lent et pas optimisé...
C'est moins lent sous winape en mode turbo ou en rajoutant des "step" en lignes 100 et 110 et aussi en changeant les coeff multiplicateurs en ligne 210 pour de l'à peut-prêt visuel...
Enfin, et si j'ai bien tout compris (pas sûr... je vieillis...) en jouant sur les variables (x1%, x2%, y1% et y2%) du repère comprenant la forme mandelbrot couplé à la variable zoom on arrive à obtenir des zones précises.
Une version z80 "ultra optimisée comme un ouf" du truc serait marrante pour voir côté vitesse ce que ça donne... et surtout selon les zones...
Bref... En attendant, merci, m'ennuyant à mourir tout ça m'a bien occupé cet après-midi :-)
Bisous.
Tronic/GPA.

Auteur :  Demoniak [ 12 Sep 2011, 10:05 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Version assembleur pas optimisée du tout, utilisant des flottants et les routines du firmware du 6128 (attention, les adresses sont différentes sur 464 et 664 il me semble).
Code :
GRA_SET_PEN     EQU     #BBDE
GRA_PLOT_ABS    EQU     #BBEA
SCR_SET_MODE    EQU     #BC0E

INT_TO_REAL     EQU     #BD64
REAL_TO_INT     EQU     #BD6A
REAL_ADD        EQU     #BD7C
REAL_SUB        EQU     #BD82
REAL_MUL        EQU     #BD85
REAL_DIV        EQU     #BD88
REAL_CP         EQU     #BD8E

        ORG     #A000
        run     $

        XOR     A
        LD      (Y+1),A
        CALL    SCR_SET_MODE
        LD      HL,const_e
        LD      DE,var_e
        CALL    COPYREAL                ; e = -1.3
Y:
        LD      A,0
        LD      HL,const_d
        LD      DE,var_d
        CALL    COPYREAL                ; d = -2.4
        XOR     A
        LD      (X+1),A
X:
        LD      A,0
        LD      HL,const_0
        LD      DE,var_z
        CALL    COPYREAL                ; z = 0
        LD      HL,const_0
        LD      DE,var_i
        CALL    COPYREAL                ; i = 0
        XOR     A
        LD      (BclWhile+1),A
BclWhile:
        LD      A,0
        CP      15
        JP      NC,FinWhile
        LD      HL,var_z
        LD      DE,var_z2
        CALL    COPYREAL                ; z2 = z
        LD      DE,var_Z
        CALL    REAL_MUL                ; z2 = z * z

        LD      HL,var_i
        LD      DE,var_i2
        CALL    COPYREAL                ; i2 = i
        LD      DE,var_i
        CALL    REAL_MUL                ; i2 = i * i

        LD      HL,var_i2
        LD      DE,var_tmp
        CALL    COPYREAL                ; tmp = i * i
        LD      DE,var_z2
        CALL    REAL_ADD                ; tmp = i * i + z * z

        LD      HL,var_tmp
        LD      DE,const_4
        CALL    REAL_CP                 ; comparer tmp avec 4

        AND     #80                     ; A=#FF si hl<de, A=0 si hl==de, A=1 si hl>de
        JR      Z,FinWhile              ; si hl>=de, on a fini

        LD      HL,var_i2
        LD      DE,var_s
        CALL    COPYREAL                ; s = i * i
        LD      DE,var_z2
        CALL    REAL_SUB                ; s = z*z - i*i
        LD      HL,var_s
        LD      DE,var_d
        CALL    REAL_ADD                ; s = s + d
       
        LD      HL,const_2
        LD      DE,var_r
        CALL    COPYREAL                ; r = 2
        LD      DE,var_i
        CALL    REAL_MUL                ; r = r * i
        LD      HL,var_r
        LD      DE,var_z
        CALL    REAL_MUL                ; r = r * z
        LD      HL,var_r
        LD      DE,var_e
        CALL    REAL_ADD                ; r = r + e

        LD      HL,var_s
        LD      DE,var_z
        CALL    COPYREAL                ; z = s

        LD      HL,var_r
        LD      DE,var_i
        CALL    COPYREAL                ; i = r

        LD      A,(BclWhile+1)
        INC     A
        LD      (BclWhile+1),A
        JP      BclWhile

FinWhile:
        LD      A,(BclWhile+1)
        CALL    GRA_SET_PEN
        LD      A,(X+1)
        LD      L,A
        LD      H,0
        ADD     HL,HL
        ADD     HL,HL                   ; x * 4 (nous sommes en mode 0)
        EX      DE,HL
        LD      A,(Y+1)
        LD      L,A
        LD      H,0
        ADD     HL,HL                   ; y * 2
        CALL    GRA_PLOT_ABS

        LD      HL,var_d
        LD      DE,const_inc_d
        CALL    REAL_ADD                ; d = d + 0.0215
        LD      A,(X+1)
        INC     A
        LD      (X+1),A
        CP      160                     ; x = 160 ?
        JP      C,X

        LD      HL,var_e
        LD      DE,const_inc_e
        CALL    REAL_ADD                ; e = e + 0.013
        LD      A,(Y+1)
        INC     A
        LD      (Y+1),A
        CP      200                     ; y = 200 ?
        JP      C,Y
        RET

; Copier un réel dans un autre
; en entrée - HL = réel source, DE = réel destination
; en sortie - HL = réel destination
COPYREAL:
        PUSH    DE
        LDI
        LDI
        LDI
        LDI
        LDI
        POP     HL
        RET

;
; Les constantes
;
const_d:
        DB      #9A,#99,#99,#99,#82     ; -2.4
const_e:
        DB      #66,#66,#66,#A6,#81     ; -1.3
const_0:
        DB      #00,#00,#00,#00,#00     ; 0
const_2:
        DB      #00,#00,#00,#00,#82     ; 2
const_4:
        DB      #00,#00,#00,#00,#83     ; 4
const_inc_d:
        DB      #9C,#C4,#20,#30,#7B     ; 0.0215
const_inc_e:
        DB      #B6,#F3,#FD,#54,#7A     ; 0.013

;
; Les variables
;
var_d:
        DS      5
var_e:
        DS      5
var_r:
        DS      5
var_s:
        DS      5
var_i:
        DS      5
var_z:
        DS      5
var_i2:
        DS      5
var_z2:
        DS      5
var_tmp:
        DS      5

Auteur :  hERMOL [ 12 Sep 2011, 10:36 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

un de plus en basic ...

Code :
20 N=40
30 OX=2:OY=1:OU=100
50 CLS
100 D=N/4
400 FOR X = 0 TO 319
500  FOR Y = 0 TO 199
505   X1=X/OU-OX:XX=X1
510   Y1=Y/OU-OY:YY=Y1
515   X2 = XX*XX
520   Y2 = YY*YY
525   IT = 0
535   IF X2 + Y2 > 4  OR  IT = N  THEN 580
540   YY = 2*XX*YY + Y1
545   XX = X2 - Y2 + X1
550   X2 = XX*XX
555   Y2 = YY*YY
560   IT = IT + 1
565   GOTO 535
580   A=IT-INT(IT/4)*4
600   PLOT X,Y,A
700  NEXT Y
800 NEXT X

la petite compilation du sujet...

Auteur :  TotO [ 12 Sep 2011, 14:18 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

J'aurai préféré que le sujet dérive sur des programmes en 1 ligne (tous genres), plutôt que les X façon de coder un Mandelbrot. :D

Auteur :  Megachur [ 13 Sep 2011, 05:44 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

TotO a écrit :
J'aurai préféré que le sujet dérive sur des programmes en 1 ligne (tous genres), plutôt que les X façon de coder un Mandelbrot. :D


je vois pas trop l’intérêt de s'embêter à coder en une ligne... A part si c'est un concours ?! :sweatingbullets:

Auteur :  TotO [ 13 Sep 2011, 07:46 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Megachur a écrit :
je vois pas trop l’intérêt de s'embêter à coder en une ligne... A part si c'est un concours ?! :sweatingbullets:
C'est pas grave...

Auteur :  Demoniak [ 13 Sep 2011, 07:48 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

Bah on peut diviser le sujet en deux :
- pour les fractales de mandelbrot et ses diverses implémentations pour le cpc
- pour les codes en une ligne de basic

:)

Auteur :  hERMOL [ 13 Sep 2011, 08:27 ]
Sujet du message :  Re: Mandelbrot en 1 ligne

ok , je clôture ce sujet..

1) Les fractales de mandelbrot
2) Les 1 ligne

Page 1 sur 1 Le fuseau horaire est UTC+1 heure
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/