个人作品

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下

力学:模拟橡皮筋(by frxyz1)

一个模拟橡皮筋的程序。

执行效果:

以下是全部源代码:

///////////////////////////////////////////////////
// 程序名称:模拟橡皮筋
// 编译环境:Visual C++ 6.0 / 2010,EasyX 20120404(beta)
// 作  者:frxyz1 <http://hi.baidu.com/frxyz1>
// 最后修改:2012-4-15
//
#include <graphics.h>
#include <conio.h>

#define NODES 20
#define GRAVITY 1
#define ITER 8

struct Vector
{
	float x, y;
	
	void operator += (Vector v) { x += v.x; y += v.y; }
	void operator -= (Vector v) { x -= v.x; y -= v.y; }
	void operator *= (Vector v) { x *= v.x; y *= v.y; }
	
	Vector operator + (Vector v) { Vector t; t.x = x + v.x; t.y = y + v.y; return t; }
	Vector operator - (Vector v) { Vector t; t.x = x - v.x; t.y = y - v.y; return t; }
	Vector operator * (Vector v) { Vector t; t.x = x * v.x; t.y = y * v.y; return t; }
};

struct Node
{
	Vector p; // 坐标
	Vector v; // 速度
} node1[NODES], node2[NODES], *p1 = &node1[0], *p2 = &node2[0];

void Init()
{
	Node n = {{320, 240}, {0}};

	for (int i = 0; i < NODES; i++)
	{
		node1[i] = node2[i] = n;
	}
}

void Update(int mx, int my)
{
	p1[0].p.x = (float)mx;
	p1[0].p.y = (float)my;
	
	p2[0] = p1[0];
	
	static Vector g = {0, GRAVITY}; // 重力
	static Vector sa = {0.01f, 0.01f};
	static Vector sv = {0.99f, 0.99f};
	
	Vector a;
	for (int i = 1; i < NODES - 1; i++)
	{
		a = (p1[i - 1].p - p1[i].p) + (p1[i + 1].p - p1[i].p) + g;
		a *= sa;
		p2[i].v = p1[i].v + a;
		p2[i].v *= sv;
		p2[i].p = p1[i].p + p2[i].v;
	}
	a = (p1[NODES - 2].p - p1[NODES - 1].p) + g;
	a *= sa;
	p2[NODES - 1].v = p1[NODES - 1].v + a;
	p2[NODES - 1].v *= sv;
	p2[NODES - 1].p = p1[NODES - 1].p + p2[NODES - 1].v;
	
	Node* t = p1; p1 = p2; p2 = t;
}

void Render()
{
	moveto((int)p1[0].p.x, (int)p1[0].p.y);
	for (int i = 1; i < NODES; i++)
	{
		lineto((int)p1[i].p.x, (int)p1[i].p.y);
	}
}

void DrawFPS()
{
	static DWORD fps = 0;
	static DWORD t = GetTickCount();
	static char str[64];
	
	if (++fps >= 100)
	{
		DWORD tt = GetTickCount();
		wsprintf(str, "FPS: %d", 100*1000/(tt-t));
		t = tt;
		fps = 0;
	}
	outtextxy(0, 0, str);
}

void main()
{
	initgraph(640, 600);
	setlinestyle(PS_SOLID, NULL, 3);
	
	// 设置初始位置和速度
	Init();
	
	MOUSEMSG m = GetMouseMsg();
	
	BeginBatchDraw();
	while (!kbhit() || getch() != 27) // 按ESC退出
	{
		while (MouseHit()) m = GetMouseMsg();
		
		for (int i = 0; i < ITER; i++) Update(m.x, m.y);
		cleardevice();
		Render();
		DrawFPS();
		FlushBatchDraw();
		Sleep(10);
	}
	
	EndBatchDraw();
	closegraph();
}
作者:frxyz1
作者个人主页:https://www.baidu.com/p/frxyz1
分享到

添加评论