// 多物体物理引擎.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<graphics.h>
#include <math.h>
#include <malloc.h>
#define PI 3.14159265
#define G 6.67259*10e-11
double val = 180.0 / PI;
struct OBB {
int radius;
double x, y;
double vx, vy;
int m;
double fx, fy;
double a;
};
struct vector {
double x;
double y;
};
OBB* initOBB(
int vx0, int vy0,
int radius,int b)//结构体指针函数,给出点,初始化OBB;
{
OBB* obb = (OBB*)malloc(sizeof(OBB));
obb->x = b%200;
obb->y = b%300;
if (obb->x < 30) { obb->x += 30; }
if (obb->y < 30) { obb->y += 30; }
if (600-(obb->x) < 30) { obb->x -= 30; }
if (500- (obb->y) < 30) { obb->y -= 30; }
obb->radius = radius;
obb->vx = vx0;
obb->vy = vy0;
/*printf("%d ", obb->vx);*/
return obb;
}
double distance(OBB* a1, OBB* a2) {
return sqrt(pow((a1->x - a2->x) ,2) + pow((a1->y - a2->y) ,2));
}
double angle(vector* v1,vector* v2){
double ret = (atan2(v1->y,v1->x)- atan2(v2->y, v2->x)) * val;
return ret;
}
//bool collapse(OBB* b1, OBB* b2) {
// if (distance(b1, b2) < double(b1->radius + b2->radius)) { return true; }
// else {return false; }
//}
vector sub(vector* v1, vector* v2) {
vector v0 = { v1->x - v2->x,v1->y - v2->y };
return v0;
}
double multiply(vector* v1, vector* v2) {
double mul = (v1->x * v2->x + v1->y * v2->y) / sqrt(pow(v2->x,2)+pow(v2->y,2));
return mul;
}
vector direct(vector* v) {
vector unit = {v->x/sqrt(pow(v->x,2)+pow(v->y,2)),v->y/ sqrt(pow(v->x,2) + pow(v->y,2)) };
if (fabs(unit.x * unit.y) > 0.000001) { return { unit.x,unit.y }; }
else { return{ 0,0 }; }
}
void conservation(OBB* obj1, OBB* obj2) {
vector vd = { obj2->y - obj1->y, obj2->x - obj1->x };
vector v1 = { obj1->vx,obj1->vy };
vector v2 = { obj2->vx,obj2->vy };
double v1x = multiply(&v1, &vd);
double v2x = multiply(&v2, &vd);
double v1xx = ((obj1->m - obj2->m) * v1x + 2 * obj2->m * v2x) / (obj1->m + obj2->m);
double v2xx= ((obj2->m - obj1->m) * v2x + 2 * obj1->m * v1x) / (obj1->m + obj2->m);
vector vec = direct(&vd);
vector vec1 = { vec.x * (v1xx - v1x),vec.y * (v1xx - v1x) };
vector vec2 = { vec.x * (v2xx - v2x),vec.y * (v2xx - v2x) };
obj1->vx += vec1.x;
obj1->vy += vec1.y;
obj2->vx += vec2.x;
obj2->vy += vec2.y;
}
void interaction(OBB* obj1, OBB* obj2) {
double ret = atan2(obj1->vy - obj2->vy, obj1->vx - obj2->vx)*val;
double r = distance(obj1, obj2);
vector f1, f2;
if (r > (obj1->radius + obj2->radius+3)) {
f1 = { G * obj2->m * obj1->m * cos(ret) / r * r,G * obj2->m * obj1->m * sin(ret) / r * r };
f2 = { G * obj2->m * obj1->m * cos(180 + ret) / r * r,G * obj2->m * obj1->m * sin(180 + ret) / r * r };
obj1->fx = f1.x;
obj1->fy = f1.y;
obj2->fx = f2.x;
obj2->fy = f2.y;
}
}
void move(OBB*obb1,OBB*obb2) {
while (1)
{
interaction(obb1,obb2);
obb1->x = obb1->x + obb1->vx;
obb1->y = obb1->y + obb1->vy;
obb2->x = obb2->x + obb2->vx;
obb2->y = obb2->y + obb2->vy;
if (distance(obb1, obb2) <= (obb1->radius + obb2->radius + 3)) {
obb1->x = obb1->x - obb1->vx;
obb1->y = obb1->y - obb1->vy;
obb2->x = obb2->x - obb2->vx;
obb2->y = obb2->y - obb2->vy;
conservation(obb1, obb2);
obb1->x = obb1->x + obb1->vx;
obb1->y = obb1->y + obb1->vy;
obb2->x = obb2->x + obb2->vx;
obb2->y = obb2->y + obb2->vy;
}
circle(obb2->x, obb2->y, obb2->radius);
circle(obb1->x, obb1->y, obb1->radius);
Sleep(1);
if (500 - obb1->y <= 30)
obb1->vy = -(obb1->vy);
if (600 - obb1->x <= 30)
obb1->vx = -(obb1->vx);
if (obb1->x <= 30)
obb1->vx = -(obb1->vx);
if (obb1->y <= 30)
obb1->vy = -(obb1->vy);
if (500 - obb2->y <= 30)
obb2->vy = -(obb2->vy);
if (600 - obb2->x <= 30)
obb2->vx = -(obb2->vx);
if (obb2->x <= 30)
obb2->vx = -(obb2->vx);
if (obb2->y <= 30)
obb2->vy = -(obb2->vy);
clearcircle(0, 0, 1000);
}
}
int main()
{
int i;
OBB* obj[2];
int a[2];
srand((unsigned)time(NULL));
for (i = 0; i<2; i++) {
a[i] = rand();
}
obj[0] = initOBB(2, -1, 35, a[0]);
obj[1] = initOBB(3, 2.5, 35, a[1]);
obj[0]->m = 1;
obj[1]->m = 1;
if (distance(obj[0], obj[1]) <= 70 ){
obj[1]->x = obj[1]->x + 2*obj[1]->radius+2*obj[2]->radius;
}
initgraph(600, 500);
move(obj[0],obj[1]);
getchar();
closegraph();
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 作者qq:2356224391,欢迎交流。
------------------------------版权所有:啾啾啾佳------------------------------------------
咕咕咕了好久 这几天终于狠心写了个物理引擎。
用了graphics库。引入向量,最主要的函数是conservation,把两球速度分解到球心连线上进行动量加能量守恒即可。预留了接口,可以扩展为多个物体