• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pmp-library / pmp-library / 25581337924

08 May 2026 09:51PM UTC coverage: 89.809% (-1.2%) from 90.99%
25581337924

push

github

dsieger
Simplify decimation test, disable unsupported test

Closes #248

5173 of 5760 relevant lines covered (89.81%)

603378.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.72
/src/pmp/algorithms/distance_point_triangle.cpp
1
// Copyright 2011-2020 the Polygon Mesh Processing Library developers.
2
// SPDX-License-Identifier: MIT
3

4
#include "pmp/algorithms/distance_point_triangle.h"
5

6
#include <cmath>
7

8
#include <limits>
9

10
namespace pmp {
11

12
Scalar dist_point_line_segment(const Point& p, const Point& v0, const Point& v1,
3✔
13
                               Point& nearest_point)
14
{
15
    Point d1(p - v0);
3✔
16
    const Point d2(v1 - v0);
3✔
17
    Point min_v(v0);
3✔
18
    Scalar t = dot(d2, d2);
3✔
19

20
    if (t > std::numeric_limits<Scalar>::min())
3✔
21
    {
22
        t = dot(d1, d2) / t;
2✔
23
        if (t > 1.0)
2✔
24
            d1 = p - (min_v = v1);
×
25
        else if (t > 0.0)
2✔
26
            d1 = p - (min_v = v0 + d2 * t);
1✔
27
    }
28

29
    nearest_point = min_v;
3✔
30
    return norm(d1);
6✔
31
}
32

33
Scalar dist_point_triangle(const Point& p, const Point& v0, const Point& v1,
34,838✔
34
                           const Point& v2, Point& nearest_point)
35
{
36
    Point v0v1 = v1 - v0;
34,838✔
37
    Point v0v2 = v2 - v0;
34,838✔
38
    Point n = cross(v0v1, v0v2); // not normalized !
34,838✔
39
    const Scalar d = sqrnorm(n);
34,838✔
40

41
    // Check if the triangle is degenerated -> measure dist to line segments
42
    if (fabs(d) < std::numeric_limits<Scalar>::min())
34,838✔
43
    {
44
        Point query;
45
        Point nearest;
46

47
        auto distance = dist_point_line_segment(p, v0, v1, nearest);
1✔
48

49
        auto other = dist_point_line_segment(p, v1, v2, query);
1✔
50
        if (other < distance)
1✔
51
        {
52
            distance = other;
×
53
            nearest = query;
×
54
        }
55

56
        other = dist_point_line_segment(p, v2, v0, query);
1✔
57
        if (other < distance)
1✔
58
        {
59
            distance = other;
×
60
            nearest = query;
×
61
        }
62

63
        nearest_point = nearest;
1✔
64
        return distance;
1✔
65
    }
66

67
    const Scalar inv_d = 1.0 / d;
34,837✔
68
    Point v1v2 = v2;
34,837✔
69
    v1v2 -= v1;
34,837✔
70
    Point v0p = p;
34,837✔
71
    v0p -= v0;
34,837✔
72
    const Point t = cross(v0p, n);
34,837✔
73
    const Scalar a = dot(t, v0v2) * -inv_d;
34,837✔
74
    const Scalar b = dot(t, v0v1) * inv_d;
34,837✔
75
    Scalar s01, s02, s12;
76

77
    // Calculate the distance to an edge or a corner vertex
78
    if (a < 0)
34,837✔
79
    {
80
        s02 = dot(v0v2, v0p) / sqrnorm(v0v2);
10,079✔
81
        if (s02 < 0.0)
10,079✔
82
        {
83
            s01 = dot(v0v1, v0p) / sqrnorm(v0v1);
444✔
84
            if (s01 <= 0.0)
444✔
85
            {
86
                v0p = v0;
444✔
87
            }
88
            else if (s01 >= 1.0)
×
89
            {
90
                v0p = v1;
×
91
            }
92
            else
93
            {
94
                (v0p = v0) += (v0v1 *= s01);
×
95
            }
96
        }
97
        else if (s02 > 1.0)
9,635✔
98
        {
99
            s12 = dot(v1v2, (p - v1)) / sqrnorm(v1v2);
626✔
100
            if (s12 >= 1.0)
626✔
101
            {
102
                v0p = v2;
626✔
103
            }
104
            else if (s12 <= 0.0)
×
105
            {
106
                v0p = v1;
×
107
            }
108
            else
109
            {
110
                (v0p = v1) += (v1v2 *= s12);
×
111
            }
112
        }
113
        else
114
        {
115
            (v0p = v0) += (v0v2 *= s02);
9,009✔
116
        }
117
    }
118

119
    // Calculate the distance to an edge or a corner vertex
120
    else if (b < 0.0)
24,758✔
121
    {
122
        s01 = dot(v0v1, v0p) / sqrnorm(v0v1);
13,961✔
123
        if (s01 < 0.0)
13,961✔
124
        {
125
            s02 = dot(v0v2, v0p) / sqrnorm(v0v2);
1,878✔
126
            if (s02 <= 0.0)
1,878✔
127
            {
128
                v0p = v0;
1,878✔
129
            }
130
            else if (s02 >= 1.0)
×
131
            {
132
                v0p = v2;
×
133
            }
134
            else
135
            {
136
                (v0p = v0) += (v0v2 *= s02);
×
137
            }
138
        }
139
        else if (s01 > 1.0)
12,083✔
140
        {
141
            s12 = dot(v1v2, (p - v1)) / sqrnorm(v1v2);
679✔
142
            if (s12 >= 1.0)
679✔
143
            {
144
                v0p = v2;
×
145
            }
146
            else if (s12 <= 0.0)
679✔
147
            {
148
                v0p = v1;
679✔
149
            }
150
            else
151
            {
152
                (v0p = v1) += (v1v2 *= s12);
×
153
            }
154
        }
155
        else
156
        {
157
            (v0p = v0) += (v0v1 *= s01);
11,404✔
158
        }
159
    }
160

161
    // Calculate the distance to an edge or a corner vertex
162
    else if (a + b > 1.0)
10,797✔
163
    {
164
        s12 = dot(v1v2, (p - v1)) / sqrnorm(v1v2);
5,679✔
165
        if (s12 >= 1.0)
5,679✔
166
        {
167
            s02 = dot(v0v2, v0p) / sqrnorm(v0v2);
2,006✔
168
            if (s02 <= 0.0)
2,006✔
169
            {
170
                v0p = v0;
×
171
            }
172
            else if (s02 >= 1.0)
2,006✔
173
            {
174
                v0p = v2;
2,006✔
175
            }
176
            else
177
            {
178
                (v0p = v0) += (v0v2 *= s02);
×
179
            }
180
        }
181
        else if (s12 <= 0.0)
3,673✔
182
        {
183
            s01 = dot(v0v1, v0p) / sqrnorm(v0v1);
2,104✔
184
            if (s01 <= 0.0)
2,104✔
185
            {
186
                v0p = v0;
×
187
            }
188
            else if (s01 >= 1.0)
2,104✔
189
            {
190
                v0p = v1;
2,104✔
191
            }
192
            else
193
            {
194
                (v0p = v0) += (v0v1 *= s01);
×
195
            }
196
        }
197
        else
198
        {
199
            (v0p = v1) += (v1v2 *= s12);
1,569✔
200
        }
201
    }
202

203
    // Calculate the distance to an interior point of the triangle
204
    else
205
    {
206
        n *= (dot(n, v0p) * inv_d);
5,118✔
207
        (v0p = p) -= n;
5,118✔
208
    }
209

210
    nearest_point = v0p;
34,837✔
211
    v0p -= p;
34,837✔
212
    return norm(v0p);
34,837✔
213
}
214

215
} // namespace pmp
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc