MyGUI
3.2.0
|
00001 00006 /* 00007 This file is part of MyGUI. 00008 00009 MyGUI is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU Lesser General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 MyGUI is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 #include "MyGUI_Precompiled.h" 00023 #include "MyGUI_GeometryUtility.h" 00024 00025 namespace MyGUI 00026 { 00027 00028 namespace geometry_utility 00029 { 00030 00031 VectorFloatPoint cropPolygon(FloatPoint* _baseVerticiesPos, size_t _size, const IntCoord& _cropRectangle) 00032 { 00033 VectorFloatPoint resultVerticiesPos; 00034 resultVerticiesPos.resize(_size); 00035 for (size_t i = 0; i < _size; ++i) 00036 { 00037 resultVerticiesPos[i] = _baseVerticiesPos[i]; 00038 } 00039 00040 cropPolygonSide(resultVerticiesPos, _cropRectangle.left, Left); 00041 cropPolygonSide(resultVerticiesPos, _cropRectangle.right(), Right); 00042 cropPolygonSide(resultVerticiesPos, _cropRectangle.top, Top); 00043 cropPolygonSide(resultVerticiesPos, _cropRectangle.bottom(), Bottom); 00044 00045 return resultVerticiesPos; 00046 } 00047 00048 void cropPolygonSide(VectorFloatPoint& _verticies, int _sideCoord, Side _side) 00049 { 00050 VectorFloatPoint newVerticies; 00051 int invert = (_side == Right || _side == Bottom) ? -1 : 1; 00052 for (size_t i = 0; i < _verticies.size(); ++i) 00053 { 00054 FloatPoint& v0 = _verticies[i]; 00055 FloatPoint& v1 = _verticies[(i+1)%_verticies.size()]; 00056 switch (_side) 00057 { 00058 case Left: 00059 case Right: 00060 // both inside 00061 if (invert* v0.left >= invert* _sideCoord && invert* v1.left >= invert * _sideCoord) 00062 newVerticies.push_back(v0); 00063 // intersect side (1st vertex in) 00064 else if (invert* v0.left >= invert * _sideCoord && invert * v1.left < invert * _sideCoord) 00065 { 00066 newVerticies.push_back(v0); 00067 float c = (v0.left - _sideCoord) / (_sideCoord - v1.left); 00068 newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1))); 00069 } 00070 // intersect side (2nd vertex in) 00071 else if (invert* v0.left <= invert * _sideCoord && invert * v1.left > invert * _sideCoord) 00072 { 00073 float c = (v0.left - _sideCoord) / (_sideCoord - v1.left); 00074 newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1))); 00075 } 00076 // else don't add any verticies 00077 break; 00078 case Top: 00079 case Bottom: 00080 // both inside 00081 if (invert* v0.top >= invert* _sideCoord && invert* v1.top >= invert * _sideCoord) 00082 newVerticies.push_back(v0); 00083 // intersect side (1st vertex in) 00084 else if (invert* v0.top >= invert * _sideCoord && invert * v1.top < invert * _sideCoord) 00085 { 00086 newVerticies.push_back(v0); 00087 float c = (v0.top - _sideCoord) / (_sideCoord - v1.top); 00088 newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord)); 00089 } 00090 // intersect side (2nd vertex in) 00091 else if (invert* v0.top <= invert * _sideCoord && invert * v1.top > invert * _sideCoord) 00092 { 00093 float c = (v0.top - _sideCoord) / (_sideCoord - v1.top); 00094 newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord)); 00095 } 00096 // else don't add any verticies 00097 break; 00098 } 00099 } 00100 00101 _verticies = newVerticies; 00102 } 00103 00104 FloatPoint getPositionInsideRect(const FloatPoint& _point, const FloatPoint& _corner0, const FloatPoint& _corner1, const FloatPoint& _corner2) 00105 { 00106 FloatPoint result; 00107 00108 FloatPoint point = _point - _corner0; 00109 FloatPoint dirX = _corner1 - _corner0; 00110 FloatPoint dirY = _corner2 - _corner0; 00111 00112 float div = dirX.left * dirY.top - dirX.top * dirY.left; 00113 if (div == 0.0f) 00114 return FloatPoint(); 00115 return FloatPoint( 00116 (point.top * dirX.left - point.left * dirX.top) / div, 00117 (point.left * dirY.top - point.top * dirY.left) / div 00118 ); 00119 } 00120 00121 FloatPoint getUVFromPositionInsideRect(const FloatPoint& _point, const FloatPoint& _v0, const FloatPoint& _v1, const FloatPoint& _baseUV) 00122 { 00123 return FloatPoint( 00124 _baseUV.left + _point.left * _v0.left + _point.top * _v1.left, 00125 _baseUV.top + _point.left * _v0.top + _point.top * _v1.top 00126 ); 00127 } 00128 00129 } // namespace geometry_utility 00130 00131 } // namespace MyGUI