scale 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /* finds node n with root attribute
  2. * finds distance minr of closest node
  3. * the layout is then scaled out from n so that
  4. * a node is put on the smallest circle of radius x*minr
  5. * containing n
  6. */
  7. BEG_G {
  8. node_t ctr;
  9. int cx, cy;
  10. int x, y;
  11. double delx, dely;
  12. int newx, newy;
  13. node_t n;
  14. edge_t e;
  15. int i, sc, d, mind = -1;
  16. double fact, newr, ang, minr;
  17. ctr = node($,aget($,"root"));
  18. sscanf (ctr.pos, "%d,%d", &cx, &cy);
  19. for (e = fstedge(ctr); e; e = nxtedge(e, ctr)) {
  20. if (e.head == ctr) n = e.tail;
  21. else n = e.head;
  22. sscanf (n.pos, "%d,%d", &x, &y);
  23. d = (x-cx)*(x-cx) + (y-cy)*(y-cy);
  24. if ((mind == -1) || (d < mind)) mind = d;
  25. }
  26. minr = (int)sqrt((double)mind);
  27. }
  28. N [$ != ctr] {
  29. sscanf ($.pos, "%d,%d", &x, &y);
  30. dely = y - cy;
  31. delx = x - cx;
  32. d = delx*delx + dely*dely;
  33. sc = (int)sqrt((double)(d/mind));
  34. if (sc > 1) {
  35. fact = 2.0;
  36. for (i=1; i<sc-1;i++) fact *= 2.0;
  37. newr = minr*(2.0 - (1.0/fact));
  38. ang = atan2 (dely, delx);
  39. newx = newr*cos(ang) + cx;
  40. newy = newr*sin(ang) + cy;
  41. $.pos = sprintf ("%d,%d", newx, newy);
  42. }
  43. }