diff --git a/rtengine/coord.cc b/rtengine/coord.cc index c35d71e73..4b5dcf40b 100644 --- a/rtengine/coord.cc +++ b/rtengine/coord.cc @@ -19,21 +19,49 @@ #include "coord.h" +#include "rt_math.h" + namespace rtengine { -void Coord::setFromPolar(PolarCoord polar) +Coord& Coord::operator= (const PolarCoord& other) { - while (polar.angle < 0.f) { - polar.angle += 360.f; - } + const auto radius = other.radius; + const auto angle = other.angle / 180.0 * M_PI; - while (polar.angle > 360.f) { - polar.angle -= 360.f; - } + x = radius * std::cos (angle); + y = radius * std::sin (angle); - x = polar.radius * cos(polar.angle / 180.f * M_PI); - y = polar.radius * sin(polar.angle / 180.f * M_PI); + return *this; +} + +PolarCoord& PolarCoord::operator= (const Coord& other) +{ + const double x = other.x; + const double y = other.y; + + radius = rtengine::norm2 (x, y); + angle = std::atan2 (x, y) * 180.0 / M_PI; + + return *this; +} + +/// @brief Clip the coord to stay in the width x height bounds +/// @return true if the x or y coordinate has changed +bool Coord::clip (const int width, const int height) +{ + const auto newX = rtengine::LIM (x, 0, width); + const auto newY = rtengine::LIM (y, 0, height); + + if (x != newX || y != newY) { + + x = newX; + y = newY; + + return true; + } else { + return false; + } } } diff --git a/rtengine/coord.h b/rtengine/coord.h index 359fb3a96..2242cec1e 100644 --- a/rtengine/coord.h +++ b/rtengine/coord.h @@ -16,205 +16,218 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ + #ifndef __COORD__ #define __COORD__ -#include "rt_math.h" - namespace rtengine { -class PolarCoord; +struct Coord; +struct PolarCoord; -// Do not confuse with rtengine::Coord2D, this one is for the GUI -class Coord +// Do not confuse with Coord2D, this one is used by the UI. +struct Coord { -public: - int x; - int y; + int x = 0; + int y = 0; - Coord() : x(-1), y(-1) {} - Coord(int x, int y) : x(x), y(y) {} + Coord () = default; + Coord (const int x, const int y); + Coord (const Coord& other) = default; + Coord (const PolarCoord& other); - void set (int x, int y) - { - this->x = x; - this->y = y; - } + Coord& operator= (const Coord& other) = default; + Coord& operator= (const PolarCoord& other); - void setFromPolar(PolarCoord polar); + void get (int& x, int& y) const; + void set (const int x, const int y); - /// @brief Clip the coord to stay in the width x height bounds - /// @return true if the x or y coordinate has changed - bool clip(int width, int height) - { - int trimmedX = rtengine::LIM(x, 0, width); - int trimmedY = rtengine::LIM(y, 0, height); - bool retval = trimmedX != x || trimmedY != y; - x = trimmedX; - y = trimmedY; - return retval; - } + bool clip (const int width, const int height); - bool operator== (const Coord& other) const - { - return other.x == x && other.y == y; - } - - bool operator!= (const Coord& other) const - { - return other.x != x || other.y != y; - } - - void operator+=(const Coord & rhs) - { - x += rhs.x; - y += rhs.y; - } - void operator-=(const Coord & rhs) - { - x -= rhs.x; - y -= rhs.y; - } - void operator*=(double scale) - { - x *= scale; - y *= scale; - } - Coord operator+(Coord & rhs) - { - Coord result(x + rhs.x, y + rhs.y); - return result; - } - Coord operator-(Coord & rhs) - { - Coord result(x - rhs.x, y - rhs.y); - return result; - } - Coord operator*(double scale) - { - Coord result(x * scale, y * scale); - return result; - } -}; - -class PolarCoord -{ -public: - double radius; - double angle; // degree - - PolarCoord() : radius(1.), angle(0.) {} - PolarCoord(double radius, double angle) : radius(radius), angle(angle) {} - PolarCoord(Coord start, Coord end) : radius(1.), angle(0.) - { - setFromCartesian(start, end); - } - PolarCoord(Coord delta) : radius(1.), angle(0.) - { - setFromCartesian(delta); - } - - void set (double radius, double angle) - { - this->radius = radius; - this->angle = angle; - } - - void setFromCartesian(Coord start, Coord end) - { - Coord delta(end.x - start.x, end.y - start.y); - setFromCartesian(delta); - } - - void setFromCartesian(Coord delta) - { - if (!delta.x && !delta.y) { - // null vector, we set to a default value - radius = 1.; - angle = 0.; - return; - } - - double x_ = double(delta.x); - double y_ = double(delta.y); - radius = sqrt(x_ * x_ + y_ * y_); - - if (delta.x > 0.) { - if (delta.y >= 0.) { - angle = atan(y_ / x_) / (2 * M_PI) * 360.; - } else if (delta.y < 0.) { - angle = (atan(y_ / x_) + 2 * M_PI) / (2 * M_PI) * 360.; - } - } else if (delta.x < 0.) { - angle = (atan(y_ / x_) + M_PI) / (2 * M_PI) * 360.; - } else if (delta.x == 0.) { - if (delta.y > 0.) { - angle = 90.; - } else { - angle = 270.; - } - } - } - - bool operator== (const PolarCoord& other) const - { - return other.radius == radius && other.angle == angle; - } - - bool operator!= (const PolarCoord& other) const - { - return other.radius != radius || other.angle != angle; - } - - void operator+=(const PolarCoord & rhs) - { - Coord thisCoord, rhsCoord; - thisCoord.setFromPolar(*this); - rhsCoord.setFromPolar(rhs); - thisCoord += rhsCoord; - setFromCartesian(thisCoord); - } - void operator-=(const PolarCoord & rhs) - { - Coord thisCoord, rhsCoord; - thisCoord.setFromPolar(*this); - rhsCoord.setFromPolar(rhs); - thisCoord -= rhsCoord; - setFromCartesian(thisCoord); - } - void operator*=(double scale) - { - radius *= scale; - } - PolarCoord operator+ (const PolarCoord& rhs) const - { - PolarCoord result; - Coord thisCoord, rhsCoord; - thisCoord.setFromPolar(*this); - rhsCoord.setFromPolar(rhs); - thisCoord += rhsCoord; - result.setFromCartesian(thisCoord); - return result; - } - PolarCoord operator- (const PolarCoord& rhs) const - { - PolarCoord result; - Coord thisCoord, rhsCoord; - thisCoord.setFromPolar(*this); - rhsCoord.setFromPolar(rhs); - thisCoord -= rhsCoord; - result.setFromCartesian(thisCoord); - return result; - } - Coord operator*(double scale) - { - Coord result(radius * scale, angle); - return result; - } + Coord& operator+= (const Coord& other); + Coord& operator-= (const Coord& other); + Coord& operator*= (const double scale); }; +bool operator== (const Coord& lhs, const Coord& rhs); +bool operator!= (const Coord& lhs, const Coord& rhs); + +const Coord operator+ (const Coord& lhs, const Coord& rhs); +const Coord operator- (const Coord& lhs, const Coord& rhs); +const Coord operator* (const Coord& lhs, const Coord& rhs); + +struct PolarCoord +{ + double radius = 0.0; + double angle = 0.0; + + PolarCoord () = default; + PolarCoord (const double radius, const double angle); + PolarCoord (const PolarCoord& other) = default; + PolarCoord (const Coord& other); + + PolarCoord& operator= (const PolarCoord& other) = default; + PolarCoord& operator= (const Coord& other); + + void get (double& radius, double& angle) const; + void set (const double radius, const double angle); + + PolarCoord& operator+= (const PolarCoord& other); + PolarCoord& operator-= (const PolarCoord& other); + PolarCoord& operator*= (const double scale); + +}; + +bool operator== (const PolarCoord& lhs, const PolarCoord& rhs); +bool operator!= (const PolarCoord& lhs, const PolarCoord& rhs); + +const PolarCoord operator+ (const PolarCoord& lhs, const PolarCoord& rhs); +const PolarCoord operator- (const PolarCoord& lhs, const PolarCoord& rhs); +const PolarCoord operator* (const PolarCoord& lhs, const double rhs); +const PolarCoord operator* (const double lhs, const PolarCoord& rhs); + +inline Coord::Coord (const int x, const int y) : x (x), y (y) +{ +} + +inline Coord::Coord (const PolarCoord& other) +{ + *this = other; +} + +inline void Coord::get (int& x, int& y) const +{ + x = this->x; + y = this->y; +} + +inline void Coord::set (const int x, const int y) +{ + this->x = x; + this->y = y; +} + +inline Coord& Coord::operator+= (const Coord& other) +{ + x += other.x; + y += other.y; + return *this; +} + +inline Coord& Coord::operator-= (const Coord& other) +{ + x -= other.x; + y -= other.y; + return *this; +} + +inline Coord& Coord::operator*= (const double scale) +{ + x *= scale; + y *= scale; + return *this; +} + +inline bool operator== (const Coord& lhs, const Coord& rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y; +} + +inline bool operator!= (const Coord& lhs, const Coord& rhs) +{ + return !(lhs == rhs); +} + +inline const Coord operator+ (const Coord& lhs, const Coord& rhs) +{ + return Coord (lhs) += rhs; +} + +inline const Coord operator- (const Coord& lhs, const Coord& rhs) +{ + return Coord (lhs) -= rhs; +} + +inline const Coord operator* (const Coord& lhs, const double rhs) +{ + return Coord (lhs) *= rhs; +} + +inline const Coord operator* (const double lhs, const Coord& rhs) +{ + return Coord (rhs) *= lhs; +} + +inline PolarCoord::PolarCoord (const double radius, const double angle) : radius (radius), angle (angle) +{ +} + +inline PolarCoord::PolarCoord (const Coord& other) +{ + *this = other; +} + +inline void PolarCoord::get (double& radius, double& angle) const +{ + radius = this->radius; + angle = this->angle; +} + +inline void PolarCoord::set (const double radius, const double angle) +{ + this->radius = radius; + this->angle = angle; +} + +inline PolarCoord& PolarCoord::operator+= (const PolarCoord& other) +{ + *this = Coord (*this) + Coord (other); + return *this; +} + +inline PolarCoord &PolarCoord::operator-= (const PolarCoord &other) +{ + *this = Coord (*this) - Coord (other); + return *this; +} + +inline PolarCoord &PolarCoord::operator*= (const double scale) +{ + radius *= scale; + return *this; +} + +inline bool operator== (const PolarCoord& lhs, const PolarCoord& rhs) +{ + return lhs.radius == rhs.radius && lhs.angle == rhs.angle; +} + +inline bool operator!= (const PolarCoord& lhs, const PolarCoord& rhs) +{ + return !(lhs == rhs); +} + +inline const PolarCoord operator+ (const PolarCoord& lhs, const PolarCoord& rhs) +{ + return PolarCoord (lhs) += rhs; +} + +inline const PolarCoord operator- (const PolarCoord& lhs, const PolarCoord& rhs) +{ + return PolarCoord (lhs) -= rhs; +} + +inline const PolarCoord operator* (const PolarCoord& lhs, const double rhs) +{ + return PolarCoord (lhs) *= rhs; +} + +inline const PolarCoord operator* (const double lhs, const PolarCoord& rhs) +{ + return PolarCoord (rhs) *= lhs; +} } diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index 93011f55b..7492d456b 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -156,29 +156,24 @@ void Gradient::updateGeometry(const int centerX, const int centerY, const double } } - PolarCoord polCoord1, polCoord2; - double decay = feather * rtengine::norm2(imW, imH) / 200.; - - rtengine::Coord origin(imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200); - - Line *currLine; - Circle *currCircle; + const auto decay = feather * rtengine::norm2 (imW, imH) / 200.0; + rtengine::Coord origin (imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200); const auto updateLine = [&](Geometry* geometry, const float radius, const float begin, const float end) { const auto line = static_cast(geometry); - line->begin.setFromPolar(PolarCoord(radius, -degree + begin)); + line->begin = PolarCoord(radius, -degree + begin); line->begin += origin; - line->end.setFromPolar(PolarCoord(radius, -degree + end)); + line->end = PolarCoord(radius, -degree + end); line->end += origin; }; const auto updateLineWithDecay = [&](Geometry* geometry, const float radius, const float offSetAngle) { const auto line = static_cast(geometry); - line->begin.setFromPolar(PolarCoord(radius, -degree + 180.) + PolarCoord(decay, -degree + offSetAngle)); + line->begin = PolarCoord (radius, -degree + 180.) + PolarCoord (decay, -degree + offSetAngle); line->begin += origin; - line->end.setFromPolar(PolarCoord(radius, -degree) + PolarCoord(decay, -degree + offSetAngle)); + line->end = PolarCoord (radius, -degree) + PolarCoord (decay, -degree + offSetAngle); line->end += origin; }; @@ -408,7 +403,7 @@ bool Gradient::button1Pressed(int modifierKey) p1.y = p2.y; p2.y = p; - pCoord.setFromCartesian(p1, p2); + pCoord = p2 - p1; draggedPointOldAngle = pCoord.angle; //printf("\ndraggedPointOldAngle=%.3f\n\n", draggedPointOldAngle); draggedPointAdjusterAngle = degree->getValue(); @@ -427,7 +422,7 @@ bool Gradient::button1Pressed(int modifierKey) centerPos.y = currPos.y; currPos.y = p; - draggedPoint.setFromCartesian(centerPos, currPos); + draggedPoint = currPos - centerPos; // compute the projected value of the dragged point draggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle - degree->getValue()) / 180.*M_PI); @@ -485,7 +480,7 @@ bool Gradient::drag1(int modifierKey) centerPos.y = currPos.y; currPos.y = p; - draggedPoint.setFromCartesian(centerPos, currPos); + draggedPoint = currPos - centerPos; double deltaAngle = draggedPoint.angle - draggedPointOldAngle; if (deltaAngle > 180.) { // crossing the boundary (0->360) @@ -530,7 +525,7 @@ bool Gradient::drag1(int modifierKey) centerPos.y = currPos.y; currPos.y = p; - draggedPoint.setFromCartesian(centerPos, currPos); + draggedPoint = currPos - centerPos; double currDraggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle - degree->getValue()) / 180.*M_PI); if (lastObject == 2)