Skip to content

Commit b6952bc

Browse files
committed
floating point accuracy
1 parent 5a5a3a5 commit b6952bc

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Package: lidR
22
Type: Package
33
Title: Airborne LiDAR Data Manipulation and Visualization for Forestry
44
Applications
5-
Version: 4.1.1
5+
Version: 4.1.2
66
Authors@R: c(
77
person("Jean-Romain", "Roussel", email = "[email protected]", role = c("aut", "cre", "cph")),
88
person("David", "Auty", email = "", role = c("aut", "ctb"), comment = "Reviews the documentation"),

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
If you are viewing this file on CRAN, please check [the latest news on GitHub](https://github.com/r-lidar/lidR/blob/master/NEWS.md) where the formatting is also better
22

3+
## lidR v4.1.2 (Release date: )
4+
5+
- Fix: strongly improved arithmetic accuracy in `point_in_triangle` to improve the quality of delaunay triangulation interpolations and avoid local NAs
6+
7+
38
## lidR v4.1.1 (Release date: 2024-02-03)
49

510
Fix: `readLAScatalog()` was not working if package `raster` was not installed.

inst/include/lidR/Shapes.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace lidR
77
{
88

9-
#define EPSILON 2e-8
9+
#define EPSILON 1e-8
1010
#define XYINF 99999999999;
1111
#define ZINF 2147483640;
1212
#define MAX(a,b,c) ((a>b)?((a>c)?a:c):((b>c)?b:c));
@@ -207,27 +207,31 @@ inline Triangle::Triangle(Point& A, Point& B, Point& C)
207207
}
208208

209209
template<typename T>
210-
bool Triangle::contains(const T& p)
210+
bool Triangle::contains(const T& P)
211211
{
212-
if (p.x < xmin - EPSILON || p.x > xmax + EPSILON || p.y < ymin - EPSILON || p.y > ymax + EPSILON)
212+
if (P.x < xmin - EPSILON || P.x > xmax + EPSILON || P.y < ymin - EPSILON || P.y > ymax + EPSILON)
213213
return false;
214214

215-
double denominator = (A.x*(B.y - C.y) + A.y*(C.x - B.x) + B.x*C.y - B.y*C.x);
216-
double t1 = (p.x*(C.y - A.y) + p.y*(A.x - C.x) - A.x*C.y + A.y*C.x) / denominator;
217-
double t2 = (p.x*(B.y - A.y) + p.y*(A.x - B.x) - A.x*B.y + A.y*B.x) / -denominator;
215+
// move to (0,0) to gain arithmetic precision
216+
double x_offset = xmin;
217+
double y_offset = ymin;
218+
PointXY a(A.x - x_offset, A.y - y_offset);
219+
PointXY b(B.x - x_offset, B.y - y_offset);
220+
PointXY c(C.x - x_offset, C.y - y_offset);
221+
PointXY p(P.x - x_offset, P.y - y_offset);
222+
223+
double denominator = (a.x*(b.y - c.y) + a.y*(c.x - b.x) + b.x*c.y - b.y*c.x);
224+
double t1 = (p.x*(c.y - a.y) + p.y*(a.x - c.x) - a.x*c.y + a.y*c.x) / denominator;
225+
double t2 = (p.x*(b.y - a.y) + p.y*(a.x - b.x) - a.x*b.y + a.y*b.x) / -denominator;
218226
double s = t1 + t2;
219227

220228
if (0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && s <= 1)
221229
return true;
222230

223231
// see http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html
224-
225-
if (distanceSquarePointToSegment(A, B, p) <= EPSILON)
226-
return true;
227-
if (distanceSquarePointToSegment(B, C, p) <= EPSILON)
228-
return true;
229-
if (distanceSquarePointToSegment(C, A, p) <= EPSILON)
230-
return true;
232+
if (distanceSquarePointToSegment(a, b, p) <= EPSILON) return true;
233+
if (distanceSquarePointToSegment(b, c, p) <= EPSILON) return true;
234+
if (distanceSquarePointToSegment(c, a, p) <= EPSILON) return true;
231235

232236
return false;
233237
}

0 commit comments

Comments
 (0)