MyGUI  3.2.0
MyGUI_GeometryUtility.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_GeometryUtility.h"
24 
25 namespace MyGUI
26 {
27 
28  namespace geometry_utility
29  {
30 
31  VectorFloatPoint cropPolygon(FloatPoint* _baseVerticiesPos, size_t _size, const IntCoord& _cropRectangle)
32  {
33  VectorFloatPoint resultVerticiesPos;
34  resultVerticiesPos.resize(_size);
35  for (size_t i = 0; i < _size; ++i)
36  {
37  resultVerticiesPos[i] = _baseVerticiesPos[i];
38  }
39 
40  cropPolygonSide(resultVerticiesPos, _cropRectangle.left, Left);
41  cropPolygonSide(resultVerticiesPos, _cropRectangle.right(), Right);
42  cropPolygonSide(resultVerticiesPos, _cropRectangle.top, Top);
43  cropPolygonSide(resultVerticiesPos, _cropRectangle.bottom(), Bottom);
44 
45  return resultVerticiesPos;
46  }
47 
48  void cropPolygonSide(VectorFloatPoint& _verticies, int _sideCoord, Side _side)
49  {
50  VectorFloatPoint newVerticies;
51  int invert = (_side == Right || _side == Bottom) ? -1 : 1;
52  for (size_t i = 0; i < _verticies.size(); ++i)
53  {
54  FloatPoint& v0 = _verticies[i];
55  FloatPoint& v1 = _verticies[(i + 1) % _verticies.size()];
56  switch (_side)
57  {
58  case Left:
59  case Right:
60  // both inside
61  if (invert* v0.left >= invert* _sideCoord && invert* v1.left >= invert * _sideCoord)
62  newVerticies.push_back(v0);
63  // intersect side (1st vertex in)
64  else if (invert* v0.left >= invert * _sideCoord && invert * v1.left < invert * _sideCoord)
65  {
66  newVerticies.push_back(v0);
67  float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
68  newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1)));
69  }
70  // intersect side (2nd vertex in)
71  else if (invert* v0.left <= invert * _sideCoord && invert * v1.left > invert * _sideCoord)
72  {
73  float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
74  newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1)));
75  }
76  // else don't add any verticies
77  break;
78  case Top:
79  case Bottom:
80  // both inside
81  if (invert* v0.top >= invert* _sideCoord && invert* v1.top >= invert * _sideCoord)
82  newVerticies.push_back(v0);
83  // intersect side (1st vertex in)
84  else if (invert* v0.top >= invert * _sideCoord && invert * v1.top < invert * _sideCoord)
85  {
86  newVerticies.push_back(v0);
87  float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
88  newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord));
89  }
90  // intersect side (2nd vertex in)
91  else if (invert* v0.top <= invert * _sideCoord && invert * v1.top > invert * _sideCoord)
92  {
93  float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
94  newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord));
95  }
96  // else don't add any verticies
97  break;
98  }
99  }
100 
101  _verticies = newVerticies;
102  }
103 
104  FloatPoint getPositionInsideRect(const FloatPoint& _point, const FloatPoint& _corner0, const FloatPoint& _corner1, const FloatPoint& _corner2)
105  {
106  FloatPoint result;
107 
108  FloatPoint point = _point - _corner0;
109  FloatPoint dirX = _corner1 - _corner0;
110  FloatPoint dirY = _corner2 - _corner0;
111 
112  float div = dirX.left * dirY.top - dirX.top * dirY.left;
113  if (div == 0.0f)
114  return FloatPoint();
115  return FloatPoint(
116  (point.top * dirX.left - point.left * dirX.top) / div,
117  (point.left * dirY.top - point.top * dirY.left) / div
118  );
119  }
120 
121  FloatPoint getUVFromPositionInsideRect(const FloatPoint& _point, const FloatPoint& _v0, const FloatPoint& _v1, const FloatPoint& _baseUV)
122  {
123  return FloatPoint(
124  _baseUV.left + _point.left * _v0.left + _point.top * _v1.left,
125  _baseUV.top + _point.left * _v0.top + _point.top * _v1.top
126  );
127  }
128 
129  } // namespace geometry_utility
130 
131 } // namespace MyGUI
FloatPoint getPositionInsideRect(const FloatPoint &_point, const FloatPoint &_corner0, const FloatPoint &_corner1, const FloatPoint &_corner2)
VectorFloatPoint cropPolygon(FloatPoint *_baseVerticiesPos, size_t _size, const IntCoord &_cropRectangle)
std::vector< FloatPoint > VectorFloatPoint
FloatPoint getUVFromPositionInsideRect(const FloatPoint &_point, const FloatPoint &_v0, const FloatPoint &_v1, const FloatPoint &_baseUV)
void cropPolygonSide(VectorFloatPoint &_verticies, int _sideCoord, Side _side)
types::TPoint< float > FloatPoint
Definition: MyGUI_Types.h:42