geotests.cpp
1 #include "geotests.hpp"
2 double const epsilon = 1.1102230246251565e-016;
3 
4 double orient2dAdapt(const TripleConstRef<Vector2D>& points, double detsum)
5 {
6  boost::array<double,2> A1,A2;
7  vector<double> B1, B2;
8  vector<double> C;
9  double acx, acy, bcx, bcy, acxtail, acytail, bcxtail, bcytail;
10  double detLeft, detRight, detLeftErr, detRightErr, det, err;
11  double s1, t1, s0, t0;
12  // Error ranges for different accuracies.
13  double resultErrBound = (3.0 + 8.0 * epsilon) * epsilon;
14  double errBoundB = (2.0 + 12.0 * epsilon) * epsilon;
15  double errBoundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
16 
17  twoDiff(points.first.x, points.third.x, acx, acxtail);
18  twoDiff(points.second.x, points.third.x, bcx, bcxtail);
19  twoDiff(points.first.y, points.third.y, acy, acytail);
20  twoDiff(points.second.y, points.third.y, bcy, bcytail);
21 
22  twoProduct(acx, bcy, detLeft, detLeftErr);
23  twoProduct(acy, bcx, detRight, detRightErr);
24  A1[0] = detLeft;
25  A1[1] = detLeftErr;
26  A2[0] = detRight;
27  A2[1] = detRightErr;
28  B1 = twoTwoDiff(A1, A2);
29  det = estimate(B1);
30  err = errBoundB * detsum;
31  // Several cases in which precision is enough.
32  if ((det >= err) || (-det >= err))
33  {
34  return det;
35  }
36  if ((acxtail == 0.0) && (acytail == 0.0) && (bcxtail == 0.0) && (bcytail == 0.0))
37  {
38  return det;
39  }
40  err = errBoundC * detsum + resultErrBound * fabs(det);
41  det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);
42  if ((det >= err) || (-det >= err))
43  {
44  return det;
45  }
46 
47  twoProduct(acxtail, bcy, s1, s0);
48  twoProduct(acytail, bcx, t1, t0);
49  A1[0] = s1;
50  A1[1] = s0;
51  A2[0] = t1;
52  A2[1] = t0;
53  B2 = twoTwoDiff(A1, A2);
54  C = fastExpansionSumZeroElim(B1, B2);
55 
56  twoProduct(acx, bcytail, s1, s0);
57  twoProduct(acy, bcxtail, t1, t0);
58  A1[0] = s1;
59  A1[1] = s0;
60  A2[0] = t1;
61  A2[1] = t0;
62  B1 = twoTwoDiff(A1, A2);
63  C = fastExpansionSumZeroElim(C, B1);
64 
65  twoProduct(acxtail, bcytail, s1, s0);
66  twoProduct(acytail, bcxtail, t1, t0);
67  A1[0] = s1;
68  A1[1] = s0;
69  A2[0] = t1;
70  A2[1] = t0;
71  B1 = twoTwoDiff(A1, A2);
72  C = fastExpansionSumZeroElim(C, B1);
73  return(C.back());
74 }
75 
76 double orient2d(const TripleConstRef<Vector2D>& points)
77 {
78  double detleft, detright, det;
79  double detsum, errbound;
80  double errBoundA = (3.0 + 16.0 * epsilon) * epsilon; // Acceptable error range for this calculation precision.
81 
82  // Calculating a 2x2 determinant.
83  detleft = (points.first.x - points.third.x) * (points.second.y - points.third.y);
84  detright = (points.first.y - points.third.y) * (points.second.x - points.third.x);
85  det = detleft - detright;
86 
87  if (detleft > 0.0)
88  {
89  if (detright <= 0.0) // Determinant sign is certain.
90  {
91  return det;
92  }
93  else
94  {
95  detsum = detleft + detright;
96  }
97  }
98  else
99  {
100  if (detleft < 0.0)
101  {
102  if (detright >= 0.0) //Determinant sign is certain.
103  {
104  return det;
105  }
106  else
107  {
108  detsum = -detleft - detright;
109  }
110  }
111  else
112  {
113  return det;
114  }
115  }
116  errbound = errBoundA * detsum;
117  if ((det >= errbound) || (-det >= errbound)) // Calculation in in acceptable error range.
118  {
119  return det;
120  }
121  return orient2dAdapt(points, detsum);
122 }
123 
124 double incircleadapt(const Vector2D& point_1,
125  const Vector2D& point_2,
126  const Vector2D& point_3,
127  const Vector2D& point_4,
128  double permanent)
129 {
130  double adx, bdx, cdx, ady, bdy, cdy;
131  double adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
132  double bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
133  double bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
134  double res1, res2, err1, err2;
135  double det, errbound;
136  // Several error ranges for different calculation precisions.
137  double errBoundB = (4.0 + 48.0 * epsilon) * epsilon;
138  double errBoundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
139  double resultErrBound = (3.0 + 8.0 * epsilon) * epsilon;
140 
141  boost::array<double,2> A1, A2;
142  vector<double> B1, B2, B3, C1, C2, C3, D1, D2, D3, E1, E2, E3, F;
143  vector<double> tmp1, tmp2;
144 
145  twoDiff(point_1.x, point_4.x, adx, adxtail);
146  twoDiff(point_2.x, point_4.x, bdx, bdxtail);
147  twoDiff(point_3.x, point_4.x, cdx, cdxtail);
148  twoDiff(point_1.y, point_4.y, ady, adytail);
149  twoDiff(point_2.y, point_4.y, bdy, bdytail);
150  twoDiff(point_3.y, point_4.y, cdy, cdytail);
151 
152  twoProduct(bdx, cdy, bdxcdy1, bdxcdy0);
153  twoProduct(cdx, bdy, cdxbdy1, cdxbdy0);
154  A1[0] = bdxcdy1;
155  A1[1] = bdxcdy0;
156  A2[0] = cdxbdy1;
157  A2[1] = cdxbdy0;
158  B1 = twoTwoDiff(A1, A2);
159  scaleExpansionZeroElim(B1,adx,C1);
160  scaleExpansionZeroElim(C1,adx,tmp1);
161  scaleExpansionZeroElim(B1, ady,C1);
162  scaleExpansionZeroElim(C1,ady,tmp2);
163  C1 = fastExpansionSumZeroElim(tmp1,tmp2);
164 
165  twoProduct(cdx, ady, cdxady1, cdxady0);
166  twoProduct(adx, cdy, adxcdy1, adxcdy0);
167  A1[0] = cdxady1;
168  A1[1] = cdxady0;
169  A2[0] = adxcdy1;
170  A2[1] = adxcdy0;
171  B2 = twoTwoDiff(A1, A2);
172  scaleExpansionZeroElim(B2,bdx,tmp2);
173  scaleExpansionZeroElim(tmp2,bdx,tmp1);
174  scaleExpansionZeroElim(B2,bdy,C2);
175  scaleExpansionZeroElim(C2,bdy,tmp2);
176  C2 = fastExpansionSumZeroElim(tmp1,tmp2);
177 
178  twoProduct(adx, bdy, adxbdy1, adxbdy0);
179  twoProduct(bdx, ady, bdxady1, bdxady0);
180  A1[0] = adxbdy1;
181  A1[1] = adxbdy0;
182  A2[0] = bdxady1;
183  A2[1] = bdxady0;
184  B3 = twoTwoDiff(A1, A2);
185  scaleExpansionZeroElim(B3,cdx,tmp2);
186  scaleExpansionZeroElim(tmp2,cdx,tmp1);
187  scaleExpansionZeroElim(B3,cdy,C3);
188  scaleExpansionZeroElim(C3,cdy,tmp2);
189  C3 = fastExpansionSumZeroElim(tmp1, tmp2);
190 
191  F = fastExpansionSumZeroElim(C1, C2);
192  F = fastExpansionSumZeroElim(F, C3);
193  det = estimate(F); //Estimating determinant.
194  // Several cases in which precision is enough.
195  errbound = errBoundB * permanent;
196  if ((det >= errbound) || (-det >= errbound))
197  {
198  return det;
199  }
200  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
201  && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0))
202  {
203  return det;
204  }
205  errbound = errBoundC * permanent + resultErrBound * fabs(det);
206  det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
207  - (bdy * cdxtail + cdx * bdytail)) + 2.0 * (adx * adxtail + ady * adytail)
208  * (bdx * cdy - bdy * cdx)) + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
209  - (cdy * adxtail + adx * cdytail)) + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
210  + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail))
211  + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
212  if ((det >= errbound) || (-det >= errbound))
213  {
214  return det;
215  }
216 
217  // A more precise calculation.
218  if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) || (cdytail != 0.0))
219  {
220  double adxadx1;
221  double adyady1;
222  double adxadx0;
223  double adyady0;
224  square(adx, adxadx1, adxadx0);
225  square(ady, adyady1, adyady0);
226  A1[0] = adxadx1;
227  A1[1] = adxadx0;
228  A2[0] = adyady1;
229  A2[1] = adyady0;
230  C1 = twoTwoSum(A1, A2);
231  }
232  if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) || (adytail != 0.0))
233  {
234  double bdxbdx1;
235  double bdybdy1;
236  double bdxbdx0;
237  double bdybdy0;
238  square(bdx, bdxbdx1, bdxbdx0);
239  square(bdy, bdybdy1, bdybdy0);
240  A1[0] = bdxbdx1;
241  A1[1] = bdxbdx0;
242  A2[0] = bdybdy1;
243  A2[1] = bdybdy0;
244  C2 = twoTwoSum(A1, A2);
245  }
246  if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) || (bdytail != 0.0))
247  {
248  double cdxcdx1;
249  double cdycdy1;
250  double cdxcdx0;
251  double cdycdy0;
252  square(cdx, cdxcdx1, cdxcdx0);
253  square(cdy, cdycdy1, cdycdy0);
254  A1[0] = cdxcdx1;
255  A1[1] = cdxcdx0;
256  A2[0] = cdycdy1;
257  A2[1] = cdycdy0;
258  C3 = twoTwoSum(A1, A2);
259  }
260  if (adxtail != 0.0)
261  {
262  vector<double> helper;
263  scaleExpansionZeroElim(B1,adxtail,D1);
264  scaleExpansionZeroElim(D1,2.0*adx,tmp1);
265  scaleExpansionZeroElim(C3, adxtail,helper);
266  scaleExpansionZeroElim(helper,bdy,tmp2);
267  tmp2 = fastExpansionSumZeroElim(tmp1,tmp2);
268  scaleExpansionZeroElim(C2, adxtail,helper);
269  scaleExpansionZeroElim(helper,-cdy,tmp1);
270  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
271  F = fastExpansionSumZeroElim(F, tmp1);
272  }
273  if (adytail != 0.0)
274  {
275  scaleExpansionZeroElim(B1, adytail,D2);
276  scaleExpansionZeroElim(D2,2.0*ady,tmp1);
277  vector<double> helper;
278  scaleExpansionZeroElim(C2,adytail,tmp2);
279  scaleExpansionZeroElim(tmp2,cdx,helper);
280  tmp2 = fastExpansionSumZeroElim(tmp1,helper);
281  scaleExpansionZeroElim(C3,adytail,tmp1);
282  scaleExpansionZeroElim(tmp1,-bdx,helper);
283  tmp1 = fastExpansionSumZeroElim(helper,tmp2);
284  F = fastExpansionSumZeroElim(F,tmp1);
285  }
286  if (bdxtail != 0.0)
287  {
288  vector<double> helper;
289  scaleExpansionZeroElim(B2, bdxtail,D3);
290  scaleExpansionZeroElim(D3, 2.0 * bdx,tmp1);
291  scaleExpansionZeroElim(C1, bdxtail,tmp2);
292  scaleExpansionZeroElim(tmp2, cdy,helper);
293  tmp2 = fastExpansionSumZeroElim(tmp1,helper);
294  scaleExpansionZeroElim(C3, bdxtail,tmp1);
295  scaleExpansionZeroElim(tmp1, -ady,helper);
296  tmp1 = fastExpansionSumZeroElim(helper, tmp2);
297  F = fastExpansionSumZeroElim(F, tmp1);
298  }
299  if (bdytail != 0.0)
300  {
301  vector<double> helper;
302  scaleExpansionZeroElim(B2, bdytail,B1);
303  scaleExpansionZeroElim(B1, 2.0 * bdy,tmp1);
304  scaleExpansionZeroElim(C3, bdytail,helper);
305  scaleExpansionZeroElim(helper, adx,tmp2);
306  tmp2 = fastExpansionSumZeroElim(tmp1, tmp2);
307  scaleExpansionZeroElim(C1, bdytail,helper);
308  scaleExpansionZeroElim(helper,-cdx,tmp1);
309  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
310  F = fastExpansionSumZeroElim(F, tmp1);
311  }
312  if (cdxtail != 0.0)
313  {
314  vector<double> helper;
315  scaleExpansionZeroElim(B3, cdxtail,B2);
316  scaleExpansionZeroElim(B2, 2.0 * cdx,tmp1);
317  scaleExpansionZeroElim(C2, cdxtail,helper);
318  scaleExpansionZeroElim(helper, ady,tmp2);
319  tmp2 = fastExpansionSumZeroElim(tmp1, tmp2);
320  scaleExpansionZeroElim(C1, cdxtail,helper);
321  scaleExpansionZeroElim(helper, -bdy,tmp1);
322  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
323  F = fastExpansionSumZeroElim(F, tmp1);
324  }
325  if (cdytail != 0.0)
326  {
327  vector<double> helper;
328  scaleExpansionZeroElim(B3,cdytail,helper);
329  B3=helper;
330  scaleExpansionZeroElim(B3, 2.0 * cdy,tmp1);
331  scaleExpansionZeroElim(C1, cdytail,helper);
332  scaleExpansionZeroElim(helper,bdx,tmp2);
333  tmp2 = fastExpansionSumZeroElim(tmp1, tmp2);
334  scaleExpansionZeroElim(C2, cdytail,helper);
335  scaleExpansionZeroElim(helper, -adx,tmp1);
336  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
337  F = fastExpansionSumZeroElim(F, tmp1);
338  }
339  if ((adxtail != 0.0) || (adytail != 0.0))
340  {
341  if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) || (cdytail != 0.0))
342  {
343  twoProduct(bdxtail, cdy, res1, err1);
344  twoProduct(bdx, cdytail, res2, err2);
345  A1[0] = res1;
346  A1[1] = err1;
347  A2[0] = res2;
348  A2[1] = err2;
349  tmp1 = twoTwoSum(A1, A2);
350  twoProduct(cdxtail, -bdy, res1, err1);
351  twoProduct(cdx, -bdytail, res2, err2);
352  A1[0] = res1;
353  A1[1] = err1;
354  A2[0] = res2;
355  A2[1] = err2;
356  tmp2 = twoTwoSum(A1, A2);
357  E1 = fastExpansionSumZeroElim(tmp1, tmp2);
358  twoProduct(bdxtail, cdytail, res1, err1);
359  twoProduct(cdxtail, bdytail, res2, err2);
360  A1[0] = res1;
361  A1[1] = err1;
362  A2[0] = res2;
363  A2[1] = err2;
364  E2 = twoTwoDiff(A1, A2);
365  }
366  else
367  {
368  E1.push_back(0.0);
369  E2.push_back(0.0);
370  }
371  if (adxtail != 0.0)
372  {
373  scaleExpansionZeroElim(D1, adxtail,tmp1);
374  scaleExpansionZeroElim(E1, adxtail,E3);
375  scaleExpansionZeroElim(E3, 2.0 * adx,tmp2);
376  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
377  F = fastExpansionSumZeroElim(F, tmp1);
378  if (bdytail != 0.0)
379  {
380  scaleExpansionZeroElim(C3, adxtail,tmp1);
381  scaleExpansionZeroElim(tmp1, bdytail,tmp2);
382  F = fastExpansionSumZeroElim(F, tmp2);
383  }
384  if (cdytail != 0.0)
385  {
386  scaleExpansionZeroElim(C2, -adxtail,tmp1);
387  scaleExpansionZeroElim(tmp1, cdytail,tmp2);
388  F = fastExpansionSumZeroElim(F, tmp2);
389  }
390  scaleExpansionZeroElim(E2, adxtail,D1);
391  scaleExpansionZeroElim(D1, 2.0 * adx,tmp1);
392  scaleExpansionZeroElim(D1, adxtail,tmp2);
393  tmp2 = fastExpansionSumZeroElim(tmp1, tmp2);
394  scaleExpansionZeroElim(E3, adxtail,tmp1);
395  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
396  F = fastExpansionSumZeroElim(F, tmp1);
397  }
398  if (adytail != 0.0)
399  {
400  scaleExpansionZeroElim(D2, adytail,tmp1);
401  scaleExpansionZeroElim(E1, adytail,D2);
402  scaleExpansionZeroElim(D2, 2.0 * ady,tmp2);
403  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
404  F = fastExpansionSumZeroElim(F, tmp1);
405  scaleExpansionZeroElim(D2, adytail,tmp1);
406  scaleExpansionZeroElim(E2, adytail,D1);
407  scaleExpansionZeroElim(D1, 2.0 * ady,E1);
408  scaleExpansionZeroElim(D1, adytail,E3);
409  tmp2 = fastExpansionSumZeroElim(E1, E3);
410  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
411  F = fastExpansionSumZeroElim(F, tmp1);
412  }
413  }
414  if ((bdxtail != 0.0) || (bdytail != 0.0))
415  {
416  if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) || (adytail != 0.0))
417  {
418  twoProduct(cdxtail, ady, res1, err1);
419  twoProduct(cdx, adytail, res2, err2);
420  A1[0] = res1;
421  A1[1] = err1;
422  A2[0] = res2;
423  A2[1] = err2;
424  tmp1 = twoTwoSum(A1, A2);
425  twoProduct(adxtail, -cdy, res1, err1);
426  twoProduct(adx, -cdytail, res2, err2);
427  A1[0] = res1;
428  A1[1] = err1;
429  A2[0] = res2;
430  A2[1] = err2;
431  tmp2 = twoTwoSum(A1, A2);
432  E1 = fastExpansionSumZeroElim(tmp1, tmp2);
433  twoProduct(cdxtail, adytail, res1, err1);
434  twoProduct(adxtail, cdytail, res2, err2);
435  A1[0] = res1;
436  A1[1] = err1;
437  A2[0] = res2;
438  A2[1] = err2;
439  E2 = twoTwoDiff(A1, A2);
440  }
441  else
442  {
443  E1.push_back(0.0);
444  E2.push_back(0.0);
445  }
446  if (bdxtail != 0.0)
447  {
448  scaleExpansionZeroElim(D3, bdxtail,tmp1);
449  scaleExpansionZeroElim(E1, bdxtail,E3);
450  scaleExpansionZeroElim(E3, 2.0 * bdx,tmp2);
451  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
452  F = fastExpansionSumZeroElim(F, tmp1);
453  if (cdytail != 0.0)
454  {
455  scaleExpansionZeroElim(C1, bdxtail,tmp1);
456  scaleExpansionZeroElim(tmp1, cdytail,tmp2);
457  F = fastExpansionSumZeroElim(F, tmp2);
458  }
459  if (adytail != 0.0)
460  {
461  scaleExpansionZeroElim(C3, -bdxtail,tmp1);
462  scaleExpansionZeroElim(tmp1, adytail,tmp2);
463  F = fastExpansionSumZeroElim(F, tmp2);
464  }
465  scaleExpansionZeroElim(E3, bdxtail,tmp1);
466  scaleExpansionZeroElim(E2, bdxtail,D1);
467  scaleExpansionZeroElim(D1, 2.0 * bdx,D2);
468  scaleExpansionZeroElim(D1, bdxtail,D3);
469  tmp2 = fastExpansionSumZeroElim(D2, D3);
470  tmp2 = fastExpansionSumZeroElim(tmp1, tmp2);
471  F = fastExpansionSumZeroElim(F, tmp2);
472  }
473  if (bdytail != 0.0)
474  {
475  scaleExpansionZeroElim(B1, bdytail,tmp1);
476  scaleExpansionZeroElim(E1, bdytail,D1);
477  scaleExpansionZeroElim(D1, 2.0 * bdy,tmp2);
478  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
479  F = fastExpansionSumZeroElim(F, tmp1);
480  scaleExpansionZeroElim(D1, bdytail,tmp1);
481  scaleExpansionZeroElim(E2, bdytail,D1);
482  scaleExpansionZeroElim(D1, 2.0 * bdy,D2);
483  scaleExpansionZeroElim(D1, bdytail,D3);
484  tmp2 = fastExpansionSumZeroElim(D2, D3);
485  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
486  F = fastExpansionSumZeroElim(F, tmp1);
487  }
488  }
489  if ((cdxtail != 0.0) || (cdytail != 0.0))
490  {
491  if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) || (bdytail != 0.0))
492  {
493  twoProduct(adxtail, bdy, res1, err1);
494  twoProduct(adx, bdytail, res2, err2);
495  A1[0] = res1;
496  A1[1] = err1;
497  A2[0] = res2;
498  A2[1] = err2;
499  tmp1 = twoTwoSum(A1, A2);
500  twoProduct(bdxtail, -ady, res1, err1);
501  twoProduct(bdx, -adytail, res2, err2);
502  A1[0] = res1;
503  A1[1] = err1;
504  A2[0] = res2;
505  A2[1] = err2;
506  tmp2 = twoTwoSum(A1, A2);
507  E1 = fastExpansionSumZeroElim(tmp1, tmp2);
508  twoProduct(adxtail, bdytail, res1, err1);
509  twoProduct(bdxtail, adytail, res2, err2);
510  A1[0] = res1;
511  A1[1] = err1;
512  A2[0] = res2;
513  A2[1] = err2;
514  E2 = twoTwoDiff(A1, A2);
515  }
516  else
517  {
518  E1.push_back(0.0);
519  E2.push_back(0.0);
520  }
521  if (cdxtail != 0.0)
522  {
523  scaleExpansionZeroElim(B2, cdxtail,tmp1);
524  scaleExpansionZeroElim(E1, cdxtail,E3);
525  scaleExpansionZeroElim(E3, 2.0 * cdx,tmp2);
526  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
527  F = fastExpansionSumZeroElim(F, tmp1);
528  if (adytail != 0.0)
529  {
530  scaleExpansionZeroElim(C2, cdxtail,tmp1);
531  scaleExpansionZeroElim(tmp1, adytail,tmp2);
532  F = fastExpansionSumZeroElim(F, tmp2);
533  }
534  if (bdytail != 0.0)
535  {
536  scaleExpansionZeroElim(C1, -cdxtail,tmp1);
537  scaleExpansionZeroElim(tmp1, bdytail,tmp2);
538  F = fastExpansionSumZeroElim(F, tmp2);
539  }
540  scaleExpansionZeroElim(E3, cdxtail,tmp1);
541  scaleExpansionZeroElim(E2, cdxtail,D1);
542  scaleExpansionZeroElim(D1, 2.0 * cdx,D2);
543  scaleExpansionZeroElim(D1, cdxtail,D3);
544  C1 = fastExpansionSumZeroElim(D2, D3);
545  C2 = fastExpansionSumZeroElim(tmp1, C1);
546  F = fastExpansionSumZeroElim(F, C2);
547  }
548  if (cdytail != 0.0)
549  {
550  scaleExpansionZeroElim(B3, cdytail,tmp1);
551  scaleExpansionZeroElim(E1, cdytail,B1);
552  scaleExpansionZeroElim(B1, 2.0 * cdy,tmp2);
553  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
554  F = fastExpansionSumZeroElim(F, tmp1);
555  scaleExpansionZeroElim(B1, cdytail,tmp1);
556  scaleExpansionZeroElim(E2, cdytail,B1);
557  scaleExpansionZeroElim(B1, 2.0 * cdy,B2);
558  scaleExpansionZeroElim(B1, cdytail,B3);
559  tmp2 = fastExpansionSumZeroElim(B2, B3);
560  tmp1 = fastExpansionSumZeroElim(tmp1, tmp2);
561  F = fastExpansionSumZeroElim(F, tmp1);
562  }
563  }
564  return F.back();
565 }
566 
567 double incircle(const Vector2D& point_1,
568  const Vector2D& point_2,
569  const Vector2D& point_3,
570  const Vector2D& point_4)
571 {
572  const double errBoundA = (10.0 + 96.0 * epsilon) * epsilon; // Acceptable error range for this calculation precision.
573 
574  const double adx = point_1.x - point_4.x;
575  const double bdx = point_2.x - point_4.x;
576  const double cdx = point_3.x - point_4.x;
577  const double ady = point_1.y - point_4.y;
578  const double bdy = point_2.y - point_4.y;
579  const double cdy = point_3.y - point_4.y;
580 
581  const double alift = adx * adx + ady * ady;
582  const double blift = bdx * bdx + bdy * bdy;
583  const double clift = cdx * cdx + cdy * cdy;
584  const double bdxcdy = bdx * cdy;
585  const double cdxbdy = cdx * bdy;
586  const double cdxady = cdx * ady;
587  const double adxcdy = adx * cdy;
588  const double adxbdy = adx * bdy;
589  const double bdxady = bdx * ady;
590 
591  //Calculating regular 3x3 matrix determinant.
592  const double det = alift * (bdxcdy - cdxbdy) + blift * (cdxady - adxcdy) + clift * (adxbdy - bdxady);
593 
594  const double permanent = (fabs(bdxcdy) + fabs(cdxbdy)) * alift
595  + (fabs(cdxady) + fabs(adxcdy)) * blift
596  + (fabs(adxbdy) + fabs(bdxady)) * clift;
597  const double errbound = errBoundA * permanent;
598  if ((det > errbound) || (-det > errbound))
599  { //Determinant is out of error bounds (accurate enough).
600  return det;
601  }
602  return incircleadapt(point_1,
603  point_2,
604  point_3,
605  point_4,
606  permanent); //calling the adaptive function.
607 }
const T & third
Reference to third item.
Definition: triplet.hpp:23
void twoDiff(double a, double b, double &res, double &err)
Difference between two numbers.
Definition: exactmath.cpp:60
Various checks for geometric data.
double incircle(const Vector2D &point_1, const Vector2D &point_2, const Vector2D &point_3, const Vector2D &point_4)
Checks whether the 4th point is inside, outside or on the counterclockwise circle created by the firs...
Definition: geotests.cpp:567
const T & second
Reference to second item.
Definition: triplet.hpp:20
double incircleadapt(const Vector2D &point_1, const Vector2D &point_2, const Vector2D &point_3, const Vector2D &point_4, double permanent)
Checks whether the 4th point is inside, outside or on the counterclockwise circle created by the firs...
Definition: geotests.cpp:124
double estimate(vector< double > const &e)
Calculate a double precision approximation of the expansion.
Definition: exactmath.cpp:488
vector< double > twoTwoSum(boost::array< double, 2 > const &a, boost::array< double, 2 > const &b)
Calculates the sum of two two-expansions.
Definition: exactmath.cpp:128
void twoProduct(double a, double b, double &res, double &err)
Product of two number.
Definition: exactmath.cpp:87
double y
Component in the y direction.
Definition: geometry.hpp:48
A collection of three identical references.
Definition: triplet.hpp:12
vector< double > twoTwoDiff(boost::array< double, 2 > const &a, boost::array< double, 2 > const &b)
Calculates the difference between two two-expansions.
Definition: exactmath.cpp:139
double orient2dAdapt(const TripleConstRef< Vector2D > &points, double detsum)
Checks whether 3 given points are on a counterclockwise circle, clockwise circle or colinear using ad...
Definition: geotests.cpp:4
const T & first
Reference to first item.
Definition: triplet.hpp:17
vector< double > fastExpansionSumZeroElim(vector< double > const &e, vector< double > const &f)
Adds up two expansions.
Definition: exactmath.cpp:213
void scaleExpansionZeroElim(vector< double > const &e, double b, vector< double > &result)
Multiplies a scalar by an expansion.
Definition: exactmath.cpp:416
2D Mathematical vector
Definition: geometry.hpp:15
double orient2d(const TripleConstRef< Vector2D > &points)
Checks whether 3 given points are on a counterclockwise circle, clockwise circle or colinear...
Definition: geotests.cpp:76
double x
Component in the x direction.
Definition: geometry.hpp:45
void square(double num, double &res, double &err)
Calculates the square of a number.
Definition: exactmath.cpp:104