Mercurial > hg > orthanc-stone
view Framework/Scene2D/ScenePoint2D.h @ 1510:1005c1cbe4dd
fix
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 07 Jul 2020 09:45:27 +0200 |
parents | 7ec8fea061b9 |
children |
line wrap: on
line source
/** * Stone of Orthanc * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2020 Osimis S.A., Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #pragma once #include "../Toolbox/AffineTransform2D.h" #include "../Toolbox/LinearAlgebra.h" namespace OrthancStone { class ScenePoint2D { private: double x_; double y_; public: ScenePoint2D() : x_(0), y_(0) { } ScenePoint2D(double x, double y) : x_(x), y_(y) { } double GetX() const { return x_; } double GetY() const { return y_; } ScenePoint2D Apply(const AffineTransform2D& t) const { double x = x_; double y = y_; t.Apply(x, y); return ScenePoint2D(x, y); } const ScenePoint2D operator-(const ScenePoint2D& a) const { ScenePoint2D v; v.x_ = x_ - a.x_; v.y_ = y_ - a.y_; return v; } const ScenePoint2D operator+(const ScenePoint2D& a) const { ScenePoint2D v; v.x_ = x_ + a.x_; v.y_ = y_ + a.y_; return v; } const ScenePoint2D operator*(double a) const { ScenePoint2D v; v.x_ = x_ * a; v.y_ = y_ * a; return v; } const ScenePoint2D operator/(double a) const { ScenePoint2D v; v.x_ = x_ / a; v.y_ = y_ / a; return v; } static void MidPoint(ScenePoint2D& result, const ScenePoint2D& a, const ScenePoint2D& b) { result.x_ = 0.5 * (a.x_ + b.x_); result.y_ = 0.5 * (a.y_ + b.y_); } static double Dot(const ScenePoint2D& a, const ScenePoint2D& b) { return a.x_ * b.x_ + a.y_ * b.y_; } static double SquaredMagnitude(const ScenePoint2D& v) { return v.x_ * v.x_ + v.y_ * v.y_; } static double Magnitude(const ScenePoint2D& v) { double squaredMagnitude = SquaredMagnitude(v); if (LinearAlgebra::IsCloseToZero(squaredMagnitude)) return 0.0; return sqrt(squaredMagnitude); } static double SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) { ScenePoint2D n = b - a; return Dot(n, n); } static double DistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) { double squaredDist = SquaredDistancePtPt(a, b); return sqrt(squaredDist); } /** Distance from point p to [a,b] segment Rewritten from https://www.randygaul.net/2014/07/23/distance-point-to-line-segment/ */ static double SquaredDistancePtSegment(const ScenePoint2D& a, const ScenePoint2D& b, const ScenePoint2D& p) { ScenePoint2D n = b - a; ScenePoint2D pa = a - p; double c = Dot(n, pa); // Closest point is a if (c > 0.0) return Dot(pa, pa); ScenePoint2D bp = p - b; // Closest point is b if (Dot(n, bp) > 0.0) return Dot(bp, bp); // if segment length is very short, we approximate distance to the // distance with a double nq = Dot(n, n); if (LinearAlgebra::IsCloseToZero(nq)) { // segment is very small: approximate distance from point to segment // with distance from p to a return Dot(pa, pa); } else { // Closest point is between a and b ScenePoint2D e = pa - n * (c / nq); return Dot(e, e); } } }; }