Пример #1
0
/*! \brief Calculates the distance between the given point and the closest
 * point on the perimeter of the box.
 *
 *  \param [in] object       The box OBJECT.
 *  \param [in] x            The x coordinate of the given point.
 *  \param [in] y            The y coordinate of the given point.
 *  \param [in] force_solid  If true, force treating the object as solid.
 *  \return The shortest distance from the object to the point. With an
 *  invalid parameter, this function returns G_MAXDOUBLE.
 */
double o_box_shortest_distance (OBJECT *object, int x, int y, int force_solid)
{
  int solid;

  g_return_val_if_fail (object->box != NULL, G_MAXDOUBLE);

  solid = force_solid || object->fill_type != FILLING_HOLLOW;

  return m_box_shortest_distance (object->box, x, y, solid);
}
Пример #2
0
/*! \brief Calculates the distance between the given point and the closest
 * point on an object within the complex object.
 *
 *  \note When querying the distance to our child objects, we always
 *        force treating them as solid filled.
 *        We ignore the force_solid argument to this function.
 *
 *  \param [in] object       The complex  OBJECT.
 *  \param [in] x            The x coordinate of the given point.
 *  \param [in] y            The y coordinate of the given point.
 *  \param [in] force_solid  If true, force treating the object as solid.
 *  \return The shortest distance from the object to the point. If the
 *  distance cannot be calculated, this function returns a really large
 *  number (G_MAXDOUBLE).  With an invalid parameter, this function returns
 *  G_MAXDOUBLE.
 */
double o_complex_shortest_distance (OBJECT *object, int x, int y,
                                    int force_solid)
{
  double shortest_distance = G_MAXDOUBLE;
  double distance;
  int found_line_bounds = 0;
  BOX line_bounds;
  GList *iter;

  g_return_val_if_fail (object->complex != NULL, G_MAXDOUBLE);

  for (iter = object->complex->prim_objs;
       iter != NULL; iter= g_list_next (iter)) {
    OBJECT *obj = iter->data;

    /* Collect the bounds of any lines and arcs in the symbol */
    if ((obj->type == OBJ_LINE || obj->type == OBJ_ARC) &&
        obj->w_bounds_valid) {

      if (found_line_bounds) {
        line_bounds.lower_x = min (line_bounds.lower_x, obj->w_left);
        line_bounds.lower_y = min (line_bounds.lower_y, obj->w_top);
        line_bounds.upper_x = max (line_bounds.upper_x, obj->w_right);
        line_bounds.upper_y = max (line_bounds.upper_y, obj->w_bottom);
      } else {
        line_bounds.lower_x = obj->w_left;
        line_bounds.lower_y = obj->w_top;
        line_bounds.upper_x = obj->w_right;
        line_bounds.upper_y = obj->w_bottom;
        found_line_bounds = 1;
      }
    } else {
      distance = o_shortest_distance_full (obj, x, y, TRUE);
      shortest_distance = min (shortest_distance, distance);
    }

    if (shortest_distance == 0.0)
      return shortest_distance;
  }

  if (found_line_bounds) {
    distance = m_box_shortest_distance (&line_bounds, x, y, TRUE);
    shortest_distance = min (shortest_distance, distance);
  }

  return shortest_distance;
}