个人作品

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

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

一个模拟橡皮筋的程序。

执行效果:

以下是全部源代码:

///////////////////////////////////////////////////
// 程序名称:模拟橡皮筋
// 编译环境:Visual C++ 6.0 / 2010,EasyX_20200315(beta)
// 作  者:frxyz1 <http://hi.baidu.com/frxyz1>
// 最后修改:2012-4-15
//
#include <graphics.h>
#include <conio.h>
#include <stdio.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 TCHAR str[64];

	if (++fps >= 100)
	{
		DWORD tt = GetTickCount();
		_stprintf(str, _T("FPS: %d"), 100 * 1000 / (tt - t));
		t = tt;
		fps = 0;
	}
	outtextxy(0, 0, str);
}

void main()
{
	initgraph(640, 600);
	BeginBatchDraw();
	setlinestyle(PS_SOLID, 3);

	// 设置初始位置和速度
	Init();

	MOUSEMSG m = GetMouseMsg();

	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