⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 invcircs.asm

📁 masm32 汇编源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	    mov	  eax,y1
	    add	  eax,y2
	    mov	  temp,eax
	    fild  temp
	    fdiv  two
	    fstp  circles.Y_Coord[ebx]	; circle-centre y-coord

	    mov	  eax,cDiam
	    mov	  temp,eax
	    fild  temp
	    fdiv  two
	    fstp  circles.Fradius[ebx]	; save radius as FP number
 
	    mov	  eax,cDiam		; Incr x1 boundary for next circle in row  
	    add	  x1,eax

	    add	  ebx,16		; increment the circle index				    	
	    inc	  esi

	  .ENDW

	  mov	eax,cDiam
	  add	y1,eax			; Set new y1 boundary

	  inc   edi

	.ENDW

        .WHILE !inverted		; Loop until key-hit when we invert the circles

	  invoke PeekMessage, ADDR msg, hWnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE

	  .IF eax!=0
		.BREAK			; Escape loop if we detect a keypress
	  .ENDIF

        .ENDW
 
 	invoke GetStockObject, WHITE_BRUSH
	mov	whiteBrush,eax	
 	invoke SelectObject, hdc, eax
	invoke Rectangle, hdc, 0, 0, cxClient, cyClient		; Clear the screen

;***********************************************;
;	Now invert all circles in the array	;  
;***********************************************;

	mov	last,bx			; bx is the index to ALL circles
	sub	last,16			 
	mov	di,first		; Set index to 1st target circle 
		
.WHILE	di <= last			; Loop until all targets are inverted
		
;-------------------------------------------------------------------------;
;  Calculate the angle beta between the line joining the centres of the   ;
;  inversion circle & the target circle to be inverted, & the horizontal  ;
;  also evaluate the sine and cosine.                                     ;
;-------------------------------------------------------------------------;
  
	fld	circles[0].Y_Coord	; Y coord for inversion circle
	fsub	circles[di].Y_Coord	; Get delta_Y into st
	
	fld	circles[0].X_Coord
	fsub	circles[di].X_Coord	; Now st = delta_X, st1 = delta_y
	fpatan				; Get the angle in radians 

	fsincos				; Get  sine & cosine
	fxch				; Swap sine & cosine
	fstp	sin_beta		; save sin(beta) & pop
	fst	cos_beta		; save cos(beta)

;-------------------------------------------------------------------------;
;  Calculate distance "SL" between the centre "S" of the invertion circle ;
;  and the most distant point "L" on the circumference of target circle   ;
;  which is coincident with the line joining the 2 centres.               ;
;								          ;
;	We use the equation:-					          ;
;								          ;	
;	SL = SQRT( (X(m) - X(t) + R(t)*cos(beta) )**2 +		          ;
;		   (Y(m) - Y(t) + R(t)*sin(beta) )**2 )		          ;   
;								          ;
;  where  X(m),Y(m) are the coordinates for centre of the invertion circle;
;	  X(t),Y(t) 	"	"	"	"         target   "      ;
;         R(t)	    is the radius of the target circle		          ;
;-------------------------------------------------------------------------;

	fmul	circles[di].Fradius	; Times radius of the target circle
	fst	radius_cos_beta		; st = R*cos(beta)
	fld	circles[0].X_Coord	; Get invertion circles X coordinate
	fsub	circles[di].X_Coord	; Minus target circles X coordinate
	    				; Gives X(m) - X(t)
					; st = delta_X, st(1) = R*cos(beta)
	fst	delta_X			; Save for use again
	fadd				; st = X(m) - X(t) + R(t)*cos(beta)
	fld	st			; Take a copy into st(1)
	fmul				; Square=(X(m)-X(t)+R(t)*cos(beta))^2

	fld	sin_beta		; st = sin(beta),st(1)=term1^2 
	fmul	circles[di].Fradius
	fst	radius_sin_beta		; Save for use again
	fld	circles[0].Y_Coord	; Get invertion circle Y coordinate
	fsub	circles[di].Y_Coord	; Minus target circles Y coordinate
					; Gives Y(m) - Y(t)
					; st=delta_Y, st(1)=R*sin(beta),st(2)=term1^2
	fst	delta_Y
	fadd			; st=Y(m)-Y(t)+R(t)*sin(beta),st(1)=term1^2

	fld	st			; Take a copy into st(1)
	fmul				; and form the square
					; st=term2^2, st(1)=term1^2

	fadd				; Add the 2 squares togeter
	fsqrt				; Now have SL in st(0)

;--------------------------------------------------------------------------;							
;	In circle inversion we have the relationship:-	                   ;
;								           ;
;		SQ * SQ' = R**2					           ;
;								           ;
;	where	SQ  is the distance from the centre of the base circle to  ;
;		    any radial point within it.			           ;       
;		SQ' is the distance from the centre of the base circle to  ;
;		    the inverted point on the same radial line.	           ;
; 		R   is the radius of the mirror circle.	                   ;
;								           ;
;	We therefore calculate the distance SL' using the equation:-       ;
;								           ;
;		SL' = R(m)**2/SL				           ;
;--------------------------------------------------------------------------;

	fld	circles[0].Fradius	; Load radius of invertion circle 
	fld	st			; Take a copy
	fmul				; Square it to give st=R^2,st(1)=SL
	fld	st			; Take a copy;	R^2, R^2, SL
	fdiv	st,st(2)		; Divide by SL;	SL', R^2, SL 
	fstp	SL_prime		; Store SL';	R^2, SL
	fxch				; Swap;		st=SL, st(1)=R^2
	fstp	st			; Flush st	st=R^2 

;--------------------------------------------------------------------------;		
;  Calculate distance "SM" between the centre of the invertion circle and  ;
;  the nearest point "M" on the circumference of the target circle, which  ;
;  is coincident with the line joining the 2 centres. We use equation:-    ;
;		 							   ;
;	SM = SQRT( (X(m) - X(t) - R(t)*cos(beta) )**2 +		      	   ; 		
;		   (Y(m) - Y(t) - R(t)*sin(beta) )**2 )			   ;
;									   ;
;  where  X(m),Y(m) are the coordinates for centre of the invertion circle ;
;         X(t),Y(t) 	"	"	"	"	target	"          ;
;	  R(t)	    is the radius of the target circle		           ;
;--------------------------------------------------------------------------;

	fld	delta_X		   ; st = delta_X, st(1) = R^2
	fsub	radius_cos_beta	   ; st = X(m)-X(t)-R(t)*cos(beta), st(1)=R^2
	fld	st		   ; Take a copy
	fmul			   ; Square; term1^2, R^2  
	fld	delta_Y		   ; st = delta_Y, st(1)=term1^2, st(2)=R^2
 	fsub	radius_sin_beta    ; Y(m)-Y(t)-R(t)*sin(beta), term1^2,R^2	
	fld	st		   ; Take a copy
	fmul			   ; Square; term2^2, term1^2, R^2
		
	fadd			   ; Add the 2 squares togeter
	fsqrt			   ; Now have SM in st(0) & R^2 in st(1)
							
;	Calculate the distance SM' using the equation:	SM' = R(m)**2/SM  	   

	fdiv				; Divide R**2 by SM to give SM'
	fst	SM_prime
	fld	st			; Take a copy; SM', SM'
	
;	Then the radius of the inverted circle is given by (SM' - SL')/2

	fsub	SL_prime		; st = (SM' - SL'), st(1) = SM'

	fabs				; Make sure it's never negative

	fdiv	two
	fstp	circles[bx].Fradius	; Add inverted circle to list of radii; now st = SM'

;------------------------------------------------------------------------;
;  Now calculate the location of the centre of the inverted circle using ;
;  the equations:-                                                       ;
;								         ;
;		X(i) = X(m) - (SL' + SM')*cos(beta)/2			 ;
;		Y(i) = Y(m) - (SL' + SM')*sin(beta)/2			 ;	
;									 ;
;  where	X(i),Y(i) are the coords of the inverted circles centre  ;
;					                                 ;
;------------------------------------------------------------------------;

	fadd	SL_prime	    	; st = (SL' + SM')
	fld	st		    	; Take a copy into st(1)
	fmul	cos_beta	    	; st=(SL'+SM')*cos(beta), st(1)=(SL'+SM')
	fld	circles[0].X_Coord
	fadd	st,st               	; Double invertion circles X coordinate 
				    	; 
	fsubr			    	; X(m)*2-(SL'+SM')*cos(beta),(SL'+SM')
	fistp	XC		    	; Store (X coordinate)*2 and get
				    	; (SL' + SM') into st(0)
	fwait	
	shr	XC,1		    	; Y coord=X(m)-(SL'+SM')*cos(beta)/2 
	fild	XC
	fstp	circles[bx].X_Coord	; Store X coord't for possible future
   					; inversion of the created circle 

	fmul	sin_beta		; st = (SL' + SM')*sin(beta)
	fld	circles[0].Y_Coord	; Get invertion circles Y coordinate
	fadd	st,st			; Double, st = Y(m)*2, st1=(SL'+SM')..

	fsubr				; Y(m)*2 - (SL' + SM')*sin(beta)

	fistp	YC			; Store & pop stack 
	fwait
	shr	YC,1			; Y coord=Y(m) -(SL'+SM')*sin(beta)/2
	fild	YC
	fstp	circles[bx].Y_Coord	; Store Y coord't for possible future 
					; inversion of the created circle

;	Set colour of the inverted circle

	mov	eax,circles[di].Ccolour	; Get colour of target circle
	mov	colour,eax		; and set inveted circle to have the same 

;	Check size of inverted circle 
		
	fld	circles[bx].Fradius	
	fistp	temp
;	cmp	temp,3			; Min circle diameter set to 6 pixels 
;	jle	skip_circle
	cmp	temp,80			; Limit size of drawn circle <160 OK 
	jg	skip_circle
	
;	Set the 4 boundaries and fill the inverted circles

	fld	circles.X_Coord[bx]
	fsub	circles.Fradius[bx]
	fistp	x1			; x1 boundary
	
	fld	circles.Y_Coord[bx]
	fsub	circles.Fradius[bx]
	fistp	y1			; y1 boundary
	
	fld	circles.X_Coord[bx]
	fadd	circles.Fradius[bx]
	fistp	x2			; x2 boundary
	
	fld	circles.Y_Coord[bx]
	fadd	circles.Fradius[bx]
	fistp	y2			; y2 boundary
	
	invoke SelectObject, hdc, colour
	invoke Ellipse, hdc, x1, y1, x2, y2	; Fill circle with colour

	add	bx,16			; Bump index up ready for next circle 
	add	circles_made,16		; Add 16 for each circle


skip_circle:

	add	di,16	
.ENDW

;-------End of circle inversion code----------------

	inverted = TRUE
 
        invoke EndPaint,hWnd, ADDR ps

	.ELSEIF eax==WM_QUIT
	
		invoke PostMessageA,hWnd,WM_CLOSE,0,0
		ret

	.ELSEIF eax==WM_DESTROY
		invoke DeleteObject, whiteBrush	       
		invoke PostQuitMessage,NULL
        .ELSE
                invoke DefWindowProc,hWnd,uMsg,wParam,lParam
                ret
	.ENDIF

        xor    eax,eax
	ret

WndProc endp

        end start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -