Mercurial > hg > orthanc-stone
diff Framework/Scene2D/ScenePoint2D.h @ 865:a29c13497557
Added operators to ScenePoint2D + highlight support on MouseOver for measuring tools
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 25 Jun 2019 15:24:13 +0200 |
parents | 5c551f078c18 |
children | c71ef52602a0 |
line wrap: on
line diff
--- a/Framework/Scene2D/ScenePoint2D.h Mon Jun 24 19:07:34 2019 +0200 +++ b/Framework/Scene2D/ScenePoint2D.h Tue Jun 25 15:24:13 2019 +0200 @@ -13,7 +13,7 @@ * 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/>. **/ @@ -22,7 +22,7 @@ #pragma once #include "../Toolbox/AffineTransform2D.h" - +#include "../Toolbox/LinearAlgebra.h" namespace OrthancStone { @@ -40,7 +40,7 @@ } ScenePoint2D(double x, - double y) : + double y) : x_(x), y_(y) { @@ -63,5 +63,74 @@ 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*(double a) const + { + ScenePoint2D v; + v.x_ = x_ * a; + v.y_ = y_ * a; + + return v; + } + + static double Dot(const ScenePoint2D& a, const ScenePoint2D& b) + { + return a.x_ * b.x_ + a.y_ * b.y_; + } + + static double SquaredDistancePtPt(const ScenePoint2D& a, const ScenePoint2D& b) + { + ScenePoint2D n = b - a; + return Dot(n, n); + } + + /** + 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); + } + } }; } +