MyGUI_GeometryUtility.cpp
Go to the documentation of this file.
/*
* This source file is part of MyGUI. For the latest info, see http://mygui.info/
* Distributed under the MIT License
* (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_GeometryUtility.h"
namespace MyGUI::geometry_utility
{
VectorFloatPoint cropPolygon(FloatPoint* _baseVerticiesPos, size_t _size, const IntCoord& _cropRectangle)
{
VectorFloatPoint resultVerticiesPos;
resultVerticiesPos.resize(_size);
for (size_t i = 0; i < _size; ++i)
{
resultVerticiesPos[i] = _baseVerticiesPos[i];
}
cropPolygonSide(resultVerticiesPos, _cropRectangle.left, Left);
cropPolygonSide(resultVerticiesPos, _cropRectangle.right(), Right);
cropPolygonSide(resultVerticiesPos, _cropRectangle.top, Top);
cropPolygonSide(resultVerticiesPos, _cropRectangle.bottom(), Bottom);
return resultVerticiesPos;
}
void cropPolygonSide(VectorFloatPoint& _verticies, int _sideCoord, Side _side)
{
VectorFloatPoint newVerticies;
int invert = (_side == Right || _side == Bottom) ? -1 : 1;
for (size_t i = 0; i < _verticies.size(); ++i)
{
FloatPoint& v0 = _verticies[i];
FloatPoint& v1 = _verticies[(i + 1) % _verticies.size()];
switch (_side)
{
case Left:
case Right:
// both inside
if (invert * v0.left >= invert * _sideCoord && invert * v1.left >= invert * _sideCoord)
newVerticies.push_back(v0);
// intersect side (1st vertex in)
else if (invert * v0.left >= invert * _sideCoord && invert * v1.left < invert * _sideCoord)
{
newVerticies.push_back(v0);
float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
newVerticies.emplace_back((float)_sideCoord, (v0.top + c * v1.top) / (c + 1));
}
// intersect side (2nd vertex in)
else if (invert * v0.left <= invert * _sideCoord && invert * v1.left > invert * _sideCoord)
{
float c = (v0.left - _sideCoord) / (_sideCoord - v1.left);
newVerticies.emplace_back((float)_sideCoord, (v0.top + c * v1.top) / (c + 1));
}
// else don't add any verticies
break;
case Top:
case Bottom:
// both inside
if (invert * v0.top >= invert * _sideCoord && invert * v1.top >= invert * _sideCoord)
newVerticies.push_back(v0);
// intersect side (1st vertex in)
else if (invert * v0.top >= invert * _sideCoord && invert * v1.top < invert * _sideCoord)
{
newVerticies.push_back(v0);
float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
newVerticies.emplace_back((v0.left + c * v1.left) / (c + 1), (float)_sideCoord);
}
// intersect side (2nd vertex in)
else if (invert * v0.top <= invert * _sideCoord && invert * v1.top > invert * _sideCoord)
{
float c = (v0.top - _sideCoord) / (_sideCoord - v1.top);
newVerticies.emplace_back((v0.left + c * v1.left) / (c + 1), (float)_sideCoord);
}
// else don't add any verticies
break;
}
}
_verticies = newVerticies;
}
FloatPoint getPositionInsideRect(
const FloatPoint& _point,
const FloatPoint& _corner0,
const FloatPoint& _corner1,
const FloatPoint& _corner2)
{
FloatPoint point = _point - _corner0;
FloatPoint dirX = _corner1 - _corner0;
FloatPoint dirY = _corner2 - _corner0;
float div = dirX.left * dirY.top - dirX.top * dirY.left;
if (div == 0.0f)
return {};
return {
(point.top * dirX.left - point.left * dirX.top) / div,
(point.left * dirY.top - point.top * dirY.left) / div};
}
FloatPoint getUVFromPositionInsideRect(
const FloatPoint& _point,
const FloatPoint& _v0,
const FloatPoint& _v1,
const FloatPoint& _baseUV)
{
return {
_baseUV.left + _point.left * _v0.left + _point.top * _v1.left,
_baseUV.top + _point.left * _v0.top + _point.top * _v1.top};
}
} // namespace MyGUI
MyGUI_GeometryUtility.h
MyGUI_Precompiled.h
MyGUI::geometry_utility
Definition MyGUI_GeometryUtility.h:19
MyGUI::geometry_utility::cropPolygonSide
void cropPolygonSide(VectorFloatPoint &_verticies, int _sideCoord, Side _side)
Definition MyGUI_GeometryUtility.cpp:30
MyGUI::geometry_utility::getUVFromPositionInsideRect
FloatPoint getUVFromPositionInsideRect(const FloatPoint &_point, const FloatPoint &_v0, const FloatPoint &_v1, const FloatPoint &_baseUV)
Definition MyGUI_GeometryUtility.cpp:104
MyGUI::geometry_utility::getPositionInsideRect
FloatPoint getPositionInsideRect(const FloatPoint &_point, const FloatPoint &_corner0, const FloatPoint &_corner1, const FloatPoint &_corner2)
Definition MyGUI_GeometryUtility.cpp:86
MyGUI::geometry_utility::Side
Side
Definition MyGUI_GeometryUtility.h:23
MyGUI::geometry_utility::Top
@ Top
Definition MyGUI_GeometryUtility.h:26
MyGUI::geometry_utility::Bottom
@ Bottom
Definition MyGUI_GeometryUtility.h:27
MyGUI::geometry_utility::Left
@ Left
Definition MyGUI_GeometryUtility.h:24
MyGUI::geometry_utility::Right
@ Right
Definition MyGUI_GeometryUtility.h:25
MyGUI::geometry_utility::cropPolygon
VectorFloatPoint cropPolygon(FloatPoint *_baseVerticiesPos, size_t _size, const IntCoord &_cropRectangle)
Definition MyGUI_GeometryUtility.cpp:13
MyGUI::FloatPoint
types::TPoint< float > FloatPoint
Definition MyGUI_Types.h:28
MyGUI::VectorFloatPoint
std::vector< FloatPoint > VectorFloatPoint
Definition MyGUI_GeometryUtility.h:16
MyGUI::IntCoord
types::TCoord< int > IntCoord
Definition MyGUI_Types.h:36
MyGUI::types::TCoord::right
T right() const
Definition MyGUI_TCoord.h:125
MyGUI::types::TCoord::top
T top
Definition MyGUI_TCoord.h:21
MyGUI::types::TCoord::left
T left
Definition MyGUI_TCoord.h:20
MyGUI::types::TCoord::bottom
T bottom() const
Definition MyGUI_TCoord.h:130
MyGUI::types::TPoint::left
T left
Definition MyGUI_TPoint.h:19
MyGUI::types::TPoint::top
T top
Definition MyGUI_TPoint.h:20