Logo Search packages:      
Sourcecode: inkscape version File versions

double unclump_dist ( SPItem item1,
SPItem item2 
)

Distance between "edges" of item1 and item2. An item is considered to be an ellipse inscribed into its w/h, so its radius (distance from center to edge) depends on the w/h and the angle towards the other item. May be negative if the edge of item1 is between the center and the edge of item2.

Definition at line 71 of file unclump.cpp.

References unclump_center().

Referenced by unclump(), unclump_average(), unclump_closest(), and unclump_farest().

{
      Geom::Point c1 = unclump_center (item1);
      Geom::Point c2 = unclump_center (item2);

      Geom::Point wh1 = unclump_wh (item1);
      Geom::Point wh2 = unclump_wh (item2);

      // angle from each item's center to the other's, unsqueezed by its w/h, normalized to 0..pi/2
      double a1 = atan2 ((c2 - c1)[Geom::Y], (c2 - c1)[Geom::X] * wh1[Geom::Y]/wh1[Geom::X]);
      a1 = fabs (a1);
      if (a1 > M_PI/2) a1 = M_PI - a1;

      double a2 = atan2 ((c1 - c2)[Geom::Y], (c1 - c2)[Geom::X] * wh2[Geom::Y]/wh2[Geom::X]);
      a2 = fabs (a2);
      if (a2 > M_PI/2) a2 = M_PI - a2;

      // get the radius of each item for the given angle
      double r1 = 0.5 * (wh1[Geom::X] + (wh1[Geom::Y] - wh1[Geom::X]) * (a1/(M_PI/2)));
      double r2 = 0.5 * (wh2[Geom::X] + (wh2[Geom::Y] - wh2[Geom::X]) * (a2/(M_PI/2)));

      // dist between centers minus angle-adjusted radii
      double dist_r =  (Geom::L2 (c2 - c1) - r1 - r2);

      double stretch1 = wh1[Geom::Y]/wh1[Geom::X];
      double stretch2 = wh2[Geom::Y]/wh2[Geom::X];

      if ((stretch1 > 1.5 || stretch1 < 0.66) && (stretch2 > 1.5 || stretch2 < 0.66)) {

            std::vector<double> dists;
            dists.push_back (dist_r);

            // If both objects are not circle-like, find dists between four corners
            std::vector<Geom::Point> c1_points(2);
            {
                  double y_closest;
                  if (c2[Geom::Y] > c1[Geom::Y] + wh1[Geom::Y]/2) {
                        y_closest = c1[Geom::Y] + wh1[Geom::Y]/2;
                  } else if (c2[Geom::Y] < c1[Geom::Y] - wh1[Geom::Y]/2) {
                        y_closest = c1[Geom::Y] - wh1[Geom::Y]/2;
                  } else {
                        y_closest = c2[Geom::Y];
                  }
                  c1_points[0] = Geom::Point (c1[Geom::X], y_closest);
                  double x_closest;
                  if (c2[Geom::X] > c1[Geom::X] + wh1[Geom::X]/2) {
                        x_closest = c1[Geom::X] + wh1[Geom::X]/2;
                  } else if (c2[Geom::X] < c1[Geom::X] - wh1[Geom::X]/2) {
                        x_closest = c1[Geom::X] - wh1[Geom::X]/2;
                  } else {
                        x_closest = c2[Geom::X];
                  }
                  c1_points[1] = Geom::Point (x_closest, c1[Geom::Y]);
            }


            std::vector<Geom::Point> c2_points(2);
            {
                  double y_closest;
                  if (c1[Geom::Y] > c2[Geom::Y] + wh2[Geom::Y]/2) {
                        y_closest = c2[Geom::Y] + wh2[Geom::Y]/2;
                  } else if (c1[Geom::Y] < c2[Geom::Y] - wh2[Geom::Y]/2) {
                        y_closest = c2[Geom::Y] - wh2[Geom::Y]/2;
                  } else {
                        y_closest = c1[Geom::Y];
                  }
                  c2_points[0] = Geom::Point (c2[Geom::X], y_closest);
                  double x_closest;
                  if (c1[Geom::X] > c2[Geom::X] + wh2[Geom::X]/2) {
                        x_closest = c2[Geom::X] + wh2[Geom::X]/2;
                  } else if (c1[Geom::X] < c2[Geom::X] - wh2[Geom::X]/2) {
                        x_closest = c2[Geom::X] - wh2[Geom::X]/2;
                  } else {
                        x_closest = c1[Geom::X];
                  }
                  c2_points[1] = Geom::Point (x_closest, c2[Geom::Y]);
            }

            for (int i = 0; i < 2; i ++) {
                  for (int j = 0; j < 2; j ++) {
                        dists.push_back (Geom::L2 (c1_points[i] - c2_points[j]));
                  }
            }

            // return the minimum of all dists
            return *std::min_element(dists.begin(), dists.end());
      } else {
            return dist_r;
      }
}


Generated by  Doxygen 1.6.0   Back to index