42cf5bc1 |
1 | // Created on: 1993-02-17 |
2 | // Created by: Remi LEQUETTE |
3 | // Copyright (c) 1993-1999 Matra Datavision |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
5 | // |
6 | // This file is part of Open CASCADE Technology software library. |
7 | // |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
13 | // |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
16 | |
17 | #ifndef _Precision_HeaderFile |
18 | #define _Precision_HeaderFile |
19 | |
20 | #include <Standard.hxx> |
21 | #include <Standard_DefineAlloc.hxx> |
22 | #include <Standard_Handle.hxx> |
23 | |
24 | #include <Standard_Real.hxx> |
25 | #include <Standard_Boolean.hxx> |
26 | |
27 | |
28 | //! The Precision package offers a set of functions defining precision criteria |
29 | //! for use in conventional situations when comparing two numbers. |
30 | //! Generalities |
31 | //! It is not advisable to use floating number equality. Instead, the difference |
32 | //! between numbers must be compared with a given precision, i.e. : |
33 | //! Standard_Real x1, x2 ; |
34 | //! x1 = ... |
35 | //! x2 = ... |
36 | //! If ( x1 == x2 ) ... |
37 | //! should not be used and must be written as indicated below: |
38 | //! Standard_Real x1, x2 ; |
39 | //! Standard_Real Precision = ... |
40 | //! x1 = ... |
41 | //! x2 = ... |
42 | //! If ( Abs ( x1 - x2 ) < Precision ) ... |
43 | //! Likewise, when ordering floating numbers, you must take the following into account : |
44 | //! Standard_Real x1, x2 ; |
45 | //! Standard_Real Precision = ... |
46 | //! x1 = ... ! a large number |
47 | //! x2 = ... ! another large number |
48 | //! If ( x1 < x2 - Precision ) ... |
49 | //! is incorrect when x1 and x2 are large numbers ; it is better to write : |
50 | //! Standard_Real x1, x2 ; |
51 | //! Standard_Real Precision = ... |
52 | //! x1 = ... ! a large number |
53 | //! x2 = ... ! another large number |
54 | //! If ( x2 - x1 > Precision ) ... |
55 | //! Precision in Cas.Cade |
56 | //! Generally speaking, the precision criterion is not implicit in Cas.Cade. Low-level geometric algorithms accept |
57 | //! precision criteria as arguments. As a rule, they should not refer directly to the precision criteria provided by the |
58 | //! Precision package. |
59 | //! On the other hand, high-level modeling algorithms have to provide the low-level geometric algorithms that they |
60 | //! call, with a precision criteria. One way of doing this is to use the above precision criteria. |
61 | //! Alternatively, the high-level algorithms can have their own system for precision management. For example, the |
62 | //! Topology Data Structure stores precision criteria for each elementary shape (as a vertex, an edge or a face). When |
63 | //! a new topological object is constructed, the precision criteria are taken from those provided by the Precision |
64 | //! package, and stored in the related data structure. Later, a topological algorithm which analyses these objects will |
65 | //! work with the values stored in the data structure. Also, if this algorithm is to build a new topological object, from |
66 | //! these precision criteria, it will compute a new precision criterion for the new topological object, and write it into the |
67 | //! data structure of the new topological object. |
68 | //! The different precision criteria offered by the Precision package, cover the most common requirements of |
69 | //! geometric algorithms, such as intersections, approximations, and so on. |
70 | //! The choice of precision depends on the algorithm and on the geometric space. The geometric space may be : |
71 | //! - a "real" 2D or 3D space, where the lengths are measured in meters, millimeters, microns, inches, etc ..., or |
72 | //! - a "parametric" space, 1D on a curve or 2D on a surface, where lengths have no dimension. |
73 | //! The choice of precision criteria for real space depends on the choice of the product, as it is based on the accuracy |
74 | //! of the machine and the unit of measurement. |
75 | //! The choice of precision criteria for parametric space depends on both the accuracy of the machine and the |
76 | //! dimensions of the curve or the surface, since the parametric precision criterion and the real precision criterion are |
77 | //! linked : if the curve is defined by the equation P(t), the inequation : |
78 | //! Abs ( t2 - t1 ) < ParametricPrecision |
79 | //! means that the parameters t1 and t2 are considered to be equal, and the inequation : |
80 | //! Distance ( P(t2) , P(t1) ) < RealPrecision |
81 | //! means that the points P(t1) and P(t2) are considered to be coincident. It seems to be the same idea, and it |
82 | //! would be wonderful if these two inequations were equivalent. Note that this is rarely the case ! |
83 | //! What is provided in this package? |
84 | //! The Precision package provides : |
85 | //! - a set of real space precision criteria for the algorithms, in view of checking distances and angles, |
86 | //! - a set of parametric space precision criteria for the algorithms, in view of checking both : |
87 | //! - the equality of parameters in a parametric space, |
88 | //! - or the coincidence of points in the real space, by using parameter values, |
89 | //! - the notion of infinite value, composed of a value assumed to be infinite, and checking tests designed to verify |
90 | //! if any value could be considered as infinite. |
91 | //! All the provided functions are very simple. The returned values result from the adaptation of the applications |
92 | //! developed by the Open CASCADE company to Open CASCADE algorithms. The main interest of these functions |
93 | //! lies in that it incites engineers developing applications to ask questions on precision factors. Which one is to be |
94 | //! used in such or such case ? Tolerance criteria are context dependent. They must first choose : |
95 | //! - either to work in real space, |
96 | //! - or to work in parametric space, |
97 | //! - or to work in a combined real and parametric space. |
98 | //! They must next decide which precision factor will give the best answer to the current problem. Within an application |
99 | //! environment, it is crucial to master precision even though this process may take a great deal of time. |
100 | class Precision |
101 | { |
102 | public: |
103 | |
104 | DEFINE_STANDARD_ALLOC |
105 | |
106 | |
107 | //! Returns the recommended precision value |
108 | //! when checking the equality of two angles (given in radians). |
109 | //! Standard_Real Angle1 = ... , Angle2 = ... ; |
110 | //! If ( Abs( Angle2 - Angle1 ) < Precision::Angular() ) ... |
111 | //! The tolerance of angular equality may be used to check the parallelism of two vectors : |
112 | //! gp_Vec V1, V2 ; |
113 | //! V1 = ... |
114 | //! V2 = ... |
115 | //! If ( V1.IsParallel (V2, Precision::Angular() ) ) ... |
116 | //! The tolerance of angular equality is equal to 1.e-12. |
117 | //! Note : The tolerance of angular equality can be used when working with scalar products or |
118 | //! cross products since sines and angles are equivalent for small angles. Therefore, in order to |
119 | //! check whether two unit vectors are perpendicular : |
120 | //! gp_Dir D1, D2 ; |
121 | //! D1 = ... |
122 | //! D2 = ... |
123 | //! you can use : |
124 | //! If ( Abs( D1.D2 ) < Precision::Angular() ) ... |
125 | //! (although the function IsNormal does exist). |
be5c3602 |
126 | static Standard_Real Angular(); |
42cf5bc1 |
127 | |
128 | |
129 | //! Returns the recommended precision value when |
130 | //! checking coincidence of two points in real space. |
131 | //! The tolerance of confusion is used for testing a 3D |
132 | //! distance : |
133 | //! - Two points are considered to be coincident if their |
134 | //! distance is smaller than the tolerance of confusion. |
135 | //! gp_Pnt P1, P2 ; |
136 | //! P1 = ... |
137 | //! P2 = ... |
138 | //! if ( P1.IsEqual ( P2 , Precision::Confusion() ) ) |
139 | //! then ... |
140 | //! - A vector is considered to be null if it has a null length : |
141 | //! gp_Vec V ; |
142 | //! V = ... |
143 | //! if ( V.Magnitude() < Precision::Confusion() ) then ... |
144 | //! The tolerance of confusion is equal to 1.e-7. |
145 | //! The value of the tolerance of confusion is also used to |
146 | //! define : |
147 | //! - the tolerance of intersection, and |
148 | //! - the tolerance of approximation. |
149 | //! Note : As a rule, coordinate values in Cas.Cade are not |
150 | //! dimensioned, so 1. represents one user unit, whatever |
151 | //! value the unit may have : the millimeter, the meter, the |
152 | //! inch, or any other unit. Let's say that Cas.Cade |
153 | //! algorithms are written to be tuned essentially with |
154 | //! mechanical design applications, on the basis of the |
155 | //! millimeter. However, these algorithms may be used with |
156 | //! any other unit but the tolerance criterion does no longer |
157 | //! have the same signification. |
158 | //! So pay particular attention to the type of your application, |
159 | //! in relation with the impact of your unit on the precision criterion. |
160 | //! - For example in mechanical design, if the unit is the |
161 | //! millimeter, the tolerance of confusion corresponds to a |
162 | //! distance of 1 / 10000 micron, which is rather difficult to measure. |
163 | //! - However in other types of applications, such as |
164 | //! cartography, where the kilometer is frequently used, |
165 | //! the tolerance of confusion corresponds to a greater |
166 | //! distance (1 / 10 millimeter). This distance |
167 | //! becomes easily measurable, but only within a restricted |
168 | //! space which contains some small objects of the complete scene. |
be5c3602 |
169 | static Standard_Real Confusion(); |
42cf5bc1 |
170 | |
171 | |
172 | //! Returns square of Confusion. |
173 | //! Created for speed and convenience. |
be5c3602 |
174 | static Standard_Real SquareConfusion(); |
42cf5bc1 |
175 | |
176 | //! Returns the precision value in real space, frequently |
177 | //! used by intersection algorithms to decide that a solution is reached. |
178 | //! This function provides an acceptable level of precision |
179 | //! for an intersection process to define the adjustment limits. |
180 | //! The tolerance of intersection is designed to ensure |
181 | //! that a point computed by an iterative algorithm as the |
182 | //! intersection between two curves is indeed on the |
183 | //! intersection. It is obvious that two tangent curves are |
184 | //! close to each other, on a large distance. An iterative |
185 | //! algorithm of intersection may find points on these |
186 | //! curves within the scope of the confusion tolerance, but |
187 | //! still far from the true intersection point. In order to force |
188 | //! the intersection algorithm to continue the iteration |
189 | //! process until a correct point is found on the tangent |
190 | //! objects, the tolerance of intersection must be smaller |
191 | //! than the tolerance of confusion. |
192 | //! On the other hand, the tolerance of intersection must |
193 | //! be large enough to minimize the time required by the |
194 | //! process to converge to a solution. |
195 | //! The tolerance of intersection is equal to : |
196 | //! Precision::Confusion() / 100. |
197 | //! (that is, 1.e-9). |
be5c3602 |
198 | static Standard_Real Intersection(); |
42cf5bc1 |
199 | |
200 | //! Returns the precision value in real space, frequently used |
201 | //! by approximation algorithms. |
202 | //! This function provides an acceptable level of precision for |
203 | //! an approximation process to define adjustment limits. |
204 | //! The tolerance of approximation is designed to ensure |
205 | //! an acceptable computation time when performing an |
206 | //! approximation process. That is why the tolerance of |
207 | //! approximation is greater than the tolerance of confusion. |
208 | //! The tolerance of approximation is equal to : |
209 | //! Precision::Confusion() * 10. |
210 | //! (that is, 1.e-6). |
211 | //! You may use a smaller tolerance in an approximation |
212 | //! algorithm, but this option might be costly. |
be5c3602 |
213 | static Standard_Real Approximation(); |
42cf5bc1 |
214 | |
215 | //! Convert a real space precision to a parametric |
216 | //! space precision. <T> is the mean value of the |
217 | //! length of the tangent of the curve or the surface. |
218 | //! |
219 | //! Value is P / T |
220 | static Standard_Real Parametric (const Standard_Real P, const Standard_Real T); |
221 | |
222 | |
223 | //! Returns a precision value in parametric space, which may be used : |
224 | //! - to test the coincidence of two points in the real space, |
225 | //! by using parameter values, or |
226 | //! - to test the equality of two parameter values in a parametric space. |
227 | //! The parametric tolerance of confusion is designed to |
228 | //! give a mean value in relation with the dimension of |
229 | //! the curve or the surface. It considers that a variation of |
230 | //! parameter equal to 1. along a curve (or an |
231 | //! isoparametric curve of a surface) generates a segment |
232 | //! whose length is equal to 100. (default value), or T. |
233 | //! The parametric tolerance of confusion is equal to : |
234 | //! - Precision::Confusion() / 100., or Precision::Confusion() / T. |
235 | //! The value of the parametric tolerance of confusion is also used to define : |
236 | //! - the parametric tolerance of intersection, and |
237 | //! - the parametric tolerance of approximation. |
238 | //! Warning |
239 | //! It is rather difficult to define a unique precision value in parametric space. |
240 | //! - First consider a curve (c) ; if M is the point of |
241 | //! parameter u and M' the point of parameter u+du on |
242 | //! the curve, call 'parametric tangent' at point M, for the |
243 | //! variation du of the parameter, the quantity : |
244 | //! T(u,du)=MM'/du (where MM' represents the |
245 | //! distance between the two points M and M', in the real space). |
246 | //! - Consider the other curve resulting from a scaling |
247 | //! transformation of (c) with a scale factor equal to |
248 | //! 10. The 'parametric tangent' at the point of |
249 | //! parameter u of this curve is ten times greater than the |
250 | //! previous one. This shows that for two different curves, |
251 | //! the distance between two points on the curve, resulting |
252 | //! from the same variation of parameter du, may vary considerably. |
253 | //! - Moreover, the variation of the parameter along the |
254 | //! curve is generally not proportional to the curvilinear |
255 | //! abscissa along the curve. So the distance between two |
256 | //! points resulting from the same variation of parameter |
257 | //! du, at two different points of a curve, may completely differ. |
258 | //! - Moreover, the parameterization of a surface may |
259 | //! generate two quite different 'parametric tangent' values |
260 | //! in the u or in the v parametric direction. |
261 | //! - Last, close to the poles of a sphere (the points which |
262 | //! correspond to the values -Pi/2. and Pi/2. of the |
263 | //! v parameter) the u parameter may change from 0 to |
264 | //! 2.Pi without impacting on the resulting point. |
265 | //! Therefore, take great care when adjusting a parametric |
266 | //! tolerance to your own algorithm. |
be5c3602 |
267 | static Standard_Real PConfusion (const Standard_Real T); |
42cf5bc1 |
268 | |
269 | |
270 | //! Returns a precision value in parametric space, which |
271 | //! may be used by intersection algorithms, to decide that |
272 | //! a solution is reached. The purpose of this function is to |
273 | //! provide an acceptable level of precision in parametric |
274 | //! space, for an intersection process to define the adjustment limits. |
275 | //! The parametric tolerance of intersection is |
276 | //! designed to give a mean value in relation with the |
277 | //! dimension of the curve or the surface. It considers |
278 | //! that a variation of parameter equal to 1. along a curve |
279 | //! (or an isoparametric curve of a surface) generates a |
280 | //! segment whose length is equal to 100. (default value), or T. |
281 | //! The parametric tolerance of intersection is equal to : |
282 | //! - Precision::Intersection() / 100., or Precision::Intersection() / T. |
be5c3602 |
283 | static Standard_Real PIntersection (const Standard_Real T); |
42cf5bc1 |
284 | |
285 | //! Returns a precision value in parametric space, which may |
286 | //! be used by approximation algorithms. The purpose of this |
287 | //! function is to provide an acceptable level of precision in |
288 | //! parametric space, for an approximation process to define |
289 | //! the adjustment limits. |
290 | //! The parametric tolerance of approximation is |
291 | //! designed to give a mean value in relation with the |
292 | //! dimension of the curve or the surface. It considers |
293 | //! that a variation of parameter equal to 1. along a curve |
294 | //! (or an isoparametric curve of a surface) generates a |
295 | //! segment whose length is equal to 100. (default value), or T. |
296 | //! The parametric tolerance of intersection is equal to : |
297 | //! - Precision::Approximation() / 100., or Precision::Approximation() / T. |
be5c3602 |
298 | static Standard_Real PApproximation (const Standard_Real T); |
42cf5bc1 |
299 | |
300 | //! Convert a real space precision to a parametric |
301 | //! space precision on a default curve. |
302 | //! |
303 | //! Value is Parametric(P,1.e+2) |
be5c3602 |
304 | static Standard_Real Parametric (const Standard_Real P); |
42cf5bc1 |
305 | |
306 | //! Used to test distances in parametric space on a |
307 | //! default curve. |
308 | //! |
309 | //! This is Precision::Parametric(Precision::Confusion()) |
310 | static Standard_Real PConfusion(); |
311 | |
312 | //! Used for Intersections in parametric space on a |
313 | //! default curve. |
314 | //! |
315 | //! This is Precision::Parametric(Precision::Intersection()) |
316 | static Standard_Real PIntersection(); |
317 | |
318 | //! Used for Approximations in parametric space on a |
319 | //! default curve. |
320 | //! |
321 | //! This is Precision::Parametric(Precision::Approximation()) |
322 | static Standard_Real PApproximation(); |
323 | |
324 | //! Returns True if R may be considered as an infinite |
325 | //! number. Currently Abs(R) > 1e100 |
be5c3602 |
326 | static Standard_Boolean IsInfinite (const Standard_Real R); |
42cf5bc1 |
327 | |
328 | //! Returns True if R may be considered as a positive |
329 | //! infinite number. Currently R > 1e100 |
be5c3602 |
330 | static Standard_Boolean IsPositiveInfinite (const Standard_Real R); |
42cf5bc1 |
331 | |
332 | //! Returns True if R may be considered as a negative |
333 | //! infinite number. Currently R < -1e100 |
be5c3602 |
334 | static Standard_Boolean IsNegativeInfinite (const Standard_Real R); |
42cf5bc1 |
335 | |
336 | //! Returns a big number that can be considered as |
337 | //! infinite. Use -Infinite() for a negative big number. |
be5c3602 |
338 | static Standard_Real Infinite(); |
42cf5bc1 |
339 | |
340 | |
341 | |
342 | |
343 | protected: |
344 | |
345 | |
346 | |
347 | |
348 | |
349 | private: |
350 | |
351 | |
352 | |
353 | |
354 | |
355 | }; |
356 | |
357 | |
358 | #include <Precision.lxx> |
359 | |
360 | |
361 | |
362 | |
363 | |
364 | #endif // _Precision_HeaderFile |