MyGUI  3.2.1
MyGUI_GeometryUtility.cpp
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
9 
10 namespace MyGUI
11 {
12 
13  namespace geometry_utility
14  {
15 
16  VectorFloatPoint cropPolygon(FloatPoint* _baseVerticiesPos, size_t _size, const IntCoord& _cropRectangle)
17  {
18  VectorFloatPoint resultVerticiesPos;
19  resultVerticiesPos.resize(_size);
20  for (size_t i = 0; i < _size; ++i)
21  {
22  resultVerticiesPos[i] = _baseVerticiesPos[i];
23  }
24 
25  cropPolygonSide(resultVerticiesPos, _cropRectangle.left, Left);
26  cropPolygonSide(resultVerticiesPos, _cropRectangle.right(), Right);
27  cropPolygonSide(resultVerticiesPos, _cropRectangle.top, Top);
28  cropPolygonSide(resultVerticiesPos, _cropRectangle.bottom(), Bottom);
29 
30  return resultVerticiesPos;
31  }
32 
33  void cropPolygonSide(VectorFloatPoint& _verticies, int _sideCoord, Side _side)
34  {
35  VectorFloatPoint newVerticies;
36  int invert = (_side == Right || _side == Bottom) ? -1 : 1;
37  for (size_t i = 0; i < _verticies.size(); ++i)
38  {
39  FloatPoint& v0 = _verticies[i];
40  FloatPoint& v1 = _verticies[(i + 1) % _verticies.size()];
41  switch (_side)
42  {
43  case Left:
44  case Right:
45  // both inside
46  if (invert * v0.left >= invert * _sideCoord && invert * v1.left >= invert * _sideCoord)
47  newVerticies.push_back(v0);
48  // intersect side (1st vertex in)
49  else if (invert * v0.left >= invert * _sideCoord && invert * v1.left < invert * _sideCoord)
50  {
51  newVerticies.push_back(v0);
52  float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
53  newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1)));
54  }
55  // intersect side (2nd vertex in)
56  else if (invert * v0.left <= invert * _sideCoord && invert * v1.left > invert * _sideCoord)
57  {
58  float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
59  newVerticies.push_back(FloatPoint((float)_sideCoord, (v0.top + c * v1.top) / (c + 1)));
60  }
61  // else don't add any verticies
62  break;
63  case Top:
64  case Bottom:
65  // both inside
66  if (invert * v0.top >= invert * _sideCoord && invert * v1.top >= invert * _sideCoord)
67  newVerticies.push_back(v0);
68  // intersect side (1st vertex in)
69  else if (invert * v0.top >= invert * _sideCoord && invert * v1.top < invert * _sideCoord)
70  {
71  newVerticies.push_back(v0);
72  float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
73  newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord));
74  }
75  // intersect side (2nd vertex in)
76  else if (invert * v0.top <= invert * _sideCoord && invert * v1.top > invert * _sideCoord)
77  {
78  float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
79  newVerticies.push_back(FloatPoint((v0.left + c * v1.left) / (c + 1), (float)_sideCoord));
80  }
81  // else don't add any verticies
82  break;
83  }
84  }
85 
86  _verticies = newVerticies;
87  }
88 
89  FloatPoint getPositionInsideRect(const FloatPoint& _point, const FloatPoint& _corner0, const FloatPoint& _corner1, const FloatPoint& _corner2)
90  {
91  FloatPoint result;
92 
93  FloatPoint point = _point - _corner0;
94  FloatPoint dirX = _corner1 - _corner0;
95  FloatPoint dirY = _corner2 - _corner0;
96 
97  float div = dirX.left * dirY.top - dirX.top * dirY.left;
98  if (div == 0.0f)
99  return FloatPoint();
100  return FloatPoint(
101  (point.top * dirX.left - point.left * dirX.top) / div,
102  (point.left * dirY.top - point.top * dirY.left) / div);
103  }
104 
105  FloatPoint getUVFromPositionInsideRect(const FloatPoint& _point, const FloatPoint& _v0, const FloatPoint& _v1, const FloatPoint& _baseUV)
106  {
107  return FloatPoint(
108  _baseUV.left + _point.left * _v0.left + _point.top * _v1.left,
109  _baseUV.top + _point.left * _v0.top + _point.top * _v1.top);
110  }
111 
112  } // namespace geometry_utility
113 
114 } // namespace MyGUI