Files

225 lines
3.3 KiB
C++

#include "dl_coor.h"
#include <cassert>
#include "io/dl_log.h"
namespace dl
{
Coor* Coor::Create(Coor* parent /*= nullptr*/)
{
Coor* ret = new Coor;
ret->SetParent(parent);
return ret;
}
Coor* Coor::Clone()
{
assert(_rootIndex == -1);
Coor* ret = new Coor(*this);
return ret;
}
void Coor::DtPosition(const Position& dt)
{
_position += dt;
}
void Coor::DtScale(const Position& dt)
{
_scale += dt;
}
void Coor::DtScale(Float dt)
{
DtScale({ dt,dt });
}
void Coor::DtRotate(Float dt)
{
_rotate += dt;
_cosR = std::cos(_rotate);
_sinRNag = -std::sin(_rotate);
}
void Coor::SetPosition(const Position& pos)
{
_position = pos;
}
void Coor::SetScale(const Position& scale)
{
assert(scale[0] && scale[1]);
_scale = scale;
}
void Coor::SetRotate(Float rotate)
{
_rotate = rotate;
_cosR = std::cos(_rotate);
_sinRNag = -std::sin(_rotate);
}
void Coor::SetParent(Coor* coor)
{
if (this == coor)
{
log("自己不能设置父坐标系为自己!");
return;
}
if (_rootIndex != -1)
{
log("根坐标系不能设置父坐标系!");
return;
}
_parent = coor;
}
Position Coor::GetPosition() const
{
return _position;
}
Position Coor::GetScale() const
{
return _scale;
}
Float Coor::GetRotate() const
{
return _rotate;
}
Coor* Coor::GetParent() const
{
return _parent;
}
Position Coor::ThisToParent(Position pos) const
{
// 先旋转、再缩放、位移
if (_rotate)
{
// cos(-x) <=> cos(x)
// sin(-x) <=> -sin(x)
Float cos_a = _cosR * pos[0];
Float cos_b = _cosR * pos[1];
Float sin_a = _sinRNag * pos[0];
Float sin_b = _sinRNag * pos[1];
pos[0] = cos_a + sin_b;
pos[1] = cos_b - sin_a;
}
if (_scale[0] != 1.0f)
pos[0] *= _scale[0];
if (_scale[1] != 1.0f)
pos[1] *= _scale[1];
pos += _position;
return pos;
}
Position Coor::ParentToThis(Position pos) const
{
pos -= _position;
if (_scale[0] != 1.0)
pos[0] /= _scale[0];
if (_scale[1] != 1.0)
pos[1] /= _scale[1];
// 相反
if (_rotate)
{
Float cos_a = _cosR * pos[0];
Float cos_b = _cosR * pos[1];
Float sin_a = -_sinRNag * pos[0];
Float sin_b = -_sinRNag * pos[1];
pos[0] = cos_a + sin_b;
pos[1] = cos_b - sin_a;
}
return pos;
}
Position Coor::ThisToWorld(Position pos) const
{
// 有parent,则转换到parent,直到没有
const Coor* coor = this;
while (coor->_parent)
{
pos = coor->ThisToParent(pos);
coor = coor->_parent;
}
return coor->ThisToParent(pos);
}
Position Coor::WorldToThis(Position pos) const
{
std::array<const Coor*, 32> stack;
size_t i = 0;
const Coor* coor = this;
stack[i++] = coor;
while (coor->_parent)
{
stack[i++] = coor->_parent;
coor = coor->_parent;
}
while (i > 0)
{
coor = stack[--i];
pos = coor->ParentToThis(pos);
}
return pos;
}
Position Coor::ThisToRoot(Position pos) const
{
// 是根节点,或者判断其父亲,直到没有parent
if (_rootIndex != -1)
return pos;
pos = ThisToParent(pos);
const Coor* coor = _parent;
//
while (coor && coor->_rootIndex == -1)
{
pos = coor->ThisToParent(pos);
coor = coor->_parent;
}
return pos;
}
Coor* Coor::GetRoot()
{
// 是根节点,或者判断其父亲,直到没有parent
if (_rootIndex != -1)
return this;
Coor* coor = _parent;
//
while (coor)
{
if (coor->_rootIndex != -1)
return coor;
coor = coor->_parent;
}
return coor;
}
}