/* is the nearest stem cell in range */
Boolean check_distance(struct distance_result nearest, 
				   	   double major_radius, 
				       double minor_radius, 
				       double thres) 
{
	if (nearest.nearest_distance == -1.0) {
		return 1;
	} else {
		double theta = tan(nearest.nearest_z/nearest.nearest_xy);
		double er = ellipse_radius(major_radius, minor_radius, theta);
		return (thres * er < nearest.nearest_distance);
	}
}
예제 #2
0
파일: ellipse.c 프로젝트: brunetton/dia
static void
ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert)
{
  Element *elem = &ellipse->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;
  Point center, bottom_right;
  Point p, c;
  real dw, dh;
  real width, height;
  real radius1, radius2;
  int i;

  /* save starting points */
  center = bottom_right = elem->corner;
  center.x += elem->width/2;
  bottom_right.x += elem->width;
  center.y += elem->height/2;
  bottom_right.y += elem->height;

  text_calc_boundingbox(ellipse->text, NULL);
  width = ellipse->text->max_width + 2 * ellipse->padding;
  height = ellipse->text->height * ellipse->text->numlines +
    2 * ellipse->padding;

  /* stop ellipse from getting infinite width/height */
  if (elem->width / elem->height > 4)
    elem->width = elem->height * 4;
  else if (elem->height / elem->width > 4)
    elem->height = elem->width * 4;

  c.x = elem->corner.x + elem->width / 2;
  c.y = elem->corner.y + elem->height / 2;
  p.x = c.x - width  / 2;
  p.y = c.y - height / 2;
  radius1 = ellipse_radius(ellipse, p.x, p.y) - ellipse->border_width/2;
  radius2 = distance_point_point(&c, &p);
  
  if (   radius1 < radius2
      && (   ellipse->text_fitting == TEXTFIT_ALWAYS
          || ellipse->text_fitting == TEXTFIT_WHEN_NEEDED)) {
    /* increase size of the ellipse while keeping its aspect ratio */
    elem->width  *= radius2 / radius1;
    elem->height *= radius2 / radius1;
  }

  /* move shape if necessary ... */
  switch (horiz) {
  case ANCHOR_MIDDLE:
    elem->corner.x = center.x - elem->width/2; break;
  case ANCHOR_END:
    elem->corner.x = bottom_right.x - elem->width; break;
  default:
    break;
  }
  switch (vert) {
  case ANCHOR_MIDDLE:
    elem->corner.y = center.y - elem->height/2; break;
  case ANCHOR_END:
    elem->corner.y = bottom_right.y - elem->height; break;
  default:
    break;
  }

  p = elem->corner;
  p.x += elem->width / 2.0;
  p.y += elem->height / 2.0 - ellipse->text->height*ellipse->text->numlines/2 +
    ellipse->text->ascent;
  switch (ellipse->text->alignment) {
  case ALIGN_LEFT:
    p.x -= (elem->width - 2*(ellipse->padding + ellipse->border_width))/2;
    break;
  case ALIGN_RIGHT:
    p.x += (elem->width - 2*(ellipse->padding + ellipse->border_width))/2;
    break;
  case ALIGN_CENTER:
    break;
  }
  text_set_position(ellipse->text, &p);

  /* Update connections: */
  c.x = elem->corner.x + elem->width / 2;
  c.y = elem->corner.y + elem->height / 2;
  dw = elem->width  / 2.0;
  dh = elem->height / 2.0;
  for (i = 0; i < NUM_CONNECTIONS-1; i++) {
    real theta = M_PI / 8.0 * i;
    real costheta = cos(theta);
    real sintheta = sin(theta);
    connpoint_update(&ellipse->connections[i],
		      c.x + dw * costheta,
		      c.y - dh * sintheta,
		      (costheta > .5?DIR_EAST:(costheta < -.5?DIR_WEST:0))|
		      (sintheta > .5?DIR_NORTH:(sintheta < -.5?DIR_SOUTH:0)));
  }
  connpoint_update(&ellipse->connections[16],
		   c.x, c.y, DIR_ALL);

  extra->border_trans = ellipse->border_width / 2.0;
  element_update_boundingbox(elem);

  obj->position = elem->corner;
  
  element_update_handles(elem);
}