|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
#include "phisics.h"
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupUpdateCells(PhGroup *g)
|
|
Ivan Mahonin |
fdbd7d |
{ for(PhNode *n = g->first; n; n = n->next) phNodeUpdateCell(n); }
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupUnreg(PhGroup *g) {
|
|
Ivan Mahonin |
fdbd7d |
if (!g->ph) return;
|
|
Ivan Mahonin |
fdbd7d |
phGroupUpdateCells(g);
|
|
Ivan Mahonin |
fdbd7d |
*(g->prev ? &g->prev->next : &g->ph->first) = g->next;
|
|
Ivan Mahonin |
fdbd7d |
*(g->next ? &g->next->prev : &g->ph->last) = g->prev;
|
|
Ivan Mahonin |
fdbd7d |
g->prev = g->next = NULL;
|
|
Ivan Mahonin |
fdbd7d |
g->ph = NULL;
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupReg(PhGroup *g, Physics *ph) {
|
|
Ivan Mahonin |
fdbd7d |
if (g->ph == ph) return;
|
|
Ivan Mahonin |
fdbd7d |
phGroupUnreg(g);
|
|
Ivan Mahonin |
fdbd7d |
g->ph = ph;
|
|
Ivan Mahonin |
fdbd7d |
g->prev = ph->last;
|
|
Ivan Mahonin |
fdbd7d |
*(g->prev ? &g->prev->next : &ph->first) = ph->last = g;
|
|
Ivan Mahonin |
fdbd7d |
phGroupUpdateCells(g);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupRecalc(PhGroup *g) {
|
|
Ivan Mahonin |
fdbd7d |
g->cnt = 0;
|
|
Ivan Mahonin |
dcf1b6 |
g->I = 0;
|
|
Ivan Mahonin |
dcf1b6 |
g->go = vzero();
|
|
Ivan Mahonin |
fdbd7d |
for(PhNode *n = g->first; n; n = n->next)
|
|
Ivan Mahonin |
fdbd7d |
{ g->go = vadd(g->go, n->gp); ++g->cnt; }
|
|
Ivan Mahonin |
fdbd7d |
if (!g->cnt) return;
|
|
Ivan Mahonin |
fdbd7d |
g->go = vdiv(g->go, g->cnt);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
for(PhNode *n = g->first; n; n = n->next) {
|
|
Ivan Mahonin |
fdbd7d |
Vec d = vsub(n->gp, g->go);
|
|
Ivan Mahonin |
fdbd7d |
double d2 = vlen2(d);
|
|
Ivan Mahonin |
dcf1b6 |
g->I += d2;
|
|
Ivan Mahonin |
fdbd7d |
n->gk = d2 > PRECISION2 ? vdiv(d, d2) : vzero();
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
f8c4ae |
if (!(vlen2(g->dx) > PRECISION2)) g->dx = vec(1, 0);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupPlaceNodes(PhGroup* g) {
|
|
Ivan Mahonin |
fdbd7d |
for(PhNode *n = g->first; n; n = n->next) {
|
|
Ivan Mahonin |
fdbd7d |
n->p = phGroupTrans(g, n->gp);
|
|
Ivan Mahonin |
fdbd7d |
phNodeUpdateCell(n);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupFix(PhGroup *g, int fixangle) {
|
|
Ivan Mahonin |
fdbd7d |
if (!g->cnt) return;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
g->o = vzero();
|
|
Ivan Mahonin |
fdbd7d |
for(PhNode *n = g->first; n; n = n->next)
|
|
Ivan Mahonin |
fdbd7d |
g->o = vadd(g->o, n->p);
|
|
Ivan Mahonin |
fdbd7d |
g->o = vdiv(g->o, g->cnt);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (!fixangle) {
|
|
Ivan Mahonin |
fdbd7d |
Vec dx = {};
|
|
Ivan Mahonin |
fdbd7d |
for(PhNode *n = g->first; n; n = n->next)
|
|
Ivan Mahonin |
fdbd7d |
dx = vadd(dx, vuntrans(n->p, n->gk, g->o));
|
|
Ivan Mahonin |
fdbd7d |
double l = vlen(dx);
|
|
Ivan Mahonin |
fdbd7d |
if (l > PRECISION) g->dx = vdiv(dx, l);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
phGroupPlaceNodes(g);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
dcf1b6 |
void phGroupMove(PhGroup *g, Vec gp, Vec p, double rotRatio) {
|
|
Ivan Mahonin |
dcf1b6 |
if (rotRatio > PRECISION && g->I > PRECISION) {
|
|
Ivan Mahonin |
dcf1b6 |
Vec d = vsub(gp, g->go);
|
|
Ivan Mahonin |
dcf1b6 |
Vec dgp = vsub(phGroupUntrans(g, p), gp);
|
|
Ivan Mahonin |
dcf1b6 |
double da = vdot(vrot90(d), dgp)*g->cnt*rotRatio/g->I;
|
|
Ivan Mahonin |
dcf1b6 |
g->dx = vrot(g->dx, da);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
dcf1b6 |
g->o = vsub(p, vturn(vsub(gp, g->go), g->dx));
|
|
Ivan Mahonin |
fdbd7d |
phGroupPlaceNodes(g);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
void phGroupMerge(PhGroup *a, PhGroup *b) {
|
|
Ivan Mahonin |
fdbd7d |
if (a == b) return;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
PhNode *afirst = a->first, *bfirst = b->first;
|
|
Ivan Mahonin |
fdbd7d |
if (afirst && bfirst) {
|
|
Ivan Mahonin |
fdbd7d |
a->last->next = bfirst;
|
|
Ivan Mahonin |
fdbd7d |
b->first->prev = a->last;
|
|
Ivan Mahonin |
fdbd7d |
a->last = b->last;
|
|
Ivan Mahonin |
fdbd7d |
} else
|
|
Ivan Mahonin |
fdbd7d |
if (!afirst) { a->first = bfirst; a->last = b->last; }
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
b->first = b->last = NULL;
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
for(PhNode *n = bfirst; n; n = n->next) {
|
|
Ivan Mahonin |
fdbd7d |
n->group = a;
|
|
Ivan Mahonin |
fdbd7d |
if (a->ph != b->ph) phNodeUpdateCell(n);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
if (!afirst) { a->cnt = b->cnt; a->go = b->go; } else
|
|
Ivan Mahonin |
fdbd7d |
if (bfirst) phGroupRecalc(a);
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
phGroupRecalc(b);
|
|
Ivan Mahonin |
fdbd7d |
phGroupUnreg(b);
|
|
Ivan Mahonin |
fdbd7d |
}
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|
|
Ivan Mahonin |
fdbd7d |
|