Blame projects/jigsaw/phisics.group.c

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 fdbd7d
  g->go.x = g->go.y = 0;
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 fdbd7d
    n->gk = d2 > PRECISION2 ? vdiv(d, d2) : vzero();
Ivan Mahonin fdbd7d
  }
Ivan Mahonin fdbd7d
  
Ivan Mahonin fdbd7d
  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 fdbd7d
void phGroupMove(PhGroup *g, Vec gp, Vec p, int fixangle) {
Ivan Mahonin fdbd7d
  if (fixangle) {
Ivan Mahonin fdbd7d
    g->o = vadd(g->o, vsub(p, phGroupTrans(g, gp)));
Ivan Mahonin fdbd7d
    phGroupPlaceNodes(g);
Ivan Mahonin fdbd7d
    return;
Ivan Mahonin fdbd7d
  }
Ivan Mahonin fdbd7d
Ivan Mahonin fdbd7d
  Vec d = vsub(p, g->o);
Ivan Mahonin fdbd7d
  Vec gd = vsub(gp, g->go);
Ivan Mahonin fdbd7d
  double l = vlen(d);
Ivan Mahonin fdbd7d
  double gl = vlen(gd);
Ivan Mahonin fdbd7d
Ivan Mahonin fdbd7d
  if (l > PRECISION) {
Ivan Mahonin fdbd7d
    g->o = vsub(p, vmul(d, gl/l));
Ivan Mahonin fdbd7d
    if (!(gl > PRECISION)) return;
Ivan Mahonin fdbd7d
  } else {
Ivan Mahonin fdbd7d
    g->o.x = p.x - gl;
Ivan Mahonin fdbd7d
    g->o.y = p.y;
Ivan Mahonin fdbd7d
    return;
Ivan Mahonin fdbd7d
  }
Ivan Mahonin fdbd7d
  
Ivan Mahonin fdbd7d
  g->dx = vunturn(d, vdiv(gd, l*gl));
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