|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r76148 - sandbox/gtl/boost/polygon/detail
From: sydorchuk.andriy_at_[hidden]
Date: 2011-12-24 18:06:48
Author: asydorchuk
Date: 2011-12-24 18:06:47 EST (Sat, 24 Dec 2011)
New Revision: 76148
URL: http://svn.boost.org/trac/boost/changeset/76148
Log:
It was math proven that relative error for the robust cross product is atmost 1 EPS.
Text files modified:
sandbox/gtl/boost/polygon/detail/voronoi_calc_utils.hpp | 59 +++++++++++++++++++--------------------
sandbox/gtl/boost/polygon/detail/voronoi_structures.hpp | 8 ++--
2 files changed, 33 insertions(+), 34 deletions(-)
Modified: sandbox/gtl/boost/polygon/detail/voronoi_calc_utils.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/detail/voronoi_calc_utils.hpp (original)
+++ sandbox/gtl/boost/polygon/detail/voronoi_calc_utils.hpp 2011-12-24 18:06:47 EST (Sat, 24 Dec 2011)
@@ -19,7 +19,7 @@
template <typename T>
class voronoi_calc_utils;
-// Predicate utils. Operates with the coordinate types that could
+// Predicate utilities. Operates with the coordinate types that could
// be converted to the 32-bit signed integer without precision loss.
template <>
class voronoi_calc_utils<int32> {
@@ -55,7 +55,8 @@
}
// Compute robust cross_product: a1 * b2 - b1 * a2.
- // The result is correct with epsilon relative error equal to 1EPS.
+ // It was mathematically proven that the result is correct
+ // with epsilon relative error equal to 1EPS.
template <typename T>
static fpt_type robust_cross_product(T a1_, T b1_, T a2_, T b2_) {
uint64 a1, b1, a2, b2;
@@ -78,15 +79,13 @@
if (!expr_l_plus) {
if (expr_r_plus)
- return -static_cast<fpt_type>(expr_l) -
- static_cast<fpt_type>(expr_r);
+ return -static_cast<fpt_type>(expr_l - expr_r);
else return (expr_l > expr_r) ?
-static_cast<fpt_type>(expr_l - expr_r) :
static_cast<fpt_type>(expr_r - expr_l);
} else {
if (!expr_r_plus)
- return static_cast<fpt_type>(expr_l) +
- static_cast<fpt_type>(expr_r);
+ return static_cast<fpt_type>(expr_l + expr_r);
else
return (expr_l < expr_r) ?
-static_cast<fpt_type>(expr_r - expr_l) :
@@ -282,7 +281,7 @@
fpt_type dist1 = find_distance_to_point_arc(left_site, new_site.point0());
fpt_type dist2 = find_distance_to_segment_arc(right_site, new_site.point0());
- // The undefined ulp range is equal to 3EPS + 8EPS <= 11ULP.
+ // The undefined ulp range is equal to 3EPS + 7EPS <= 10ULP.
return reverse_order ^ (dist1 < dist2);
}
@@ -300,7 +299,7 @@
fpt_type dist1 = find_distance_to_segment_arc(left_site, new_site.point0());
fpt_type dist2 = find_distance_to_segment_arc(right_site, new_site.point0());
- // The undefined ulp range is equal to 8EPS + 8EPS <= 16ULP.
+ // The undefined ulp range is equal to 7EPS + 7EPS <= 14ULP.
return dist1 < dist2;
}
@@ -335,7 +334,7 @@
} else {
k = (k - b1) / (a1 * a1);
}
- // The relative error is atmost 8EPS.
+ // The relative error is atmost 7EPS.
return robust_cross_product(a1, b1, a3, b3) * k;
}
}
@@ -984,7 +983,7 @@
fpt_type dif_y2 = static_cast<fpt_type>(site2.y()) -
static_cast<fpt_type>(site3.y());
fpt_type orientation = robust_cross_product(dif_x1, dif_y1, dif_x2, dif_y2);
- robust_fpt_type inv_orientation(0.5 / orientation, 3.0);
+ robust_fpt_type inv_orientation(0.5 / orientation, 2.0);
fpt_type sum_x1 = static_cast<fpt_type>(site1.x()) +
static_cast<fpt_type>(site2.x());
fpt_type sum_x2 = static_cast<fpt_type>(site2.x()) +
@@ -1035,18 +1034,18 @@
static_cast<fpt_type>(site1.y());
fpt_type vec_y = static_cast<fpt_type>(site1.x()) -
static_cast<fpt_type>(site2.x());
- robust_fpt_type teta(robust_cross_product(line_a, line_b, -vec_y, vec_x), 2.0);
+ robust_fpt_type teta(robust_cross_product(line_a, line_b, -vec_y, vec_x), 1.0);
robust_fpt_type A(robust_cross_product(line_a, line_b,
static_cast<fpt_type>(site3.point1().y()) -
static_cast<fpt_type>(site1.y()),
static_cast<fpt_type>(site1.x()) -
- static_cast<fpt_type>(site3.point1().x())), 2.0);
+ static_cast<fpt_type>(site3.point1().x())), 1.0);
robust_fpt_type B(robust_cross_product(line_a, line_b,
static_cast<fpt_type>(site3.point1().y()) -
static_cast<fpt_type>(site2.y()),
static_cast<fpt_type>(site2.x()) -
- static_cast<fpt_type>(site3.point1().x())), 2.0);
- robust_fpt_type denom(robust_cross_product(vec_x, vec_y, line_a, line_b), 2.0);
+ static_cast<fpt_type>(site3.point1().x())), 1.0);
+ robust_fpt_type denom(robust_cross_product(vec_x, vec_y, line_a, line_b), 1.0);
robust_fpt_type inv_segm_len(1.0 / std::sqrt(sqr_distance(line_a, line_b)), 3.0);
robust_dif_type t;
if (get_orientation(denom) == COLLINEAR) {
@@ -1106,14 +1105,14 @@
fpt_type b2 = static_cast<fpt_type>(segm_end2.y()) -
static_cast<fpt_type>(segm_start2.y());
bool recompute_c_x, recompute_c_y, recompute_lower_x;
- robust_fpt_type orientation(robust_cross_product(b1, a1, b2, a2), 2.0);
+ robust_fpt_type orientation(robust_cross_product(b1, a1, b2, a2), 1.0);
if (get_orientation(orientation) == COLLINEAR) {
robust_fpt_type a(a1 * a1 + b1 * b1, 2.0);
robust_fpt_type c(robust_cross_product(b1, a1,
static_cast<fpt_type>(segm_start2.y()) -
static_cast<fpt_type>(segm_start1.y()),
static_cast<fpt_type>(segm_start2.x()) -
- static_cast<fpt_type>(segm_start1.x())), 2.0);
+ static_cast<fpt_type>(segm_start1.x())), 1.0);
robust_fpt_type det(robust_cross_product(a1, b1,
static_cast<fpt_type>(site1.x()) -
static_cast<fpt_type>(segm_start1.x()),
@@ -1123,7 +1122,7 @@
static_cast<fpt_type>(site1.y()) -
static_cast<fpt_type>(segm_start2.y()),
static_cast<fpt_type>(site1.x()) -
- static_cast<fpt_type>(segm_start2.x())), 5.0);
+ static_cast<fpt_type>(segm_start2.x())), 3.0);
robust_dif_type t;
t -= robust_fpt_type(a1, false) * robust_fpt_type(
(static_cast<fpt_type>(segm_start1.x()) +
@@ -1157,7 +1156,7 @@
} else {
robust_fpt_type sqr_sum1(std::sqrt(a1 * a1 + b1 * b1), 2.0);
robust_fpt_type sqr_sum2(std::sqrt(a2 * a2 + b2 * b2), 2.0);
- robust_fpt_type a(robust_cross_product(a1, b1, -b2, a2), 2.0);
+ robust_fpt_type a(robust_cross_product(a1, b1, -b2, a2), 1.0);
if (a >= 0) {
a += sqr_sum1 * sqr_sum2;
} else {
@@ -1167,19 +1166,19 @@
static_cast<fpt_type>(segm_end1.y()) -
static_cast<fpt_type>(site1.y()),
static_cast<fpt_type>(segm_end1.x()) -
- static_cast<fpt_type>(site1.x())), 2.0);
+ static_cast<fpt_type>(site1.x())), 1.0);
robust_fpt_type or2(robust_cross_product(a2, b2,
static_cast<fpt_type>(segm_end2.x()) -
static_cast<fpt_type>(site1.x()),
static_cast<fpt_type>(segm_end2.y()) -
- static_cast<fpt_type>(site1.y())), 2.0);
+ static_cast<fpt_type>(site1.y())), 1.0);
robust_fpt_type det = robust_fpt_type(2.0, false) * a * or1 * or2;
robust_fpt_type c1(robust_cross_product(b1, a1,
static_cast<fpt_type>(segm_end1.y()),
- static_cast<fpt_type>(segm_end1.x())), 2.0);
+ static_cast<fpt_type>(segm_end1.x())), 1.0);
robust_fpt_type c2(robust_cross_product(a2, b2,
static_cast<fpt_type>(segm_end2.x()),
- static_cast<fpt_type>(segm_end2.y())), 2.0);
+ static_cast<fpt_type>(segm_end2.y())), 1.0);
robust_fpt_type inv_orientation = robust_fpt_type(1.0, false) / orientation;
robust_dif_type t, b, ix, iy;
ix += robust_fpt_type(a2, false) * c1 * inv_orientation;
@@ -1193,10 +1192,10 @@
b += iy * (robust_fpt_type(b2, false) * sqr_sum1);
b -= sqr_sum1 * robust_fpt_type(robust_cross_product(a2, b2,
static_cast<fpt_type>(-site1.y()),
- static_cast<fpt_type>(site1.x())), 2.0);
+ static_cast<fpt_type>(site1.x())), 1.0);
b -= sqr_sum2 * robust_fpt_type(robust_cross_product(a1, b1,
static_cast<fpt_type>(-site1.y()),
- static_cast<fpt_type>(site1.x())), 2.0);
+ static_cast<fpt_type>(site1.x())), 1.0);
t -= b;
if (point_index == 2) {
t += det.sqrt();
@@ -1232,26 +1231,26 @@
static_cast<fpt_type>(site1.x0(true)), 0.0);
robust_fpt_type b1(static_cast<fpt_type>(site1.y1(true)) -
static_cast<fpt_type>(site1.y0(true)), 0.0);
- robust_fpt_type c1(robust_cross_product(site1.x0(true), site1.y0(true), site1.x1(true), site1.y1(true)), 2.0);
+ robust_fpt_type c1(robust_cross_product(site1.x0(true), site1.y0(true), site1.x1(true), site1.y1(true)), 1.0);
robust_fpt_type a2(static_cast<fpt_type>(site2.x1(true)) -
static_cast<fpt_type>(site2.x0(true)), 0.0);
robust_fpt_type b2(static_cast<fpt_type>(site2.y1(true)) -
static_cast<fpt_type>(site2.y0(true)), 0.0);
- robust_fpt_type c2(robust_cross_product(site2.x0(true), site2.y0(true), site2.x1(true), site2.y1(true)), 2.0);
+ robust_fpt_type c2(robust_cross_product(site2.x0(true), site2.y0(true), site2.x1(true), site2.y1(true)), 1.0);
robust_fpt_type a3(static_cast<fpt_type>(site3.x1(true)) -
static_cast<fpt_type>(site3.x0(true)), 0.0);
robust_fpt_type b3(static_cast<fpt_type>(site3.y1(true)) -
static_cast<fpt_type>(site3.y0(true)), 0.0);
- robust_fpt_type c3(robust_cross_product(site3.x0(true), site3.y0(true), site3.x1(true), site3.y1(true)), 2.0);
+ robust_fpt_type c3(robust_cross_product(site3.x0(true), site3.y0(true), site3.x1(true), site3.y1(true)), 1.0);
robust_fpt_type len1 = (a1 * a1 + b1 * b1).sqrt();
robust_fpt_type len2 = (a2 * a2 + b2 * b2).sqrt();
robust_fpt_type len3 = (a3 * a3 + b3 * b3).sqrt();
- robust_fpt_type cross_12(robust_cross_product(a1.fpv(), b1.fpv(), a2.fpv(), b2.fpv()), 2.0);
- robust_fpt_type cross_23(robust_cross_product(a2.fpv(), b2.fpv(), a3.fpv(), b3.fpv()), 2.0);
- robust_fpt_type cross_31(robust_cross_product(a3.fpv(), b3.fpv(), a1.fpv(), b1.fpv()), 2.0);
+ robust_fpt_type cross_12(robust_cross_product(a1.fpv(), b1.fpv(), a2.fpv(), b2.fpv()), 1.0);
+ robust_fpt_type cross_23(robust_cross_product(a2.fpv(), b2.fpv(), a3.fpv(), b3.fpv()), 1.0);
+ robust_fpt_type cross_31(robust_cross_product(a3.fpv(), b3.fpv(), a1.fpv(), b1.fpv()), 1.0);
robust_dif_type denom, c_x, c_y, r;
// denom = cross_12 * len3 + cross_23 * len1 + cross_31 * len2.
Modified: sandbox/gtl/boost/polygon/detail/voronoi_structures.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/detail/voronoi_structures.hpp (original)
+++ sandbox/gtl/boost/polygon/detail/voronoi_structures.hpp 2011-12-24 18:06:47 EST (Sat, 24 Dec 2011)
@@ -214,9 +214,9 @@
// Circle event is made by the two consequtive nodes in the beach line data
// structure. In case another node was inserted during algorithm execution
// between the given two nodes circle event becomes inactive.
- // Variables: center_x_ - numerator of the center's x-coordinate.
- // center_y_ - numerator of the center's y-coordinate.
- // lower_x_ - numerator of the bottom point's x-coordinate.
+ // Variables: center_x_ - center x-coordinate.
+ // center_y_ - center y-coordinate.
+ // lower_x_ - leftmost x-coordinate.
// is_active_ - states whether circle event is still active.
// NOTE: lower_y coordinate is always equal to center_y.
template <typename T>
@@ -339,7 +339,7 @@
// the site and from the sweepline. If the site is a point then arc is
// a parabola, otherwise it's a line segment. A segment site event will
// produce different bisectors based on its direction.
- // In the general case two sites will create two opposite bisectors. That's
+ // In general case two sites will create two opposite bisectors. That's
// why the order of the sites is important to define the unique bisector.
// The one site is considered to be newer than the other one if it was
// processed by the algorithm later (has greater index).
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk