"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/ggadget/math_utils.h" (9 Jun 2009, 12045 Bytes) of package /linux/misc/old/google-gadgets-for-linux-0.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2   Copyright 2008 Google Inc.
    3 
    4   Licensed under the Apache License, Version 2.0 (the "License");
    5   you may not use this file except in compliance with the License.
    6   You may obtain a copy of the License at
    7 
    8        http://www.apache.org/licenses/LICENSE-2.0
    9 
   10   Unless required by applicable law or agreed to in writing, software
   11   distributed under the License is distributed on an "AS IS" BASIS,
   12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13   See the License for the specific language governing permissions and
   14   limitations under the License.
   15 */
   16 
   17 #ifndef GGADGET_MATH_UTILS_H__
   18 #define GGADGET_MATH_UTILS_H__
   19 
   20 namespace ggadget {
   21 
   22 /**
   23  * @defgroup MathUtilities Math utilities
   24  * @ingroup Utilities
   25  * @{
   26  */
   27 
   28 /**
   29  * Converts coordinates in a parent element's space to coordinates in a
   30  * child element.
   31  * @param parent_x X-coordinate in the parent space to convert.
   32  * @param parent_y Y-coordinate in the parent space to convert.
   33  * @param child_x_pos X-coordinate of the child pin point in parent space.
   34  * @param child_y_pos Y-coordinate of the child pin point in parent space.
   35  * @param child_pin_x X-coordinate of the child rotation pin in child space.
   36  * @param child_pin_y Y-coordinate of the child rotation pin in child space.
   37  * @param rotation_radians The rotation of the child element in radians.
   38  * @param[out] child_x Parameter to store the converted child X-coordinate.
   39  * @param[out] child_y Parameter to store the converted child Y-coordinate.
   40  */
   41 void ParentCoordToChildCoord(double parent_x, double parent_y,
   42                              double child_x_pos, double child_y_pos,
   43                              double child_pin_x, double child_pin_y,
   44                              double rotation_radians,
   45                              double *child_x, double *child_y);
   46 
   47 /**
   48  * Reversed function of the above function.
   49  * @param child_x X-coordinate in the child space to convert.
   50  * @param child_y Y-coordinate in the child space to convert.
   51  * @param child_x_pos X-coordinate of the child pin point in parent space.
   52  * @param child_y_pos Y-coordinate of the child pin point in parent space.
   53  * @param child_pin_x X-coordinate of the child rotation pin in child space.
   54  * @param child_pin_y Y-coordinate of the child rotation pin in child space.
   55  * @param rotation_radians The rotation of the child element in radians.
   56  * @param[out] parent_x Parameter to store the converted parent X-coordinate.
   57  * @param[out] parent_y Parameter to store the converted parent Y-coordinate.
   58  */
   59 void ChildCoordToParentCoord(double child_x, double child_y,
   60                              double child_x_pos, double child_y_pos,
   61                              double child_pin_x, double child_pin_y,
   62                              double rotation_radians,
   63                              double *parent_x, double *parent_y);
   64 
   65 /**
   66  * Calculate the maximum parent extent of a child.
   67  * @param child_x_pos X-coordinate of the child pin point in parent space.
   68  * @param child_y_pos Y-coordinate of the child pin point in parent space.
   69  * @param child_pin_x X-coordinate of the child rotation pin in child space.
   70  * @param child_pin_y Y-coordinate of the child rotation pin in child space.
   71  * @param child_width
   72  * @param child_height
   73  * @param rotation_radians The rotation of the child element in radians.
   74  * @param[out] extent_right The maximum X-coordinate of the child rect
   75  *     in parent space.
   76  * @param[out] extent_bottom The maximum Y-coordinate of the child rect
   77  *     in parent space.
   78  */
   79 void GetChildExtentInParent(double child_x_pos, double child_y_pos,
   80                             double child_pin_x, double child_pin_y,
   81                             double child_width, double child_height,
   82                             double rotation_radians,
   83                             double *extent_right, double *extent_bottom);
   84 
   85 /**
   86  * Extended version of the above function. Calculate the extent rectangle
   87  * in parent for a rectangle in child.
   88  */
   89 void GetChildRectExtentInParent(double child_x_pos, double child_y_pos,
   90                                 double child_pin_x, double child_pin_y,
   91                                 double rotation_radians,
   92                                 double left_in_child, double top_in_child,
   93                                 double right_in_child, double bottom_in_child,
   94                                 double *extent_left, double *extent_top,
   95                                 double *extent_right, double *extent_bottom);
   96 
   97 /**
   98  * Calculator object used to convert a parent element's coordinate space to
   99  * that of a child element. This struct is a better choice if the multiple
  100  * coordinate conversions need to be done for the same child element.
  101  */
  102 class ChildCoordCalculator {
  103  public:
  104   /**
  105    * Constructs the coordinate calculator object.
  106    * @param child_x_pos X-coordinate of the child pin point in parent space.
  107    * @param child_y_pos Y-coordinate of the child pin point in parent space.
  108    * @param child_pin_x X-coordinate of the child rotation pin in child space.
  109    * @param child_pin_y Y-coordinate of the child rotation pin in child space.
  110    * @param rotation_radians The rotation of the child element in radians.
  111    */
  112   ChildCoordCalculator(double child_x_pos, double child_y_pos,
  113                        double child_pin_x, double child_pin_y,
  114                        double rotation_radians);
  115 
  116   /**
  117    * Converts coordinates the given coordinates.
  118    * @param parent_x X-coordinate in the parent space to convert.
  119    * @param parent_y Y-coordinate in the parent space to convert.
  120    * @param[out] child_x Parameter to store the converted child X-coordinate.
  121    * @param[out] child_y Parameter to store the converted child Y-coordinate.
  122    */
  123   void Convert(double parent_x, double parent_y,
  124                double *child_x, double *child_y);
  125 
  126   /**
  127    * @param parent_x X-coordinate in the parent space to convert.
  128    * @param parent_y Y-coordinate in the parent space to convert.
  129    * @return The converted child X-coordinate.
  130    */
  131   double GetChildX(double parent_x, double parent_y);
  132 
  133   /**
  134    * @param parent_x X-coordinate in the parent space to convert.
  135    * @param parent_y Y-coordinate in the parent space to convert.
  136    * @return The converted child Y-coordinate.
  137    */
  138   double GetChildY(double parent_x, double parent_y);
  139 
  140  private:
  141   double sin_theta_, cos_theta_;
  142   double a_13_, a_23_;
  143 };
  144 
  145 /**
  146  * Calculator object used to convert a child element's coordinate space to
  147  * that of the parent element. This struct is a better choice if the multiple
  148  * coordinate conversions need to be done for the same child element.
  149  */
  150 class ParentCoordCalculator {
  151  public:
  152   /**
  153    * Constructs the coordinate calculator object.
  154    * @param child_x_pos X-coordinate of the child pin point in parent space.
  155    * @param child_y_pos Y-coordinate of the child pin point in parent space.
  156    * @param child_pin_x X-coordinate of the child rotation pin in child space.
  157    * @param child_pin_y Y-coordinate of the child rotation pin in child space.
  158    * @param rotation_radians The rotation of the child element in radians.
  159    */
  160   ParentCoordCalculator(double child_x_pos, double child_y_pos,
  161                         double child_pin_x, double child_pin_y,
  162                         double rotation_radians);
  163 
  164   /**
  165    * Converts child coordinates into parent coordinations.
  166    * @param child_x X-coordinate in the child space to convert.
  167    * @param child_y Y-coordinate in the child space to convert.
  168    * @param[out] parent_x Parameter to store the converted parent X-coordinate.
  169    * @param[out] parent_y Parameter to store the converted parent Y-coordinate.
  170    */
  171   void Convert(double child_x, double child_y,
  172                double *parent_x, double *parent_y);
  173   /**
  174    * @param child_x X-coordinate in the child space to convert.
  175    * @param child_y Y-coordinate in the child space to convert.
  176    * @return The converted parent X-coordinate.
  177    */
  178   double GetParentX(double child_x, double child_y);
  179 
  180   /**
  181    * @param child_x X-coordinate in the child space to convert.
  182    * @param child_y Y-coordinate in the child space to convert.
  183    * @return The converted parent Y-coordinate.
  184    */
  185   double GetParentY(double child_x, double child_y);
  186 
  187  private:
  188   double sin_theta_, cos_theta_;
  189   double x0_, y0_;
  190 };
  191 
  192 /**
  193  * @return The radian measure of the input parameter.
  194  */
  195 double DegreesToRadians(double degrees);
  196 /**
  197  * @return The degree measure of the input parameter.
  198  */
  199 double RadiansToDegrees(double radians);
  200 
  201 /**
  202  * Checks to see if the given (x, y) is contained in an element.
  203  * @param x X-coordinate of the element's (0, 0) point in parent space.
  204  * @param y Y-coordinate of the element's (0, 0) point in parent space.
  205  * @param width Width of element.
  206  * @param height Height of element.
  207  */
  208 bool IsPointInElement(double x, double y, double width, double height);
  209 
  210 
  211 /** A class represents a rectangle. */
  212 class Rectangle {
  213  public:
  214   Rectangle() : x(0), y(0), w(0), h(0) { }
  215 
  216   Rectangle(double ax, double ay, double aw, double ah)
  217     : x(ax), y(ay), w(aw), h(ah) {
  218   }
  219 
  220   bool operator==(const Rectangle &rect) const {
  221     return x == rect.x && y == rect.y && w == rect.w && h == rect.h;
  222   }
  223 
  224   /**
  225    * Calculates the union of two rectangles, and stores the result into this
  226    * rectangle.
  227    */
  228   void Union(const Rectangle &rect);
  229 
  230   /**
  231    * Calculates the intersection of two rectangles, and stores the result into
  232    * this rectangle.
  233    *
  234    * If they do not intersect with each other, false will be returned and this
  235    * rectangle will not change.
  236    */
  237   bool Intersect(const Rectangle &rect);
  238 
  239   /**
  240    * Integerize the rectangle region. That means to make the coordinates of the
  241    * vertexes be integer. This is useful since clip operation may time wasted
  242    * if the region is not integer.
  243    *
  244    * @param expand if @c true, the method ensures the result rectangle contains
  245    *     the original one; otherwise the coordinates are simply rounded.
  246    */
  247   void Integerize(bool expand);
  248 
  249   /**
  250    * Checks if two rectangles are overlapped.
  251    * @param other the other rectangle we are interested in.
  252    * @return @true if they are overlapped and false otherwise
  253    */
  254   bool Overlaps(const Rectangle &another) const;
  255 
  256   /**
  257    * Checks if this rectangle is inside the other one.
  258    * @param other the other rectangle we are interested in.
  259    * @return @true if this rectangle is inside the other one.
  260    */
  261   bool IsInside(const Rectangle &another) const {
  262     return x >= another.x && (x + w) <= (another.x + another.w) &&
  263            y >= another.y && (y + h) <= (another.y + another.h);
  264   }
  265 
  266   /**
  267    * Judge if a point is in the rectangle.
  268    * @param x X-coordinate of the point
  269    * @param y Y-coordinate of the point
  270    * @return @true if the point is in and false otherwise
  271    */
  272   bool IsPointIn(double px, double py) const {
  273     return px >= x && py >= y && px < x + w && py < y + h;
  274   }
  275 
  276   /** Set the rectangle parameters. */
  277   void Set(double ax, double ay, double aw, double ah) {
  278     x = ax;
  279     y = ay;
  280     w = aw;
  281     h = ah;
  282   }
  283 
  284   /** Reset the rectangle to all zero state. */
  285   void Reset() {
  286     x = y = w = h = 0;
  287   }
  288 
  289   /** Zoom the rectangle by a specified zoom fector. */
  290   void Zoom(double zoom) {
  291     x *= zoom;
  292     y *= zoom;
  293     w *= zoom;
  294     h *= zoom;
  295   }
  296 
  297   bool IsEmpty() const {
  298     return w == 0 && h == 0;
  299   }
  300 
  301  public:
  302   /**
  303    * Gets the extents of a polygon represented by a set of vertexes.
  304    *
  305    * @param n number of vertexes.
  306    * @param vertexes coordinates of the vertexes, format: x0, y0, x1, y1, ...
  307    *        it must have 2 * n elements.
  308    * @return the extents rectangle of the polygon.
  309    */
  310   static Rectangle GetPolygonExtents(size_t n, const double *vertexes);
  311 
  312  public:
  313   double x, y, w, h;
  314 };
  315 
  316 /**
  317  * Returns val if low < val < high, otherwise returns low if val <= low or high
  318  * if val >= high.
  319  */
  320 template<typename T>
  321 T Clamp(T val, T low, T high) {
  322   return val > high ? high : (val < low ? low : val);
  323 }
  324 
  325 /** @} */
  326 
  327 } // namespace ggadget
  328 
  329 #endif // GGADGET_MATH_UTILS_H__