1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Utilities for robust floating-point comparisons in geometric code.
//!
//! This module provides [`FloatSign`] and [`classify_to_zero`] for classifying
//! values relative to zero with an epsilon tolerance, avoiding brittle `== 0`
//! checks in the presence of numerical error.
use Float;
/// Classification of a value relative to zero using an epsilon tolerance.
///
/// Used throughout the library for robust geometric tests (e.g. whether a point
/// lies on a plane or a segment is parallel to another). Values whose absolute
/// value is below the tolerance are treated as [`Zero`](FloatSign::Zero).
///
/// # Example
///
/// ```
/// use apollonius::{classify_to_zero, FloatSign};
///
/// match classify_to_zero(1e-10, None) {
/// FloatSign::Positive => {}
/// FloatSign::Zero => {} // tiny values are treated as zero
/// FloatSign::Negative => {}
/// }
/// ```
/// Classifies a floating-point number relative to zero using an epsilon threshold.
///
/// This utility is essential for robust geometric calculations where precision
/// errors can cause strict equality checks (`val == 0.0`) to fail.
///
/// # Arguments
/// * `val` - The value to classify.
/// * `epsilon_override` - An optional custom threshold. Defaults to `1e-6` if `None`.
///
/// # Examples
///
/// ```
/// use apollonius::{classify_to_zero, FloatSign};
///
/// // Values smaller than epsilon are treated as Zero
/// let tiny = 1e-8;
/// assert_eq!(classify_to_zero(tiny, None), FloatSign::Zero);
///
/// // Values larger than epsilon are classified by their sign
/// let big = 10.0;
/// assert_eq!(classify_to_zero(big, None), FloatSign::Positive);
///
/// let neg = -5.0;
/// assert_eq!(classify_to_zero(neg, None), FloatSign::Negative);
/// ```