楼主要求的程序,不是很复杂,用纯粹的C语言,使用Win32API,就可以了,楼主要学的话看一下WIN32 API的书,当然你也可以学MFC,前提要对C++比较熟悉,类,继承,多态一定要搞清楚。
我写了一下,代码如下:
#include <windows.h>
#include <math.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM)
int cxClient, cyClient ,cByteWidth
POINT apt[5]
bool requestRedraw
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
//入口点,就是main函数
static TCHAR szAppName[] = TEXT ("Bezier")
HWND hwnd
MSG msg
WNDCLASS wndclass
wndclass.style = CS_HREDRAW | CS_VREDRAW
wndclass.lpfnWndProc = WndProc
wndclass.cbClsExtra= 0
wndclass.cbWndExtra= 0
wndclass.hInstance = hInstance
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION)
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW)
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH)
wndclass.lpszMenuName = NULL
wndclass.lpszClassName = szAppName
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR)
return 0
}
//创建一个窗口
hwnd = CreateWindow (szAppName, TEXT ("Bezier Splines"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL)
ShowWindow (hwnd, iCmdShow)
UpdateWindow (hwnd)
//建立消息循环,来接受鼠标动作,窗口缩放,移动等动作
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg)
DispatchMessage (&msg)
}
return msg.wParam
}
void DrawBezier (HDC hdc,HDC hdcMem)
{
//这里是画曲线,通过打点的方式画到位图中,然后显示,当然算法有待改进
static char bits [259200]
if(requestRedraw)
{
memset(bits,0xFF,259200)
float tDelat = 0.025/max(cxClient,cyClient)
for(float t = 0 t <1 + tDelat t += tDelat)
{
float mt = 1 - t
float t2 = t * t,t3 = t2 * t,t4 = t3 * t
float mt2 = mt * mt,mt3 = mt2 * mt,mt4 = mt3 * mt
int fX = apt[0].x * t4 + 4 * apt[1].x * t3 * mt + 6 * apt[2].x * t2 * mt2
+ 4 * apt[3].x * t * mt3 + apt[4].x * mt4 + 0.5f
int fY = apt[0].y * t4 + 4 * apt[1].y * t3 * mt + 6 * apt[2].y * t2 * mt2
+ 4 * apt[3].y * t * mt3 + apt[4].y * mt4 + 0.5f
bits[( fX + ((fY * cByteWidth) <<3)) >>3] &= (0xFF ^ ( 0x80 >>( fX &0x07 )))
}
requestRedraw = false
}
HBITMAP hBitmap
BITMAP bitmap = { 0, cxClient, cyClient, cByteWidth, 1, 1 }
bitmap.bmBits = bits
hBitmap = CreateBitmapIndirect (&bitmap)
SelectObject(hdcMem,hBitmap)
BitBlt (hdc, 0, 0, cxClient, cyClient,
hdcMem, 0, 0, SRCCOPY)
DeleteObject(hBitmap)
//把点用直线连起来
static HPEN hRedPen = CreatePen (PS_SOLID, 1, RGB (255, 0, 0))
SelectObject(hdc,hRedPen)
MoveToEx (hdc, apt[0].x, apt[0].y, NULL)
LineTo (hdc, apt[1].x, apt[1].y)
LineTo (hdc, apt[2].x, apt[2].y)
LineTo (hdc, apt[3].x, apt[3].y)
LineTo (hdc, apt[4].x, apt[4].y)
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//消息循环处理函数
static HDC hdc,hdcMem
static PAINTSTRUCT ps
static int chosen = -1,minDistance = 1e3
switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd)
hdcMem = CreateCompatibleDC (hdc)
ReleaseDC(hwnd,hdc)
return 0
//当窗口大小改变,要重新画曲线
case WM_SIZE:
cxClient = LOWORD (lParam)
cyClient = HIWORD (lParam)
cByteWidth = int(ceil(cxClient / 8.0f))%2 == 0 ? ceil(cxClient / 8.0f) : ceil(cxClient / 8.0f)+1
apt[0].x = 1 * cxClient / 6 apt[0].y = 1 * cyClient / 2
apt[1].x = 1 * cxClient / 2 apt[1].y = 1 * cyClient / 6
apt[2].x = 1 * cxClient / 2 apt[2].y = 4 * cyClient / 5
apt[3].x = 2 * cxClient / 3 apt[3].y = 4 * cyClient / 5
apt[4].x = 4 * cxClient / 5 apt[4].y = 1 * cyClient / 3
chosen = -1
requestRedraw = true
return 0
//鼠标点击,计算出选择哪一个要移动的点
case WM_LBUTTONDOWN:
minDistance = 1e3chosen = -1
for(int i = 0 i <5 i++ )
{
int dx = LOWORD (lParam) - apt[i].x int dy = HIWORD (lParam) - apt[i].y
int currentDist = dx*dx + dy*dy
if(currentDist <minDistance)
{
minDistance = currentDist
chosen = i
}
}
return 0
//鼠标移动,让点跟随鼠标
case WM_MOUSEMOVE:
if (wParam &MK_LBUTTON &&chosen >= 0)
{
apt[chosen].x = LOWORD (lParam)
apt[chosen].y = HIWORD (lParam)
requestRedraw = true
PostMessage(hwnd,WM_PAINT,NULL,NULL)
}
return 0
//这个是windows传给程序的绘图命令
case WM_PAINT:
InvalidateRect (hwnd, NULL, FALSE)
hdc = BeginPaint (hwnd, &ps)
DrawBezier (hdc,hdcMem)
EndPaint (hwnd, &ps)
return 0
case WM_DESTROY:
PostQuitMessage (0)
return 0
}
return DefWindowProc (hwnd, message, wParam, lParam)
}
不懂的话,可以Hi我
三次样条插值程序float hypot(float X, float Y)
void tspLine(int n, int ch, int *Num, float x[], float y[], float u1[], float v1[], float tx1 = 0.0, float tx2 = 0.0, float ty1 = 0.0, float ty2 = 0.0)
float hypot(float X, float Y)
{
return sqrt(X * X + Y * Y)
}
void tspLine(int n, int ch, int *Num, float x[], float y[], float u1[], float v1[], float tx1, float tx2, float ty1, float ty2)
{
int i, j, iNum
float *a, *b, *c, *dx, *dy
float *qx, *qy
float *t, *px, *py
float tt, bx3, bx4, by3, by4
float cx, cy
float u[3]
a = new float[n + 1]
b = new float[n + 1]
c = new float[n + 1]
dx = new float[n + 1]
dy = new float[n + 1]
qx = new float[n + 1]
qy = new float[n + 1]
t = new float[n + 1]
px = new float[n + 1]
py = new float[n + 1]
iNum = 0
for (i = 1i <= ni++)
t[i] = hypot(x[i] - x[i - 1], y[i] - y[i - 1])
switch (ch)
{
case 0: //抛物条件
u[0] = (x[1] - x[0]) / t[1]
u[1] = (x[2] - x[1]) / t[2]
u[2] = (u[1] - u[0]) / (t[2] + t[1])
tx1 = u[0] - u[2] * t[1]
u[0] = (y[1] - y[0]) / t[1]
u[1] = (y[2] - y[1]) / t[2]
u[2] = (u[1] - u[0]) / (t[2] + t[1])
ty1 = u[0] - u[2] * t[1]
u[0] = (x[n] - x[n - 1]) / t[n]
u[1] = (x[n - 1] - x[n - 2]) / t[n - 1]
u[2] = (u[0] - u[1]) / (t[n] + t[n - 1])
tx2 = u[0] + u[2] * t[n]
u[0] = (y[n] - y[n - 1]) / t[n]
u[1] = (y[n - 1] - y[n - 2]) / t[n - 1]
u[2] = (u[0] - u[1]) / (t[n] + t[n - 1])
ty2 = u[0] + u[2] * t[n]
break
case 1: //夹持条件
a[0] = 1.0
c[0] = 0.0
dx[0] = tx1
dy[0] = ty1
a[n] = 1.0
b[n] = 0.0
dx[n] = tx2
dy[n] = ty2
break
case 2: //自由条件
a[0] = 2.0
c[0] = 1.0
dx[0] = 3.0 * (x[1] - x[0]) / t[1]
dy[0] = 3.0 * (y[1] - y[0]) / t[1]
a[n] = 2.0
b[n] = 1.0
dx[n] = 3.0 * (x[n] - x[n - 1]) / t[n]
dy[n] = 3.0 * (y[n] - y[n - 1]) / t[n]
break
case 3: //循环条件
a[0] = 2.0
c[0] = 1.0
dx[0] = 3.0 * (x[1] - x[0]) / t[1] - (t[1] * (x[2] - x[1]) / t[2] - x[1] + x[0]) / (t[1] + t[2])
dy[0] = 3.0 * (y[1] - y[0]) / t[1] - (t[1] * (y[2] - y[1]) / t[2] - y[1] + y[0]) / (t[1] + t[2])
a[n] = 2.0
b[n] = 1.0
dx[n] = 3.0 * (x[n] - x[n - 1]) / t[n]
dx[n] = dx[n] + (x[n] - x[n - 1] - t[n] * (x[n - 1] - x[n - 2]) / t[n - 1]) / (t[n] + t[n - 1])
dy[n] = 3.0 * (y[n] - y[n - 1]) / t[n]
dy[n] = dy[n] + (y[n] - y[n - 1] - t[n] * (y[n - 1] - y[n - 2]) / t[n - 1]) / (t[n] + t[n - 1])
}
//计算方程组系数阵和常数阵
for (i = 1i <ni++)
{
j = i + 1
a[i] = 2.0 * (t[i] + t[j])
b[i] = t[j]
c[i] = t[i]
dx[i] = 3.0 * (t[i] * (x[j] - x[i]) / t[j] + t[j] * (x[i] - x[i - 1]) / t[i])
dy[i] = 3.0 * (t[i] * (y[j] - y[i]) / t[j] + t[j] * (y[i] - y[i - 1]) / t[i])
}
//采用追赶法解方程组
c[0] = c[0] / a[0]
for (i = 1i <ni++)
{
a[i] -= b[i] * c[i - 1]
c[i] /= a[i]
}
a[n] -= b[n] * c[i - 1]
qx[0] = dx[0] / a[0]
qy[0] = dy[0] / a[0]
for (i = 1i <= ni++)
{
qx[i] = (dx[i] - b[i] * qx[i - 1]) / a[i]
qy[i] = (dy[i] - b[i] * qy[i - 1]) / a[i]
}
px[n] = qx[n]
py[n] = qy[n]
for (i = n - 1i >= 0i--)
{
px[i] = qx[i] - c[i] * px[i + 1]
py[i] = qy[i] - c[i] * py[i + 1]
}
//计算曲线上点的坐标
for (i = 0i <ni++)
{
j = i + 1
bx3 = (3.0 * (x[j] - x[i]) / t[j] - 2.0 * px[i] - px[j]) / t[j]
bx4 = ((2.0 * (x[i] - x[j]) / t[j] + px[i] + px[j]) / t[j]) / t[j]
by3 = (3.0 * (y[j] - y[i]) / t[j] - 2.0 * py[i] - py[j]) / t[j]
by4 = ((2.0 * (y[i] - y[j]) / t[j] + py[i] + py[j]) / t[j]) / t[j]
tt = 0.0
while (tt <= t[j])
{
cx = x[i] + (px[i] + (bx3 + bx4 * tt) * tt) * tt
cy = y[i] + (py[i] + (by3 + by4 * tt) * tt) * tt
u1[iNum] = cx
v1[iNum] = cy
iNum++
tt += 0.5
}
u1[iNum] = x[j]
v1[iNum] = y[j]
iNum++
}
delete a
delete b
delete c
delete dx
delete dy
delete qx
delete qy
delete t
delete px
delete py
*Num = iNum
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)