主题:[原创]随机画Bezier曲线的程序
caoxin [专家分:1540] 发布于 2005-05-17 23:50:00
工程目录是:Win32App
vc6.0
#include<windows.h>
#include<stdlib.h>
#include<time.h>
#define NUM 10
LRESULT CALLBACK Winproc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstanc,LPSTR lpCmdLine,int nShowCmd)
{
MSG msg;
static TCHAR szClassName[] = TEXT("::Bezier样条计算公式由法国雷诺汽车公司的工程师Pierm Bezier于六十年代提出");
HWND hwnd;
WNDCLASS wc;
wc.cbClsExtra =0;
wc.cbWndExtra =0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = Winproc;
wc.lpszClassName = szClassName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wc))
{
MessageBox(NULL,TEXT("注册失败"),TEXT("警告框"),MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szClassName,szClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWMAXIMIZED);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK Winproc(HWND hwnd,UINT message, WPARAM wparam,LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
static POINT pt[NUM];
TEXTMETRIC tm;
static int cxClient,cyClient;
HPEN hpen;
int i,j,k,n,t;
switch(message)
{
case WM_CREATE:
static int cxchar;
hdc = GetDC(hwnd);
GetTextMetrics(hdc,&tm);
cxchar = tm.tmAveCharWidth;
ReleaseDC(hwnd,hdc);
case WM_SIZE:
cxClient = LOWORD(lparam);
cyClient = HIWORD(lparam);
return 0;
case WM_PAINT:
hdc = GetDC(hwnd);
srand(time(0));
Rectangle(hdc,0,0,cxClient,cyClient);
for(i=0; i<500; i++)
{
SelectObject(hdc,GetStockObject(WHITE_PEN));
PolyBezier(hdc,pt,NUM);
for(j=0; j<NUM; j++)
{
pt[j].x = rand()%cxClient;
pt[j].y = rand()%cyClient;
}
hpen = CreatePen(PS_INSIDEFRAME,3,RGB(rand()%256,rand()%256,rand()%256));
DeleteObject(SelectObject(hdc,hpen));
PolyBezier(hdc,pt,NUM);
for(k=0; k<50000000;k++);
}
for(i=0; i<100;i++)
{
Ellipse(hdc,rand()%cxClient,rand()%cyClient,rand()%cxClient,rand()%cyClient);
Pie(hdc,j=rand()%cxClient,k=rand()%cyClient,n=rand()%cxClient,t=rand()%cyClient,rand()%cxClient,rand()%cyClient,rand()%cxClient,rand()%cyClient) ;
}
if((n=(n+j)/2)>cxchar*20) n=cxchar*20;
SetTextColor(hdc,RGB(rand()%256,rand()%256,rand()%256));
TextOut(hdc,n/2,(t+k)/2,TEXT("瑾以此向Pierm Bezier致敬!"),lstrlen(TEXT("瑾以此向Pierm Bezier致敬!")));
ReleaseDC(hwnd,hdc);
DeleteObject(hpen);
ValidateRect(hwnd,NULL);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wparam,lparam);
}
回复列表 (共9个回复)
沙发
bruceteen [专家分:42660] 发布于 2005-05-18 10:22:00
:)整个代码其实有用的就是一句 PolyBezier(hdc,pt,NUM) ,而且PolyBezier还是windows的一个API。
板凳
caoxin [专家分:1540] 发布于 2005-05-19 21:28:00
嘿嘿.知道怎么用就不错了
另外:
SelectObject(hdc,GetStockObject(WHITE_PEN));
CreatePen(PS_INSIDEFRAME,3,RGB(rand()%256,rand()%256,rand()%256));
DeleteObject(SelectObject(hdc,hpen));
也是有用的.
3 楼
sunson468 [专家分:510] 发布于 2005-05-19 21:44:00
怎么看起来都象封装的原程序,就加了一点东西!
4 楼
caoxin [专家分:1540] 发布于 2005-05-19 21:48:00
Windows程序都是这样的.
5 楼
caoxin [专家分:1540] 发布于 2005-05-28 00:36:00
顶!
6 楼
jackin0627 [专家分:1270] 发布于 2005-09-29 11:03:00
用的都是人家 的技术,
要是自个编一个画Bezier曲线的函数才好
7 楼
探路者二号 [专家分:1170] 发布于 2005-09-29 12:29:00
--------------------Configuration: BezierCurves. - Win32 Debug--------------------
Compiling...
BezierCurves..c
E:\MSVCDev\BezierCurves..c(65) : error C2143: syntax error : missing ';' before 'type'
E:\MSVCDev\BezierCurves..c(68) : error C2065: 'cxchar' : undeclared identifier
Error executing cl.exe.
BezierCurves..exe - 2 error(s), 0 warning(s)
8 楼
iAkiak [专家分:8460] 发布于 2005-09-29 21:00:00
ogl2dlib里的b样条生成代码:乱是比较乱...不过还凑合能用
#pragma warning(disable : 4786)
#include <windows.h>
#include <gl/gl.h>
#include <assert.h>
#include "bspline.h"
/// b-spline
/*
{ -d^3 + 3d^2 - 3d + 1 }
{x1,x2,x3,x4} . { 3d^3 - 6d^2 + 0d + 4 }
{y1,y2,y3,y4} { -3d^3 + 3d^2 + 3d + 1 }
{ d^3 + 0d^2 + 0d + 0 }
x = {x1(-d^3+3d^2-3d+1)+x2(d^3-6d^2+4)+x3(-d^3+3d^2+3d+1)+x4(d^3) } / 6
y = {y1(-d^3+3d^2-3d+1)+y2(d^3-6d^2+4)+y3(-d^3+3d^2+3d+1)+y4(d^3) } / 6
*/
sbspline sBspLine;
float g_dd[4];
#define SP_COUNT 1023
float s_dd[SP_COUNT + 1][4];
const float one_sixth = 1.0f/6.0f;
void initbspline()
{
float d,d2,d3,t1,t2,t3;
int i = 0;
for (d=0.0f; i<=SP_COUNT; d+=1.0f / SP_COUNT)
{
d2 = d * d;
d3 = d2 * d;
t1 = -d3 + 3*d2 - 3*d + 1.0f;
t2 = 3*d3 - 6*d2 + 4.0f;
t3 = -3*d3 +3*d2 + 3*d +1.0f;
s_dd[i][0] = t1 * one_sixth;
s_dd[i][1] = t2 * one_sixth;
s_dd[i][2] = t3 * one_sixth;
s_dd[i][3] = d3 * one_sixth;
++i;
}
}
struct splineInitializer
{
splineInitializer()
{
initbspline();
}
};
static splineInitializer spl;
void bspline(float d)
{
/*
float d2 = d * d;
float d3 = d2 * d;
d *= 3.0f;
d2 *= 3.0f;
float t1 = d2 - d + 1.0f - d3;
float t3 = 3.0f * d3 - d2;
float t2 = t3 - d2 + 4.0f;
t3 = d + 1.0f - t3;
sBspLine.x = (sBspLine.x1*t1 + sBspLine.x2*t2 + sBspLine.x3*t3 + sBspLine.x4*d3)*one_sixth;
sBspLine.y = (sBspLine.y1*t1 + sBspLine.y2*t2 + sBspLine.y3*t3 + sBspLine.y4*d3)*one_sixth;
/*/
int i = (int)(d * SP_COUNT);
if (i > SP_COUNT) i = SP_COUNT;
if (i < 0) i = 0;
float t1 = s_dd[i][0];
float t2 = s_dd[i][1];
float t3 = s_dd[i][2];
float d3 = s_dd[i][3];
sBspLine.x = sBspLine.x1*t1 + sBspLine.x2*t2 + sBspLine.x3*t3 + sBspLine.x4*d3;
sBspLine.y = sBspLine.y1*t1 + sBspLine.y2*t2 + sBspLine.y3*t3 + sBspLine.y4*d3;
//*/
}
void bspline_d(float d)
{
/*
float d2 = d * d;
float d3 = d2 * d;
d *= 3.0f;
d2 *= 3.0f;
float t1 = d2 - d + 1.0f - d3;
float t3 = 3.0f * d3 - d2;
float t2 = t3 - d2 + 4.0f;
t3 = d + 1.0f - t3;
g_dd[0] = t1*one_sixth;
g_dd[1] = t2*one_sixth;
g_dd[2] = t3*one_sixth;
g_dd[3] = d3*one_sixth;
/*/
int i = (int)(d * SP_COUNT);
if (i > SP_COUNT) i = SP_COUNT;
if (i < 0) i = 0;
g_dd[0] = s_dd[i][0];
g_dd[1] = s_dd[i][1];
g_dd[2] = s_dd[i][2];
g_dd[3] = s_dd[i][3];
//*/
}
void makeBS(int sn, float xs[], float ys[], float ts[], int t, float &ox, float &oy)
{
float dd;
int j;
// j = (t/200) % (sn - 4 + 1);
while (1)
{
for (j=0;j<sn-4+1;j++)
{
if (t<ts[j])
break;
}
if (j < sn-4+1)
break;
t -= (int)ts[sn-1];
}
dd = (t-ts[j-1]) / (ts[j] - ts[j-1]);
sBspLine.x1 = xs[j];
sBspLine.y1 = ys[j];
sBspLine.x2 = xs[j+1];
sBspLine.y2 = ys[j+1];
sBspLine.x3 = xs[j+2];
sBspLine.y3 = ys[j+2];
sBspLine.x4 = xs[j+3];
sBspLine.y4 = ys[j+3];
bspline(dd);
ox = sBspLine.x;
oy = sBspLine.y;
}
void DrawBS(int sn, float xs[], float ys[])
{
float n,x,y,dd;
int j,i;
glDisable(GL_TEXTURE_2D);
glColor3f(0,1,0);
glBegin(GL_LINE_STRIP);
for (j=0;j<sn;j++)
glVertex2f(xs[j],ys[j]);
glEnd();
glColor3f(1,1,1);
glBegin(GL_LINE_STRIP);
n=8;
for (j=0;j < sn - 4 + 1;j++)
{
dd=0.f;
for (i=0;i<n;i++)
{
sBspLine.x1 = xs[j];
sBspLine.y1 = ys[j];
sBspLine.x2 = xs[j+1];
sBspLine.y2 = ys[j+1];
sBspLine.x3 = xs[j+2];
sBspLine.y3 = ys[j+2];
sBspLine.x4 = xs[j+3];
sBspLine.y4 = ys[j+3];
bspline(dd);
x = sBspLine.x;
y = sBspLine.y;
//glColor3f((j*n+i)/(5*n),(j*n+i)/(5*n),(j*n+i)/(5*n));
glVertex2f(x, y);
dd += 1.0f/n;
}
}
bspline(dd);
x = sBspLine.x;
y = sBspLine.y;
//glColor3f((j*n+i)/(5*n),(j*n+i)/(5*n),(j*n+i)/(5*n));
glVertex2f(x, y);
glEnd();
glEnable(GL_TEXTURE_2D);
}
9 楼
caoxin [专家分:1540] 发布于 2005-09-30 16:27:00
隔了数月看自己写的东西,发现该用PeekMessage()的
我来回复