d30895f5 |
1 | // Created on: 2016-06-07 |
2 | // Created by: Nikolai BUKHALOV |
3 | // Copyright (c) 2016 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | |
17 | #include <Bnd_Range.hxx> |
0904aa63 |
18 | #include <Standard_Dump.hxx> |
d30895f5 |
19 | |
20 | //======================================================================= |
21 | //function : Common |
22 | //purpose : |
23 | //======================================================================= |
24 | void Bnd_Range::Common(const Bnd_Range& theOther) |
25 | { |
26 | if(theOther.IsVoid()) |
27 | { |
28 | SetVoid(); |
29 | } |
30 | |
31 | if(IsVoid()) |
32 | { |
33 | return; |
34 | } |
35 | |
36 | myFirst = Max(myFirst, theOther.myFirst); |
37 | myLast = Min(myLast, theOther.myLast); |
38 | } |
261b7d9e |
39 | |
40 | //======================================================================= |
41 | //function : Union |
42 | //purpose : |
43 | //======================================================================= |
44 | Standard_Boolean Bnd_Range::Union(const Bnd_Range& theOther) |
45 | { |
46 | if (IsVoid() || theOther.IsVoid()) |
47 | return Standard_False; |
48 | |
49 | if (myLast < theOther.myFirst) |
50 | return Standard_False; |
51 | |
52 | if (myFirst > theOther.myLast) |
53 | return Standard_False; |
54 | |
55 | myFirst = Min(myFirst, theOther.myFirst); |
56 | myLast = Max(myLast, theOther.myLast); |
57 | |
58 | return Standard_True; |
59 | } |
60 | |
61 | //======================================================================= |
62 | //function : IsIntersected |
63 | //purpose : |
64 | //======================================================================= |
65 | Standard_Integer Bnd_Range::IsIntersected(const Standard_Real theVal, |
66 | const Standard_Real thePeriod) const |
67 | { |
68 | if (IsVoid()) |
69 | return Standard_False; |
70 | |
71 | const Standard_Real aPeriod = Abs(thePeriod); |
72 | const Standard_Real aDF = myFirst - theVal, |
73 | aDL = myLast - theVal; |
74 | |
75 | if (aPeriod <= RealSmall()) |
76 | { |
77 | const Standard_Real aDelta = aDF*aDL; |
78 | if (IsEqual(aDelta, 0.0)) |
79 | return 2; |
80 | |
81 | if (aDelta > 0.0) |
82 | return 0; |
83 | |
84 | return 1; |
85 | } |
86 | |
87 | //If <this> intersects theVal then there exists an integer |
88 | //number N such as |
89 | // (myFirst <= theVal+aPeriod*N <= myLast) <=> |
90 | // ((myFirst-theVal)/aPeriod <= N <= (myLast-theVal)/aPeriod). |
91 | //I.e. the interval [aDF/aPeriod, aDL/aPeriod] must contain at least one |
92 | //integer number. |
93 | //In this case, Floor(aDF/aPeriod) and Floor(aDL/aPeriod) |
94 | //return different values or aDF/aPeriod (aDL/aPeriod) |
95 | //is strictly integer number. |
96 | //Examples: |
97 | // 1. (aDF/aPeriod==2.8, aDL/aPeriod==3.5 => |
98 | // Floor(aDF/aPeriod) == 2, Floor(aDL/aPeriod) == 3. |
99 | // 2. aDF/aPeriod==2.0, aDL/aPeriod==2.6 => |
100 | // Floor(aDF/aPeriod) == Floor(aDL/aPeriod) == 2. |
101 | |
102 | const Standard_Real aVal1 = aDF / aPeriod, |
103 | aVal2 = aDL / aPeriod; |
104 | const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1)); |
105 | const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2)); |
106 | if (aPar1 != aPar2) |
107 | {//Interval (myFirst, myLast] intersects seam-edge |
108 | if (IsEqual(aVal2, static_cast<Standard_Real>(aPar2))) |
109 | {//aVal2 is an integer number => myLast lies ON the "seam-edge" |
110 | return 2; |
111 | } |
112 | |
113 | return 1; |
114 | } |
115 | |
116 | //Here, aPar1 == aPar2. |
117 | |
118 | if (IsEqual(aVal1, static_cast<Standard_Real>(aPar1))) |
119 | {//aVal1 is an integer number => myFirst lies ON the "seam-edge" |
120 | return 2; |
121 | } |
122 | |
123 | #if 0 |
124 | // This check is excess because always myFirst <= myLast. |
125 | // So, this condition is never satisfied. |
126 | if (IsEqual(aVal2, static_cast<Standard_Real>(aPar2))) |
127 | {//aVal2 is an integer number => myLast lies ON the "seam-edge" |
128 | return 2; |
129 | } |
130 | #endif |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | //======================================================================= |
136 | //function : Split |
137 | //purpose : |
138 | //======================================================================= |
139 | void Bnd_Range::Split(const Standard_Real theVal, |
140 | NCollection_List<Bnd_Range>& theList, |
141 | const Standard_Real thePeriod) const |
142 | { |
143 | const Standard_Real aPeriod = Abs(thePeriod); |
144 | if (IsIntersected(theVal, aPeriod) != 1) |
145 | { |
146 | theList.Append(*this); |
147 | return; |
148 | } |
149 | |
150 | const Standard_Boolean isPeriodic = (aPeriod > 0.0); |
151 | |
152 | if (!isPeriodic) |
153 | { |
154 | theList.Append(Bnd_Range(myFirst, theVal)); |
155 | theList.Append(Bnd_Range(theVal, myLast)); |
156 | return; |
157 | } |
158 | |
159 | Standard_Real aValPrev = theVal + aPeriod*Ceiling((myFirst - theVal) / aPeriod); |
160 | |
161 | //Now, (myFirst <= aValPrev < myFirst+aPeriod). |
162 | |
163 | if (aValPrev > myFirst) |
164 | { |
165 | theList.Append(Bnd_Range(myFirst, aValPrev)); |
166 | } |
167 | |
168 | for (Standard_Real aVal = aValPrev+aPeriod; aVal <= myLast; aVal += aPeriod) |
169 | { |
170 | theList.Append(Bnd_Range(aValPrev, aVal)); |
171 | aValPrev = aVal; |
172 | } |
173 | |
174 | if (aValPrev < myLast) |
175 | { |
176 | theList.Append(Bnd_Range(aValPrev, myLast)); |
177 | } |
0904aa63 |
178 | } |
179 | |
180 | // ======================================================================= |
181 | // function : DumpJson |
182 | // purpose : |
183 | // ======================================================================= |
bc73b006 |
184 | void Bnd_Range::DumpJson (Standard_OStream& theOStream, Standard_Integer) const |
0904aa63 |
185 | { |
bc73b006 |
186 | OCCT_DUMP_CLASS_BEGIN (theOStream, Bnd_Range) |
0904aa63 |
187 | |
bc73b006 |
188 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myFirst) |
189 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLast) |
0904aa63 |
190 | } |