128 lines
4.6 KiB
C++
128 lines
4.6 KiB
C++
#include "CoordSpaceHelperTransform.hpp"
|
|
#include "CoordSpaceHelper.hpp"
|
|
#include "nlohmann/json.hpp"
|
|
|
|
CoordSpaceHelperTransform::CoordSpaceHelperTransform() {}
|
|
|
|
CoordSpaceHelperTransform::CoordSpaceHelperTransform(const WorldVec& translationPos):
|
|
transformType(TransformType::TRANSLATE),
|
|
pos(translationPos)
|
|
{}
|
|
|
|
CoordSpaceHelperTransform::CoordSpaceHelperTransform(const WorldVec& rotatePos, double angle):
|
|
transformType(TransformType::ROTATE),
|
|
pos(rotatePos),
|
|
rotation(angle)
|
|
{}
|
|
|
|
CoordSpaceHelperTransform::CoordSpaceHelperTransform(const WorldVec& scalePos, const WorldMultiplier& inverseScaleAmount):
|
|
transformType(TransformType::SCALE),
|
|
pos(scalePos),
|
|
inverseScale(inverseScaleAmount)
|
|
{}
|
|
|
|
bool CoordSpaceHelperTransform::operator==(const CoordSpaceHelperTransform& otherCoords) const {
|
|
return otherCoords.transformType == transformType && rotation == otherCoords.rotation && pos == otherCoords.pos && inverseScale == otherCoords.inverseScale;
|
|
}
|
|
|
|
bool CoordSpaceHelperTransform::operator!=(const CoordSpaceHelperTransform& otherCoords) const {
|
|
return rotation != otherCoords.rotation || pos != otherCoords.pos || inverseScale != otherCoords.inverseScale;
|
|
}
|
|
|
|
//WorldVec CoordSpaceHelperTransform::to_space_world(const WorldVec& coord) const {
|
|
// switch(transformType) {
|
|
// case TransformType::NONE:
|
|
// return coord;
|
|
// case TransformType::TRANSLATE:
|
|
// return (coord - pos);
|
|
// case TransformType::SCALE:
|
|
// return pos + FixedPoint::multiplier_vec_div(coord - pos, inverseScale);
|
|
// case TransformType::ROTATE:
|
|
// return rotate_world_coord(coord + pos, -rotation) - pos;
|
|
// }
|
|
// return coord;
|
|
//}
|
|
|
|
WorldVec CoordSpaceHelperTransform::from_space_world(const WorldVec& coord) const {
|
|
switch(transformType) {
|
|
case TransformType::NONE:
|
|
return coord;
|
|
case TransformType::TRANSLATE:
|
|
return (coord + pos);
|
|
case TransformType::SCALE:
|
|
return FixedPoint::multiplier_vec_div(coord - pos, inverseScale) + pos;
|
|
case TransformType::ROTATE:
|
|
return pos + rotate_world_coord(coord - pos, rotation);
|
|
}
|
|
return coord;
|
|
}
|
|
|
|
CoordSpaceHelper CoordSpaceHelperTransform::other_coord_space_to_this_space(const CoordSpaceHelper& other) const {
|
|
switch(transformType) {
|
|
case TransformType::NONE:
|
|
return other;
|
|
case TransformType::TRANSLATE: {
|
|
auto toRet = other;
|
|
toRet.translate(-pos);
|
|
return toRet;
|
|
}
|
|
case TransformType::SCALE: {
|
|
auto toRet = other;
|
|
toRet.scale_about(pos, WorldMultiplier(1) / inverseScale);
|
|
return toRet;
|
|
}
|
|
case TransformType::ROTATE: {
|
|
auto toRet = other;
|
|
toRet.rotate_about(pos, -rotation);
|
|
return toRet;
|
|
}
|
|
}
|
|
return other;
|
|
}
|
|
|
|
CoordSpaceHelper CoordSpaceHelperTransform::other_coord_space_from_this_space(const CoordSpaceHelper& other) const {
|
|
switch(transformType) {
|
|
case TransformType::NONE:
|
|
return other;
|
|
case TransformType::TRANSLATE: {
|
|
auto toRet = other;
|
|
toRet.translate(pos);
|
|
return toRet;
|
|
}
|
|
case TransformType::SCALE: {
|
|
auto toRet = other;
|
|
toRet.scale_about(pos, inverseScale);
|
|
return toRet;
|
|
}
|
|
case TransformType::ROTATE: {
|
|
auto toRet = other;
|
|
toRet.rotate_about(pos, rotation);
|
|
return toRet;
|
|
}
|
|
}
|
|
return other;
|
|
}
|
|
|
|
void CoordSpaceHelperTransform::translate(const WorldVec& translation) {
|
|
pos += translation;
|
|
}
|
|
|
|
void CoordSpaceHelperTransform::rotate_about(const WorldVec& rotatePos, double angle) {
|
|
WorldVec a = pos - rotatePos;
|
|
FixedPoint::Number<boost::multiprecision::cpp_int, 15> s = FixedPoint::Number<boost::multiprecision::cpp_int, 15>(std::sin(angle));
|
|
FixedPoint::Number<boost::multiprecision::cpp_int, 15> c = FixedPoint::Number<boost::multiprecision::cpp_int, 15>(std::cos(angle));
|
|
set_rotation(rotation + angle);
|
|
pos = {
|
|
rotatePos.x() + a.x().multiply_different_precision(c) - a.y().multiply_different_precision(s),
|
|
rotatePos.y() + a.x().multiply_different_precision(s) + a.y().multiply_different_precision(c)
|
|
};
|
|
}
|
|
|
|
void CoordSpaceHelperTransform::set_rotation(double newRotation) {
|
|
rotation = newRotation;
|
|
// using circular fmod caused inaccuracies, so these loops might be a better solution
|
|
while(rotation >= 2.0 * std::numbers::pi)
|
|
rotation -= 2.0 * std::numbers::pi;
|
|
while (rotation < 0.0)
|
|
rotation += 2.0 * std::numbers::pi;
|
|
}
|