示例#1
0
int user_pos(attrsym_t * posptr, attrsym_t * pinptr, node_t * np, int nG)
{
    double *pvec;
    char *p, c;
    double z;

    if (posptr == NULL)
	return FALSE;
    pvec = ND_pos(np);
    p = agxget(np, posptr->index);
    if (p[0]) {
	c = '\0';
	if ((Ndim >= 3) && 
            (sscanf(p, "%lf,%lf,%lf%c", pvec, pvec+1, pvec+2, &c) >= 3)){
	    ND_pinned(np) = P_SET;
	    if (PSinputscale > 0.0) {
		int i;
		for (i = 0; i < Ndim; i++)
		    pvec[i] = pvec[i] / PSinputscale;
	    }
	    if (Ndim > 3)
		jitter_d(np, nG, 3);
	    if ((c == '!')
		|| (pinptr && mapbool(agxget(np, pinptr->index))))
		ND_pinned(np) = P_PIN;
	    return TRUE;
	}
	else if (sscanf(p, "%lf,%lf%c", pvec, pvec + 1, &c) >= 2) {
	    ND_pinned(np) = P_SET;
	    if (PSinputscale > 0.0) {
		int i;
		for (i = 0; i < Ndim; i++)
		    pvec[i] = pvec[i] / PSinputscale;
	    }
	    if (Ndim > 2) {
		if (N_z && (p = agxget(np, N_z->index)) && 
                           (sscanf(p,"%lf",&z) == 1)) { 
		    if (PSinputscale > 0.0) {
			pvec[2] = z / PSinputscale;
		    }
		    else
			pvec[2] = z;
		    jitter_d(np, nG, 3);
		}
		else
		    jitter3d(np, nG);
	    }
	    if ((c == '!')
		|| (pinptr && mapbool(agxget(np, pinptr->index))))
		ND_pinned(np) = P_PIN;
	    return TRUE;
	} else
	    agerr(AGERR, "node %s, position %s, expected two doubles\n",
		  np->name, p);
    }
    return FALSE;
}
示例#2
0
文件: tlayout.c 项目: aosm/graphviz
static void
updatePos (Agraph_t* g, double temp, bport_t* pp)
{
  Agnode_t*    n;
  double       temp2;
  double       len2;
  double       x,y,d;
  double       dx,dy;

  temp2 = temp * temp;
  for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
    if (ND_pinned(n) & P_FIX) continue;
    dx = DISP(n)[0];
    dy = DISP(n)[1];
    len2 = dx*dx + dy*dy;

      /* limit by temperature */
    if (len2 < temp2) {
      x = ND_pos(n)[0] + dx;
      y = ND_pos(n)[1] + dy;
    }
    else {
      double fact = temp/(sqrt(len2));
      x = ND_pos(n)[0] + dx*fact;
      y = ND_pos(n)[1] + dy*fact;
    }
    
      /* if ports, limit by boundary */
    if (pp) {
      d = sqrt((x*x)/Wd2 + (y*y)/Ht2);
      if (IS_PORT(n)) {
        ND_pos(n)[0] = x/d;
        ND_pos(n)[1] = y/d;
      }
      else if (d >= 1.0) {
        ND_pos(n)[0] = 0.95*x/d;
        ND_pos(n)[1] = 0.95*y/d;
      }
      else {
        ND_pos(n)[0] = x;
        ND_pos(n)[1] = y;
      }
    }
    else {
      ND_pos(n)[0] = x;
      ND_pos(n)[1] = y;
    }
  }
}
示例#3
0
static void initialPositions(graph_t * g)
{
    int i;
    node_t *np;
    attrsym_t *possym;
    attrsym_t *pinsym;
    double *pvec;
    char *p;
    char c;

    possym = agfindattr(g->proto->n, "pos");
    if (!possym)
	return;
    pinsym = agfindattr(g->proto->n, "pin");
    for (i = 0; (np = GD_neato_nlist(g)[i]); i++) {
	p = agxget(np, possym->index);
	if (p[0]) {
	    pvec = ND_pos(np);
	    c = '\0';
	    if (sscanf(p, "%lf,%lf%c", pvec, pvec + 1, &c) >= 2) {
		if (PSinputscale > 0.0) {
		    int i;
		    for (i = 0; i < NDIM; i++)
			pvec[i] = pvec[i] / PSinputscale;
		}
		ND_pinned(np) = P_SET;
		if ((c == '!')
		    || (pinsym && mapbool(agxget(np, pinsym->index))))
		    ND_pinned(np) = P_PIN;
	    } else
		fprintf(stderr,
			"Warning: node %s, position %s, expected two floats\n",
			np->name, p);
	}
    }
}
示例#4
0
文件: tlayout.c 项目: aosm/graphviz
/* initPositions:
 * Create initial layout of nodes
 * TODO :
 *  Position nodes near neighbors with positions.
 *  Use bbox to reset K.
 */
static pointf
initPositions (graph_t* g, bport_t* pp)
{
  int       nG = agnnodes (g) - NPORTS (g);
  double    size;
  Agnode_t* np;
  int       n_pos = 0;  /* no. of nodes with position info */
  box       bb;
  pointf    ctr;        /* center of boundary ellipse */
  long      local_seed;
  double    PItimes2 = M_PI * 2.0;

  for (np = agfstnode(g); np; np = agnxtnode(g,np)) {
    if (ND_pinned(np)) {
      if (n_pos) {
        bb.LL.x = MIN(ND_pos(np)[0],bb.LL.x);
        bb.LL.y = MIN(ND_pos(np)[1],bb.LL.y);
        bb.UR.x = MAX(ND_pos(np)[0],bb.UR.x);
        bb.UR.y = MAX(ND_pos(np)[1],bb.UR.y);
      }
      else {
        bb.UR.x = bb.LL.x = ND_pos(np)[0];
        bb.UR.y = bb.LL.y = ND_pos(np)[1];
      }
      n_pos++;
    }
  }

  size = T_K * (sqrt((double)nG) + 1.0);
  Wd = Ht = expFactor*(size/2.0);
  if (n_pos == 1) {
    ctr.x = bb.LL.x;
    ctr.y = bb.LL.y;
  }
  else if (n_pos > 1) {
    double alpha, area, width, height, quot;
    ctr.x = (bb.LL.x + bb.UR.x)/2.0;
    ctr.y = (bb.LL.y + bb.UR.y)/2.0;
    width = expFactor*(bb.UR.x - bb.LL.x);
    height = expFactor*(bb.UR.y - bb.LL.y);
    area = 4.0*Wd*Ht;
    quot = (width*height)/area;
    if (quot >= 1.0) {   /* If bbox has large enough area, use it */
      Wd = width/2.0;
      Ht = height/2.0;
    }
    else if (quot > 0.0) {  /* else scale up to have enough area */
      quot = 2.0*sqrt(quot);
      Wd = width/quot;
      Ht = height/quot;
    }
    else {    /* either width or height is 0 */
      if (width > 0) {
        height = area/width;
        Wd = width/2.0;
        Ht = height/2.0;
      }
      else if (height > 0) {
        width = area/height;
        Wd = width/2.0;
        Ht = height/2.0;
      }
      /* If width = height = 0, use Wd and Ht as defined above for
       * the case the n_pos == 0.
       */
    }
    
      /* Construct enclosing ellipse */
    alpha = atan2 (Ht, Wd);
    Wd = Wd/cos(alpha);
    Ht = Ht/sin(alpha);
  }
  else {
    ctr.x = ctr.y = 0;
  }
  Wd2 = Wd*Wd;
  Ht2 = Ht*Ht;

    /* Set seed value */
  if (smode == seed_val) local_seed = T_seed;
  else {
#ifdef MSWIN32
    local_seed = time(NULL);
#else
    local_seed = getpid() ^ time(NULL);
#endif
  }
  srand48(local_seed);

  /* If ports, place ports on and nodes within an ellipse centered at origin
   * with halfwidth Wd and halfheight Ht. 
   * If no ports, place nodes within a rectangle centered at origin
   * with halfwidth Wd and halfheight Ht. Nodes with a given position
   * are translated. Wd and Ht are set to contain all positioned points.
   * The reverse translation will be applied to all
   * nodes at the end of the layout.
   * TODO: place unfixed points using adjacent ports or fixed pts.
   */
  if (pp) {
    while (pp->e) { /* position ports on ellipse */
      np = pp->n;
      ND_pos(np)[0] = Wd * cos(pp->alpha);
      ND_pos(np)[1] = Ht * sin(pp->alpha);
      ND_pinned(np) = P_SET;
      pp++;
    }
    for (np = agfstnode(g); np; np = agnxtnode(g,np)) {
      if (IS_PORT(np)) continue;
      if (ND_pinned(np)) {
        ND_pos(np)[0] -= ctr.x;
        ND_pos(np)[1] -= ctr.y;
      }
      else {
        double angle = PItimes2 * drand48();
        double radius = 0.9 * drand48();
        ND_pos(np)[0] = radius * Wd * cos(angle);
        ND_pos(np)[1] = radius * Ht * sin(angle);
      }
    }
  }
  else {
    if (n_pos) {  /* If positioned nodes */
      for (np = agfstnode(g); np; np = agnxtnode(g,np)) {
        if (ND_pinned(np)) {
          ND_pos(np)[0] -= ctr.x;
          ND_pos(np)[1] -= ctr.y;
        }
        else {
          ND_pos(np)[0] = Wd * (2.0*drand48() - 1.0);
          ND_pos(np)[1] = Ht * (2.0*drand48() - 1.0);
        }
      }
    }
    else {   /* No ports or positions; place randomly */
      for (np = agfstnode(g); np; np = agnxtnode(g,np)) {
        ND_pos(np)[0] = Wd * (2.0*drand48() - 1.0);
        ND_pos(np)[1] = Ht * (2.0*drand48() - 1.0);
      }
    }
  }

  return ctr;
}