MyGUI  3.2.1
MyGUI_GeometryUtility.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_GeometryUtility.h"
00009 
00010 namespace MyGUI
00011 {
00012 
00013     namespace geometry_utility
00014     {
00015 
00016         VectorFloatPoint cropPolygon(FloatPoint* _baseVerticiesPos, size_t _size, const IntCoord& _cropRectangle)
00017         {
00018             VectorFloatPoint resultVerticiesPos;
00019             resultVerticiesPos.resize(_size);
00020             for (size_t i = 0; i < _size; ++i)
00021             {
00022                 resultVerticiesPos[i] = _baseVerticiesPos[i];
00023             }
00024 
00025             cropPolygonSide(resultVerticiesPos, _cropRectangle.left, Left);
00026             cropPolygonSide(resultVerticiesPos, _cropRectangle.right(), Right);
00027             cropPolygonSide(resultVerticiesPos, _cropRectangle.top, Top);
00028             cropPolygonSide(resultVerticiesPos, _cropRectangle.bottom(), Bottom);
00029 
00030             return resultVerticiesPos;
00031         }
00032 
00033         void cropPolygonSide(VectorFloatPoint& _verticies, int _sideCoord, Side _side)
00034         {
00035             VectorFloatPoint newVerticies;
00036             int invert = (_side == Right || _side == Bottom) ? -1 : 1;
00037             for (size_t i = 0; i < _verticies.size(); ++i)
00038             {
00039                 FloatPoint& v0 = _verticies[i];
00040                 FloatPoint& v1 = _verticies[(i + 1) % _verticies.size()];
00041                 switch (_side)
00042                 {
00043                 case Left:
00044                 case Right:
00045                     // both inside
00046                     if (invert * v0.left >= invert * _sideCoord && invert * v1.left >= invert * _sideCoord)
00047                         newVerticies.push_back(v0);
00048                     // intersect side (1st vertex in)
00049                     else if (invert * v0.left >= invert * _sideCoord && invert * v1.left < invert * _sideCoord)
00050                     {
00051                         newVerticies.push_back(v0);
00052                         float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
00053                         newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1)));
00054                     }
00055                     // intersect side (2nd vertex in)
00056                     else if (invert * v0.left <= invert * _sideCoord && invert * v1.left > invert * _sideCoord)
00057                     {
00058                         float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
00059                         newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1)));
00060                     }
00061                     // else don't add any verticies
00062                     break;
00063                 case Top:
00064                 case Bottom:
00065                     // both inside
00066                     if (invert * v0.top >= invert * _sideCoord && invert * v1.top >= invert * _sideCoord)
00067                         newVerticies.push_back(v0);
00068                     // intersect side (1st vertex in)
00069                     else if (invert * v0.top >= invert * _sideCoord && invert * v1.top < invert * _sideCoord)
00070                     {
00071                         newVerticies.push_back(v0);
00072                         float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
00073                         newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord));
00074                     }
00075                     // intersect side (2nd vertex in)
00076                     else if (invert * v0.top <= invert * _sideCoord && invert * v1.top > invert * _sideCoord)
00077                     {
00078                         float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
00079                         newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord));
00080                     }
00081                     // else don't add any verticies
00082                     break;
00083                 }
00084             }
00085 
00086             _verticies = newVerticies;
00087         }
00088 
00089         FloatPoint getPositionInsideRect(const FloatPoint& _point, const FloatPoint& _corner0, const FloatPoint& _corner1, const FloatPoint& _corner2)
00090         {
00091             FloatPoint result;
00092 
00093             FloatPoint point = _point - _corner0;
00094             FloatPoint dirX = _corner1 - _corner0;
00095             FloatPoint dirY = _corner2 - _corner0;
00096 
00097             float div = dirX.left * dirY.top - dirX.top * dirY.left;
00098             if (div == 0.0f)
00099                 return FloatPoint();
00100             return FloatPoint(
00101                 (point.top * dirX.left - point.left * dirX.top) / div,
00102                 (point.left * dirY.top - point.top * dirY.left) / div);
00103         }
00104 
00105         FloatPoint getUVFromPositionInsideRect(const FloatPoint& _point, const FloatPoint& _v0, const FloatPoint& _v1, const FloatPoint& _baseUV)
00106         {
00107             return FloatPoint(
00108                 _baseUV.left + _point.left * _v0.left + _point.top * _v1.left,
00109                 _baseUV.top  + _point.left * _v0.top  + _point.top * _v1.top);
00110         }
00111 
00112     } // namespace geometry_utility
00113 
00114 } // namespace MyGUI