1 #ifndef AREA_OCCUPANCY_ESTIMATOR_H 2 #define AREA_OCCUPANCY_ESTIMATOR_H 21 double low_qual = 0.01,
double unknown_qual = 0.5)
28 bool is_occ)
override {
46 if (intrs.size() == 1) {
51 switch (raw_intersections.size()) {
52 case 0: assert(
false &&
"BUG: no inters must be detected earlier");
56 intrs = raw_intersections;
80 assert(
false &&
"BUG: non-axis aligned segment is on rectange edge");
90 bool beg_is_inside, end_is_inside;
93 if (beg_is_inside ^ end_is_inside) {
104 switch (intersections.size()) {
109 assert(
false &&
"BUG: unable to classify segment");
120 if (beg_edge && end_edge) {
121 return std::make_tuple(
false,
false);
127 if (!beg_edge && !end_edge) {
128 return std::make_tuple(beg_contains, end_contains);
135 return beg_edge ? std::make_tuple(
false, end_contains) :
136 std::make_tuple(beg_contains, !beg_contains);
154 std::copy_if(inters.begin(), inters.end(),
155 std::back_inserter(filtered_inters),
159 return filtered_inters;
164 const std::vector<Intersection> &inters) {
165 if (inters.size() == 0) {
167 return bnds.
area() / 2;
170 assert(inters.size() == 2);
171 double corner_x = 0, corner_y = 0, area = 0;
172 double chunk_is_triangle = inters[0].is_horiz() ^ inters[1].is_horiz();
173 if (chunk_is_triangle) {
176 for (
auto &inter : inters) {
177 switch (inter.location) {
182 default: assert(
false &&
"Unexpected location type");
187 for (
auto &inter : inters) {
188 if (inter.is_horiz()) {
189 area *= std::abs(inter.x - corner_x);
191 area *= std::abs(inter.y - corner_y);
197 corner_x = bnds.
left(), corner_y = bnds.
bot();
199 for (
auto &inter : inters) {
200 if (inter.is_horiz()) {
201 base_sum += std::abs(inter.x - corner_x);
203 base_sum += std::abs(inter.y - corner_y);
207 area = 0.5 * (bnds.
top() - bnds.
bot()) * base_sum;
209 assert(0 <= area && area <= bnds.
area() &&
"BUG: AOE area estimation");
212 beam.
beg(), {corner_x, corner_y})) {
213 area = bnds.
area() - area;
220 double dx = line_p2.
x - line_p1.
x, dy = line_p2.
y - line_p1.
y;
221 return 0 < (dy*p1.
y - dx*p1.
x + dy*p1.
x - dx*p1.
y) *
222 (dy*p2.
y - dx*p2.
x + dy*p2.
x - dx*p2.
y);
227 double area_rate = chunk_area / total_area;
234 if (0.5 < area_rate) {
235 area_rate = 1 - area_rate;
CONSTEXPR bool are_equal(const T &a, const T &b, const T &eps)
SegmentPositionType classify_segment(const Segment2D &s, const Rectangle &cell) const
Segment2D find_containing_edge(const Point2D &p) const
bool contains_intersection(const Point2D &p) const
bool are_on_the_same_side(const Point2D &line_p1, const Point2D &line_p2, const Point2D &p1, const Point2D &p2)
Intersections find_intersections(const Segment2D &s) const
static Occupancy invalid()
const Occupancy & base_empty() const
const Point2D & end() const
std::vector< Intersection > Intersections
double compute_chunk_area(const Segment2D &beam, const Rectangle &bnds, bool is_occ, const std::vector< Intersection > &inters)
Occupancy estimate_occupancy(const Segment2D &beam, const Rectangle &cell, bool is_occ) override
double estimation_quality
std::tuple< bool, bool > modified_is_inside(const Segment2D &s, const Rectangle &cell) const
Segment2D ensure_segment_not_on_edge(const Segment2D &s, const Rectangle &cell) const
bool contains(const Point2D &p) const
Intersections find_intersections(const Segment2D &beam, const Rectangle &bnds, bool is_occ)
const Point2D & beg() const
Occupancy estimate_occupancy(double chunk_area, double total_area, bool is_occ)
const Occupancy & base_occupied() const
AreaOccupancyEstimator(const Occupancy &base_occupied, const Occupancy &base_empty, double low_qual=0.01, double unknown_qual=0.5)
bool has_on_edge_line(const Segment2D &s) const