x1=x0+cx/3
x2=x1+(cx+bx)/3
x3=x0+cx+bx+ax
y1=y0+cy/3
y2=y1+(cy+by)/3
y3=y0+cy+by+ay
则:
cx=3(x1-x0)
bx=3(x2-x1)-cx
ax=x3-x0-cx-bx
cy=3(y1-y0)
by=3(y2-y1)-cy
ay=y3-y0-cy-by
x(t)=ax*t^3 + bx*t^2 + cx*t +x0
y(t)=ay*t^3 + by*t^2 + cy*t +y0
x(t)为所确定贝塞尔曲线的一个点的x轴坐标
y(t)为所确定贝塞尔曲线的一个点的y轴坐标
t为 0~1 之间的实数
;--------------------------------------------------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data?
hInstance dd ?
hWinMain dd ?
t dd ?
_cx dd ?
_bx dd ?
_ax dd ?
_cy dd ?
_by dd ?
_ay dd ?
x dd ?
y dd ?
hdc dd ?
lpPoint dd 8 dup(?)
buff db 12 dup(?)
j1 dd ?
j2 dd ?
j3 dd ?
j4 dd ?
j5 dd ?
j6 dd ?
j7 dd ?
j8 dd ?
.const
tt dd 5.0E-3
szClassName db 'Bezier',0
szCaptionMain db 'Bezier !',0
.code
_bh proc lp,jh,fx,max
pushad
mov esi,lp
mov ebx,jh
mov eax,max
cmp eax,dword ptr[esi]
je lp0
cmp dword ptr[esi],0
jne @f
lp0:
xor dword ptr[ebx],1
@@:
mov eax,fx
cmp eax,dword ptr[ebx]
je @f
dec dword ptr[esi]
dec dword ptr[esi]
@@:
inc dword ptr[esi]
popad
ret
_bh endp
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
mov eax,uMsg
.if eax == WM_TIMER
invoke GetStockObject,WHITE_PEN
invoke SelectObject,hdc,eax
mov edi,2
jmp lp1
lp:
invoke _bh,addr lpPoint,addr j1,1,800
invoke _bh,addr lpPoint+4,addr j2,1,600
invoke _bh,addr lpPoint+8,addr j3,0,800
invoke _bh,addr lpPoint+12,addr j4,0,600
invoke _bh,addr lpPoint+16,addr j5,1,800
invoke _bh,addr lpPoint+20,addr j6,1,600
invoke _bh,addr lpPoint+24,addr j7,0,800
invoke _bh,addr lpPoint+28,addr j8,0,600
lp1:
invoke MoveToEx,hdc,dword ptr lpPoint,dword ptr lpPoint+4,0
mov ebx,3
mov eax,dword ptr lpPoint+8
sub eax,dword ptr lpPoint
mul ebx
mov _cx,eax
mov eax,dword ptr lpPoint+16
sub eax,dword ptr lpPoint+8
mul ebx
sub eax,_cx
mov _bx,eax
mov eax,dword ptr lpPoint+24
mov ecx,dword ptr lpPoint
add ecx,_cx
add ecx,_bx
sub eax,ecx
mov _ax,eax
mov eax,dword ptr lpPoint+12
sub eax,dword ptr lpPoint+4
mul ebx
mov _cy,eax
mov eax,dword ptr lpPoint+20
sub eax,dword ptr lpPoint+12
mul ebx
sub eax,_cy
mov _by,eax
mov eax,dword ptr lpPoint+28
mov ecx,dword ptr lpPoint+4
add ecx,_cy
add ecx,_by
sub eax,ecx
mov _ay,eax
finit
fldz
fild _ax
fild _bx
fild _cx
fild _ay
fild _by
fild _cy
fstp _cy
fstp _by
fstp _ay
fstp _cx
fstp _bx
fstp _ax
fstp t
mov ebx,200
@@:
finit
fld t
fmul t
fld st
fmul t
fmul _ax
fxch
fmul _bx
fld t
fmul _cx
fild dword ptr lpPoint
fadd
fadd
fadd
fist x
fld t
fmul t
fld st
fmul t
fmul _ay
fxch
fmul _by
fld t
fmul _cy
fild dword ptr lpPoint+4
fadd
fadd
fadd
fist y
fld t
fadd tt
fst t
invoke LineTo,hdc,x,y
dec ebx
jnz @b
invoke LineTo,hdc,dword ptr lpPoint+24,dword ptr lpPoint+28
invoke GetStockObject,BLACK_PEN
invoke SelectObject,hdc,eax
dec edi
jnz lp
invoke EndPaint,hWnd,addr @stPs
.elseif eax == WM_CREATE
mov dword ptr lpPoint,100
mov dword ptr lpPoint+4,330
mov dword ptr lpPoint+8,100
mov dword ptr lpPoint+12,350
mov dword ptr lpPoint+16,799
mov dword ptr lpPoint+20,350
mov dword ptr lpPoint+24,450
mov dword ptr lpPoint+28,399
invoke GetDC,hWnd
mov hdc,eax
invoke SetTimer,hWnd,1,1,0
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_MINIMIZEBOX or WS_SYSMENU,\
0,0,812,630,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
start:
call _WinMain
invoke ExitProcess,NULL
end start