IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++ 2D小球 碰撞模拟 -> 正文阅读

[C++知识库]c++ 2D小球 碰撞模拟

一个简单的2D小球碰撞模拟程序,代码不长主程序90多行。

全部用c++实现,借助easyx绘图,同时实现简单向量类便于计算 (默认小球质量相同 大小相同)。

#include <iostream>
#include <easyx.h>
#include <conio.h>
#include <algorithm>
#include <vector>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include "Vector2D.h"//2D向量头
#include "CollisionBox.h"//只有一个球
using namespace std;
const int WIDTH = 1100;
const int HEIGHT = 600;

void CollisionCheck(vector<Ball> &v) {																							  							//碰撞检测
				/****************为简化模型  视小球为  “一动一静” ********************************/
	for (int i = 0; i < v.size(); i++) {
		for (int j = i + 1; j < v.size(); j++) {
			if (pow(v[i].x - v[j].x, 2) + pow(v[i].y - v[j].y, 2) <= 4.0 * v[i].r*v[i].r) {
				Vector2D vv(v[i].vx - v[j].vx, v[i].vy - v[j].vy);	//和速度向量
				Vector2D v1, v2;									//小球1速度向量、小球2速度向量

				/*****************根据两球坐标计算两球碰撞球心连线的向量(方向)**********************/

				Vector2D t1(v[i].x, v[i].y), t2(v[j].x, v[j].y);
				v2 = t2 - t1;
				double angle = Angle(vv, v2);						//得到球心连线与和速度夹角
				double k = Len(vv)*cos(Rad(angle)) / Len(v2);
																	
				v2.x *= k;											//得到小球2的速度向量
				v2.y *= k;
				v1 = vv - v2;										//计算得到小球1的速度向量

				/******************至此已经计算出碰撞后两小球的相对运动状态*************************/

				v[i].vx = v1.x + v[j].vx;							//再加上之前的速度是因为计算过程是将一个球看做静态来计算的
				v[i].vy = v1.y + v[j].vy;
				v[j].vx += v2.x;
				v[j].vy += v2.y;
			}
		}
	}
}
void WallCheck(vector<Ball> &v) {
	for (int i = 0; i < v.size(); i++) {
		if (v[i].x + v[i].r >= WIDTH) v[i].vx *= -1;		//右壁
		else if (v[i].y - v[i].r <= 0) v[i].vy *= -1;		//上壁
		else if (v[i].x - v[i].r <= 0) v[i].vx *= -1;		//左壁
		else if (v[i].y + v[i].r >= HEIGHT) v[i].vy *= -1;	//下壁
	}
}
void CreatBall(vector<Ball> &v) {
	srand((unsigned int)time(NULL));
	for (int i = 0; i < 10; i++) {					//随机生成10个小球
		double x, y, r = 20, vx, vy;
		bool f = 1;
		while (f) {
			f = 0;
			x = (rand() % (WIDTH - 2 * (int)r))*1.0 + r;
			y = (rand() % (HEIGHT - 2 * (int)r))*1.0 + r;

			for (int j = 0; j < v.size(); j++) {	//要保证生成的位置不重叠
				if (pow(v[j].x - x, 2) + pow(v[j].y - y, 2) <= 4.0 * pow(v[j].r, 2)) {
					f = 1;
				}
			}
			if (!f) {
				vx = rand() % 6;					//速度太快会粘到一起......汗
				vy = rand() % 6;
				Ball t(x, y, r, vx, vy);
				v.push_back(t);
			}
		}
	}
}
int main() {
	initgraph(WIDTH, HEIGHT);
	vector<Ball> v;
	CreatBall(v);
	while (1) {
		BeginBatchDraw();
		for (int i = 0; i < v.size(); i++) solidcircle(v[i].x, v[i].y, v[i].r);
		CollisionCheck(v);
		WallCheck(v);
		for (int i = 0; i <= 10000000; i++);		//适当延时
		EndBatchDraw();
		cleardevice();
		for (int i = 0; i < v.size(); i++) {
			v[i].x += v[i].vx;
			v[i].y += v[i].vy;
		}
		
	}
	closegraph();
	return 0;
}

头文件:
Vector2D.h

#pragma once
#include<cmath>
const double PI = 3.1415926;
//转角度
double Deg(double rad) { return rad * 180.0 / PI; }
//转弧度
double Rad(double deg) { return deg / 180.0 * PI; }
/*2D向量头*/
struct Vector2D {
	Vector2D() :x(), y() {};
	Vector2D(double px, double py) :x(px), y(py) {};

	double x, y;

	Vector2D operator + (const Vector2D &b)const {//减法
		return Vector2D(this->x + b.x, this->y + b.y);
	}
	Vector2D operator - (const Vector2D &b)const {//加法
		return Vector2D(this->x - b.x, this->y - b.y);
	}
	Vector2D operator () (double px, double py) {
		this->x = px, this->y = py;
		return *this;
	}
	double operator * (const Vector2D &b)const {//向量内积
		return (this->x * b.x + this->y * b.y);
	}
};

double Len(const Vector2D &a) {//向量的模
	return sqrt(a.x*a.x + a.y*a.y);
}
double Angle(const Vector2D &a, const Vector2D &b) {//两个向量夹角
	return Deg(acos(a*b / (Len(a)*Len(b))));
}

CollisionBox.h

#pragma once
struct Ball {
	double x, y, r;
	double vx, vy;		//x、y轴的的方向向量
	Ball() :x(), y(), r(), vx(), vy() {}
	Ball(double sx, double sy, double sr = 30.0, double svx = 3.0, double svy = 0.0):
		x(sx), y(sy), r(sr), vx(svx), vy(svy) {}
};
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-31 16:26:28  更:2021-07-31 16:28:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/27 19:18:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码