MyGUI
3.2.1
|
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