FCL  0.6.0
Flexible Collision Library
interval-inl.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2016, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 // This code is based on code developed by Stephane Redon at UNC and Inria for the CATCH library: http://graphics.ewha.ac.kr/CATCH/
39 #ifndef FCL_CCD_INTERVAL_INL_H
40 #define FCL_CCD_INTERVAL_INL_H
41 
42 #include "fcl/math/motion/taylor_model/interval.h"
43 
44 namespace fcl
45 {
46 
47 //==============================================================================
48 extern template
49 struct Interval<double>;
50 
51 //==============================================================================
52 extern template
53 Interval<double> bound(const Interval<double>& i, double v);
54 
55 //==============================================================================
56 extern template
57 Interval<double> bound(const Interval<double>& i, const Interval<double>& other);
58 
59 //==============================================================================
60 template <typename S>
61 Interval<S>::Interval()
62 {
63  i_[0] = i_[1] = 0;
64 }
65 
66 //==============================================================================
67 template <typename S>
68 Interval<S>::Interval(S v)
69 {
70  i_[0] = i_[1] = v;
71 }
72 
73 //==============================================================================
74 template <typename S>
75 Interval<S>::Interval(S left, S right)
76 {
77  i_[0] = left; i_[1] = right;
78 }
79 
80 //==============================================================================
81 template <typename S>
82 void Interval<S>::setValue(S a, S b)
83 {
84  i_[0] = a; i_[1] = b;
85 }
86 
87 //==============================================================================
88 template <typename S>
90 {
91  i_[0] = i_[1] = x;
92 }
93 
94 //==============================================================================
95 template <typename S>
96 S Interval<S>::operator [] (size_t i) const
97 {
98  return i_[i];
99 }
100 
101 //==============================================================================
102 template <typename S>
104 {
105  return i_[i];
106 }
107 
108 //==============================================================================
109 template <typename S>
110 bool Interval<S>::operator == (const Interval& other) const
111 {
112  if(i_[0] != other.i_[0]) return false;
113  if(i_[1] != other.i_[1]) return false;
114  return true;
115 }
116 
117 //==============================================================================
118 template <typename S>
120 {
121  return Interval(i_[0] + other.i_[0], i_[1] + other.i_[1]);
122 }
123 
124 //==============================================================================
125 template <typename S>
127 {
128  return Interval(i_[0] - other.i_[1], i_[1] - other.i_[0]);
129 }
130 
131 //==============================================================================
132 template <typename S>
134 {
135  i_[0] += other.i_[0];
136  i_[1] += other.i_[1];
137  return *this;
138 }
139 
140 //==============================================================================
141 template <typename S>
143 {
144  i_[0] -= other.i_[1];
145  i_[1] -= other.i_[0];
146  return *this;
147 }
148 
149 //==============================================================================
150 template <typename S>
152 {
153  if(other.i_[0] >= 0)
154  {
155  if(i_[0] >= 0) return Interval<S>(i_[0] * other.i_[0], i_[1] * other.i_[1]);
156  if(i_[1] <= 0) return Interval<S>(i_[0] * other.i_[1], i_[1] * other.i_[0]);
157  return Interval<S>(i_[0] * other.i_[1], i_[1] * other.i_[1]);
158  }
159  if(other.i_[1] <= 0)
160  {
161  if(i_[0] >= 0) return Interval<S>(i_[1] * other.i_[0], i_[0] * other.i_[1]);
162  if(i_[1] <= 0) return Interval<S>(i_[1] * other.i_[1], i_[0] * other.i_[0]);
163  return Interval<S>(i_[1] * other.i_[0], i_[0] * other.i_[0]);
164  }
165 
166  if(i_[0] >= 0) return Interval<S>(i_[1] * other.i_[0], i_[1] * other.i_[1]);
167  if(i_[1] <= 0) return Interval<S>(i_[0] * other.i_[1], i_[0] * other.i_[0]);
168 
169  S v00 = i_[0] * other.i_[0];
170  S v11 = i_[1] * other.i_[1];
171  if(v00 <= v11)
172  {
173  S v01 = i_[0] * other.i_[1];
174  S v10 = i_[1] * other.i_[0];
175  if(v01 < v10) return Interval<S>(v01, v11);
176  return Interval<S>(v10, v11);
177  }
178 
179  S v01 = i_[0] * other.i_[1];
180  S v10 = i_[1] * other.i_[0];
181  if(v01 < v10) return Interval<S>(v01, v00);
182  return Interval<S>(v10, v00);
183 }
184 
185 //==============================================================================
186 template <typename S>
188 {
189  if(other.i_[0] >= 0)
190  {
191  if(i_[0] >= 0)
192  {
193  i_[0] *= other.i_[0];
194  i_[1] *= other.i_[1];
195  }
196  else if(i_[1] <= 0)
197  {
198  i_[0] *= other.i_[1];
199  i_[1] *= other.i_[0];
200  }
201  else
202  {
203  i_[0] *= other.i_[1];
204  i_[1] *= other.i_[1];
205  }
206  return *this;
207  }
208 
209  if(other.i_[1] <= 0)
210  {
211  if(i_[0] >= 0)
212  {
213  S tmp = i_[0];
214  i_[0] = i_[1] * other.i_[0];
215  i_[1] = tmp * other.i_[1];
216  }
217  else if(i_[1] <= 0)
218  {
219  S tmp = i_[0];
220  i_[0] = i_[1] * other.i_[1];
221  i_[1] = tmp * other.i_[0];
222  }
223  else
224  {
225  S tmp = i_[0];
226  i_[0] = i_[1] * other.i_[0];
227  i_[1] = tmp * other.i_[0];
228  }
229  return *this;
230  }
231 
232  if(i_[0] >= 0)
233  {
234  i_[0] = i_[1] * other.i_[0];
235  i_[1] *= other.i_[1];
236  return *this;
237  }
238 
239  if(i_[1] <= 0)
240  {
241  i_[1] = i_[0] * other.i_[0];
242  i_[0] *= other.i_[1];
243  return *this;
244  }
245 
246  S v00 = i_[0] * other.i_[0];
247  S v11 = i_[1] * other.i_[1];
248  if(v00 <= v11)
249  {
250  S v01 = i_[0] * other.i_[1];
251  S v10 = i_[1] * other.i_[0];
252  if(v01 < v10)
253  {
254  i_[0] = v01;
255  i_[1] = v11;
256  }
257  else
258  {
259  i_[0] = v10;
260  i_[1] = v11;
261  }
262  return *this;
263  }
264 
265  S v01 = i_[0] * other.i_[1];
266  S v10 = i_[1] * other.i_[0];
267  if(v01 < v10)
268  {
269  i_[0] = v01;
270  i_[1] = v00;
271  }
272  else
273  {
274  i_[0] = v10;
275  i_[1] = v00;
276  }
277 
278  return *this;
279 }
280 
281 //==============================================================================
282 template <typename S>
284 {
285  if(d >= 0) return Interval(i_[0] * d, i_[1] * d);
286  return Interval(i_[1] * d, i_[0] * d);
287 }
288 
289 //==============================================================================
290 template <typename S>
292 {
293  if(d >= 0)
294  {
295  i_[0] *= d;
296  i_[1] *= d;
297  }
298  else
299  {
300  S tmp = i_[0];
301  i_[0] = i_[1] * d;
302  i_[1] = tmp * d;
303  }
304 
305  return *this;
306 }
307 
308 //==============================================================================
309 template <typename S>
311 {
312  return *this * Interval(1.0 / other.i_[1], 1.0 / other.i_[0]);
313 }
314 
315 //==============================================================================
316 template <typename S>
318 {
319  *this *= Interval(1.0 / other.i_[1], 1.0 / other.i_[0]);
320  return *this;
321 }
322 
323 //==============================================================================
324 template <typename S>
325 bool Interval<S>::overlap(const Interval<S>& other) const
326 {
327  if(i_[1] < other.i_[0]) return false;
328  if(i_[0] > other.i_[1]) return false;
329  return true;
330 }
331 
332 //==============================================================================
333 template <typename S>
334 bool Interval<S>::intersect(const Interval<S>& other)
335 {
336  if(i_[1] < other.i_[0]) return false;
337  if(i_[0] > other.i_[1]) return false;
338  if(i_[1] > other.i_[1]) i_[1] = other.i_[1];
339  if(i_[0] < other.i_[0]) i_[0] = other.i_[0];
340  return true;
341 }
342 
343 //==============================================================================
344 template <typename S>
346 {
347  return Interval<S>(-i_[1], -i_[0]);
348 }
349 
350 //==============================================================================
351 template <typename S>
353 {
354  if(i_[0] >= 0) return i_[0];
355  if(i_[1] >= 0) return 0;
356  return -i_[1];
357 }
358 
359 //==============================================================================
360 template <typename S>
362 {
363  if(i_[0] + i_[1] >= 0) return i_[1];
364  return i_[0];
365 }
366 
367 //==============================================================================
368 template <typename S>
369 bool Interval<S>::contains(S v) const
370 {
371  if(v < i_[0]) return false;
372  if(v > i_[1]) return false;
373  return true;
374 }
375 
376 //==============================================================================
377 template <typename S>
379 {
380  if(v < i_[0]) i_[0] = v;
381  if(v > i_[1]) i_[1] = v;
382  return *this;
383 }
384 
385 //==============================================================================
386 template <typename S>
388 {
389  if(other.i_[0] < i_[0]) i_[0] = other.i_[0];
390  if(other.i_[1] > i_[1]) i_[1] = other.i_[1];
391  return *this;
392 }
393 
394 //==============================================================================
395 template <typename S>
396 void Interval<S>::print() const
397 {
398  std::cout << "[" << i_[0] << ", " << i_[1] << "]" << std::endl;
399 }
400 
401 //==============================================================================
402 template <typename S>
403 S Interval<S>::center() const
404 {
405  return 0.5 * (i_[0] + i_[1]);
406 }
407 
408 //==============================================================================
409 template <typename S>
410 S Interval<S>::diameter() const
411 {
412  return i_[1] -i_[0];
413 }
414 
415 //==============================================================================
416 template <typename S>
417 Interval<S> bound(const Interval<S>& i, S v)
418 {
419  Interval<S> res = i;
420  if(v < res.i_[0]) res.i_[0] = v;
421  if(v > res.i_[1]) res.i_[1] = v;
422  return res;
423 }
424 
425 //==============================================================================
426 template <typename S>
427 Interval<S> bound(const Interval<S>& i, const Interval<S>& other)
428 {
429  Interval<S> res = i;
430  if(other.i_[0] < res.i_[0]) res.i_[0] = other.i_[0];
431  if(other.i_[1] > res.i_[1]) res.i_[1] = other.i_[1];
432  return res;
433 }
434 
435 } // namespace fcl
436 
437 #endif
Interval & bound(S v)
Compute the minimum interval contains v and original interval.
Definition: interval-inl.h:378
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
S getAbsUpper() const
Return the farthest distance for points within the interval to zero.
Definition: interval-inl.h:361
Interval class for [a, b].
Definition: interval.h:50
bool overlap(const Interval &other) const
determine whether the intersection between intervals is empty
Definition: interval-inl.h:325
S getAbsLower() const
Return the nearest distance for points within the interval to zero.
Definition: interval-inl.h:352
void setValue(S a, S b)
construct interval [left, right]
Definition: interval-inl.h:82
Interval operator/(const Interval &other) const
other must not contain 0
Definition: interval-inl.h:310
S operator[](size_t i) const
access the interval endpoints: 0 for left, 1 for right end
Definition: interval-inl.h:96
bool operator==(const Interval &other) const
whether two intervals are the same
Definition: interval-inl.h:110
Interval operator+(const Interval &other) const
add two intervals
Definition: interval-inl.h:119