kreis darstellen?
-
ich hab in nem tut hinweise drauf bekommen wie man kreise in (t)asm darstellt.
das problem: es waren halt nur tips, aber kein source!!
wie mach ich das nu???danke im voraus!
-
hi,
hier ist ein beispiel. die prozedur ist eigentlich viel zu langsam, da sie die wurzelfunktion benutzt, wegen:
r²=x²+y²
und somit:
y=wurzel(r²-x²)aber zum kreise zeichnen eignet sich ´schon ganz gut. naja, ein kleiner speedup ist, dass sie nur ein achtel des kreises ausrechnet und dann spiegelt, weil man in einem kreis alle achtel auf einander spiegeln kann.
weiter unten ist nochmal c++ code der macht dasselbe, dachte nur, dass du es dann vielleicht einfacher hättest durch den code zu steigen.model tiny, pascal locals .code org 100h main: .386 fstenv [ENV] mov ax,13h int 10h mov cx,99 repeat: CALL circle,160,100,cx,cx dec cx jnz repeat mov ah,08h int 21h mov ax,03h int 10h fldenv [ENV] ret .8086 public circle circle proc near USES ax bx dx es,X0,Y0,R : word,COL0 : byte local X,Y,Rq : word mov ax,0A000h mov es,ax mov dl,byte ptr [COL0] mov [X],0 ffree st(7) fild [R] fmul st(0),st(0) ;r² berechnen fist [Rq] ; und in Rq speichern @@calc_oct: ffree st(6) ffree st(7) fild [X] ; fmul st(0),st(0) ; x² berechnen fild [Rq] ; r²-x² fsub st(0),st(1) fsqrt ; daraus die wurzel fist [Y] ; in y speichern also y = wurzel(r²-x²) CALL circ_pix,[X],[Y],[X0],[Y0] ; den pixel setzen bei x,y CALL circ_pix,[Y],[X],[X0],[Y0] ; bei y,x neg [X] ; jetzt spiegeln CALL circ_pix,[X],[Y],[X0],[Y0] ; bei -x,y setzen CALL circ_pix,[Y],[X],[X0],[Y0] ; y,-x neg [Y] CALL circ_pix,[X],[Y],[X0],[Y0] ; -x,-y CALL circ_pix,[Y],[X],[X0],[Y0] ; .... neg [X] CALL circ_pix,[X],[Y],[X0],[Y0] ; ..... ... ... CALL circ_pix,[Y],[X],[X0],[Y0] neg [Y] inc [X] mov ax,[X] cmp ax,[Y] ; schleife für x jnl @@finished ; wenn x>=y dann sind wir mit dem achtel fertig jmp @@calc_oct @@finished: ret ; ------ das hier soll ne lokale prozedur sein, ist glaub ich nicht ganz lokal ; sie setzt nen pixel bei (Xc+Xt,Yc+Yt) ... (Xt/Yt) ist der mittelpunkt des ; kreises circ_pix proc near Xc,Yc,Xt,Yt mov ax,[Yc] add ax,[Yt] mov bx,[Xc] add bx,[Xt] xchg ah,al add bx,ax .286 shr ax,2 .8086 add bx,ax mov es:[bx],dl ret circ_pix endp circle endp ENV dw 7 dup (?) end main
----------------------------------------------------------------------
dasselbe nun in C++
----------------------------------------------------------------------#include <dos.h> #include <math.h> #include <conio.h> #include <stdlib.h> unsigned char far* vga = (unsigned char far*)0xA0000000; int x,y,r; unsigned int i; unsigned char col; void circle(int x0,int y0,int r,int col) { int x,y,rq = r*r; // hier auch r² berechnen und in rq speichern for (x = 0; x < y ; x++) { y = sqrt(rq-x*x); // dasselbe wie oben // pixel setzen und den achtel spiegeln vga[(x+x0)+((y+y0) << 8)+((y+y0) << 6)] = col; vga[(x+x0)+((-y+y0) << 8)+((-y+y0) << 6)] = col; vga[(y+x0)+((x+y0) << 8)+((x+y0) << 6)] = col; vga[(y+x0)+((-x+y0) << 8)+((-x+y0) << 6)] = col; vga[(-x+x0)+((y+y0) << 8)+((y+y0) << 6)] = col; vga[(-x+x0)+((-y+y0) << 8)+((-y+y0) << 6)] = col; vga[(-y+x0)+((x+y0) << 8)+((x+y0) << 6)] = col; vga[(-y+x0)+((-x+y0) << 8)+((-x+y0) << 6)] = col; } } main() { asm { mov ax,13h int 10h } do { x = random(320); y = random(200); r = random(100); col = random(256); circle(x,y,r,col); } while (inportb(0x60) != 1); asm { mov ax,03h int 10h } }
-
ach ja, wollte noch sagen dass du dich mit bresenham algorithmen beschäftigen solltest wenn du schnelle kreisroutinen willst. aber naja, auf den heutigen rechnern merkt das auge nix.
-
hab grad gemerkt dass ich noch eine version mit ein paar verbesserungen hab, sorry möchte den thread eigentlich ncith vollspammen:
model tiny,pascal locals .code org 100h main: .386 fstenv [ENV] mov ax,13h int 10h mov cx,99 repeat: CALL circle,160,100,cx,cx dec cx jnz repeat mov ah,08h int 21h mov ax,03h int 10h fldenv [ENV] ret .8086 public circle circle proc near USES ax bx dx es,X0,Y0,R : word,COL0 : byte local X,Y : word local Rq : dword mov ax,0A000h mov es,ax mov dl,byte ptr [COL0] mov [X],0 ffree st(7) fild [R] fmul st(0),st(0) fstp dword ptr [Rq] @@calc_oct: ffree st(6) fild [X] fmul st(0),st(0) fld [Rq] fsub st(0),st(1) fsqrt fistp [Y] CALL circ_pix,[X],[Y],[X0],[Y0] CALL circ_pix,[Y],[X],[X0],[Y0] neg [X] CALL circ_pix,[X],[Y],[X0],[Y0] CALL circ_pix,[Y],[X],[X0],[Y0] neg [Y] CALL circ_pix,[X],[Y],[X0],[Y0] CALL circ_pix,[Y],[X],[X0],[Y0] neg [X] CALL circ_pix,[X],[Y],[X0],[Y0] CALL circ_pix,[Y],[X],[X0],[Y0] neg [Y] inc [X] mov ax,[X] cmp ax,[Y] jnl @@finished jmp @@calc_oct @@finished: ret circ_pix proc near Xc,Yc,Xt,Yt mov ax,[Yc] add ax,[Yt] mov bx,[Xc] add bx,[Xt] xchg ah,al add bx,ax .286 shr ax,2 .8086 add bx,ax mov es:[bx],dl ret circ_pix endp circle endp ENV dw 7 dup (?) end main
-
obiges C++-Programm ist nicht portabel (random, inportb).