Mercurial > hg > orthanc-stone
diff OrthancStone/Sources/Scene2D/ScenePoint2D.cpp @ 1804:5a872e69c74f
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 20 May 2021 14:48:51 +0200 |
parents | |
children | 3889ae96d2e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Scene2D/ScenePoint2D.cpp Thu May 20 14:48:51 2021 +0200 @@ -0,0 +1,162 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2021 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/>. + **/ + + +#include "ScenePoint2D.h" + + +namespace OrthancStone +{ + ScenePoint2D ScenePoint2D::Apply(const AffineTransform2D& t) const + { + double x = x_; + double y = y_; + t.Apply(x, y); + return ScenePoint2D(x, y); + } + + + const ScenePoint2D ScenePoint2D::operator-(const ScenePoint2D& a) const + { + ScenePoint2D v; + v.x_ = x_ - a.x_; + v.y_ = y_ - a.y_; + return v; + } + + + const ScenePoint2D ScenePoint2D::operator+(const ScenePoint2D& a) const + { + ScenePoint2D v; + v.x_ = x_ + a.x_; + v.y_ = y_ + a.y_; + return v; + } + + + const ScenePoint2D ScenePoint2D::operator*(double a) const + { + ScenePoint2D v; + v.x_ = x_ * a; + v.y_ = y_ * a; + return v; + } + + + const ScenePoint2D ScenePoint2D::operator/(double a) const + { + ScenePoint2D v; + v.x_ = x_ / a; + v.y_ = y_ / a; + return v; + } + + + void ScenePoint2D::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_); + } + + + double ScenePoint2D::Dot(const ScenePoint2D& a, const ScenePoint2D& b) + { + return a.x_ * b.x_ + a.y_ * b.y_; + } + + + double ScenePoint2D::SquaredMagnitude(const ScenePoint2D& v) + { + return v.x_ * v.x_ + v.y_ * v.y_; + } + + + double ScenePoint2D::Magnitude(const ScenePoint2D& v) + { + double squaredMagnitude = SquaredMagnitude(v); + + if (LinearAlgebra::IsCloseToZero(squaredMagnitude)) + { + return 0.0; + } + else + { + return sqrt(squaredMagnitude); + } + } + + + double ScenePoint2D::SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) + { + ScenePoint2D n = b - a; + return Dot(n, n); + } + + + double ScenePoint2D::DistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) + { + double squaredDist = SquaredDistancePtPt(a, b); + return sqrt(squaredDist); + } + + + double ScenePoint2D::SquaredDistancePtSegment(const ScenePoint2D& a, const ScenePoint2D& b, const ScenePoint2D& p) + { + // Rewritten from https://www.randygaul.net/2014/07/23/distance-point-to-line-segment/ + + 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); + } + } +}