Lagrange
geometry2d.h
1/*
2 * Copyright 2020 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <Eigen/Core>
15
16namespace lagrange {
17
19template <typename Scalar>
21 const Eigen::Vector2<Scalar>& a,
22 const Eigen::Vector2<Scalar>& b,
23 const Eigen::Vector2<Scalar>& p)
24{
25 const Scalar l2 = (a - b).squaredNorm();
26 if (l2 == 0.0) return (p - a).squaredNorm(); // a==b
27
28 Scalar t = (p - a).dot(b - a) / l2;
29 if (t < 0) t = Scalar(0);
30 if (t > 1) t = Scalar(1);
31 const Eigen::Vector2<Scalar> projection = a + t * (b - a);
32 return (p - projection).squaredNorm();
33}
34
35// Returns the circumcenter of a 2D triangle.
36template <typename Scalar>
37Eigen::Vector2<Scalar> triangle_circumcenter(
38 const Eigen::Vector2<Scalar>& p1,
39 const Eigen::Vector2<Scalar>& p2,
40 const Eigen::Vector2<Scalar>& p3)
41{
42 Scalar a = p2.x() - p1.x();
43 Scalar b = p2.y() - p1.y();
44 Scalar c = p3.x() - p1.x();
45 Scalar d = p3.y() - p1.y();
46 Scalar e = a * (p1.x() + p2.x()) + b * (p1.y() + p2.y());
47 Scalar f = c * (p1.x() + p3.x()) + d * (p1.y() + p3.y());
48 Scalar g = 2 * (a * (p3.y() - p2.y()) - b * (p3.x() - p2.x()));
49
50 if (std::abs(g) < std::numeric_limits<Scalar>::epsilon()) {
51 Scalar minx = std::min({p1.x(), p2.x(), p3.x()});
52 Scalar miny = std::min({p1.y(), p2.y(), p3.y()});
53 Scalar dx = (std::max({p1.x(), p2.x(), p3.x()}) - minx) * 0.5f;
54 Scalar dy = (std::max({p1.y(), p2.y(), p3.y()}) - miny) * 0.5f;
55
56 return Eigen::Vector2<Scalar>(minx + dx, miny + dy);
57 } else {
58 Eigen::Vector2<Scalar> center((d * e - b * f) / g, (a * f - c * e) / g);
59 return center;
60 }
61}
62
63} // namespace lagrange
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Scalar sqr_minimum_distance(const Eigen::Vector2< Scalar > &a, const Eigen::Vector2< Scalar > &b, const Eigen::Vector2< Scalar > &p)
Returns the squared minimum distance between 2d line segment ab and point p.
Definition: geometry2d.h:20