Lagrange
Loading...
Searching...
No Matches
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
35template <typename Scalar>
36std::array<Scalar, 2> triangle_circumcenter_2d(
40{
41 Scalar a = p2[0] - p1[0];
42 Scalar b = p2[1] - p1[1];
43 Scalar c = p3[0] - p1[0];
44 Scalar d = p3[1] - p1[1];
45 Scalar e = a * (p1[0] + p2[0]) + b * (p1[1] + p2[1]);
46 Scalar f = c * (p1[0] + p3[0]) + d * (p1[1] + p3[1]);
47 Scalar g = 2 * (a * (p3[1] - p2[1]) - b * (p3[0] - p2[0]));
48
49 if (std::abs(g) < std::numeric_limits<Scalar>::epsilon()) {
50 Scalar minx = std::min({p1[0], p2[0], p3[0]});
51 Scalar miny = std::min({p1[1], p2[1], p3[1]});
52 Scalar dx = (std::max({p1[0], p2[0], p3[0]}) - minx) * 0.5f;
53 Scalar dy = (std::max({p1[1], p2[1], p3[1]}) - miny) * 0.5f;
54
55 return {minx + dx, miny + dy};
56 } else {
57 return {(d * e - b * f) / g, (a * f - c * e) / g};
58 }
59}
60
61// Returns the circumcenter of a 2D triangle.
62template <typename Scalar>
63Eigen::Vector2<Scalar> triangle_circumcenter_2d(
64 const Eigen::Vector2<Scalar>& p1,
65 const Eigen::Vector2<Scalar>& p2,
66 const Eigen::Vector2<Scalar>& p3)
67{
68 auto r = triangle_circumcenter_2d<Scalar>(
69 span<const Scalar, 2>({p1.x(), p1.y()}),
70 span<const Scalar, 2>({p2.x(), p2.y()}),
71 span<const Scalar, 2>({p3.x(), p3.y()}));
72 return Eigen::Vector2<Scalar>(r[0], r[1]);
73}
74
75
76template <typename Scalar>
77[[deprecated]]
78Eigen::Vector2<Scalar> triangle_circumcenter(
79 const Eigen::Vector2<Scalar>& p1,
80 const Eigen::Vector2<Scalar>& p2,
81 const Eigen::Vector2<Scalar>& p3)
82{
83 auto r = triangle_circumcenter_2d<Scalar>({p1.x(), p1.y()}, {p2.x(), p2.y()}, {p3.x(), p3.y()});
84 return Eigen::Vector2<Scalar>(r[0], r[1]);
85}
86
87} // namespace lagrange
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
::nonstd::span< T, Extent > span
A bounds-safe view for sequences of objects.
Definition span.h:27
Main namespace for Lagrange.
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