bool boundaries_intersect(const Polygon_2& P, const Polygon_2& Q, bool proper) { std::list<Segment_2> segments0, segments1; segments0.insert(segments0.end(), P.edges_begin(), P.edges_end()); segments1.insert(segments1.end(), Q.edges_begin(), Q.edges_end()); bool intersects = has_intersection(segments0.begin(), segments0.end(), segments1.begin(), segments1.end(), true, true); if (!intersects || !proper) return intersects; if (has_intersection(segments0.begin(), segments0.end(), segments1.begin(), segments1.end(), false, false)) return true; typedef Polygon_2::Vertex_const_iterator Iter; for (Iter it = P.vertices_begin(); it != P.vertices_end(); ++it) { if (Q.has_on_bounded_side(*it)) return true; } for (Iter it = Q.vertices_begin(); it != Q.vertices_end(); ++it) { if (P.has_on_bounded_side(*it)) return true; } return false; }
// Merge a given rank sink (new_sink) (ie. a set of Nodes) with one of exsisting // rank sink(s). // Returns ture if it merges, otherwise insert it to sink(s) group as a new rank sink // merge condition : if new_sink n sinks_i => merged( new_sink u sinks_i) for all 'i' in sinks // where // n, u - set intersect and union operators // sink_i - 'i'th sink set in sinks bool PageRank::merge_rank_sinks(vector<vector<Node> >& sinks, vector<Node>& new_sink) const { // check whether the created rank_sink can be merged with an already created rank sink for (unsigned int rs=0; rs< sinks.size(); ++rs) { // check all rank sink created so far bool shared_nodes= has_intersection(sinks[rs].begin(), sinks[rs].end(), new_sink.begin(), new_sink.end()); if (shared_nodes) { // merge new rank_sink with sinks[rs] set vector<Node> merged_sink; merged_sink.resize( new_sink.size() + sinks[rs].size()); // size() on the safe side vector<Node>::iterator nsize; nsize = set_union(new_sink.begin(), new_sink.end(), sinks[rs].begin(), sinks[rs].end(), merged_sink.begin()); merged_sink.resize(nsize - merged_sink.begin()); // resize sinks[rs] = merged_sink; PRINT(LOG_LVL_3, "Rank sink is merged with a previously found sink" << endl); return true; } } // couldn't merge create a new sink group sinks.push_back( new_sink); PRINT(LOG_LVL_3, "New rank sink created" << endl); return false; }
bool intersects_boundary(const Polygon_2& P, const Segment_2& s, bool end_internal, bool end_end) { std::list<Segment_2> segments0, segments1; segments0.insert(segments0.end(), P.edges_begin(), P.edges_end()); segments1.push_back(s); return has_intersection(segments0.begin(), segments0.end(), segments1.begin(), segments1.end(), end_internal, end_end); }
static bool requiresDedupe(const NGHolder &h, const flat_set<ReportID> &reports, const Grey &grey) { /* TODO: tighten */ NFAVertex seen_vert = NGHolder::null_vertex(); for (auto v : inv_adjacent_vertices_range(h.accept, h)) { if (has_intersection(h[v].reports, reports)) { if (seen_vert != NGHolder::null_vertex()) { return true; } seen_vert = v; } } for (auto v : inv_adjacent_vertices_range(h.acceptEod, h)) { if (has_intersection(h[v].reports, reports)) { if (seen_vert != NGHolder::null_vertex()) { return true; } seen_vert = v; } } if (seen_vert) { /* if the reporting vertex is part of of a terminal repeat, the * construction process may reform the graph splitting it into two * vertices (pos, cyclic) and hence require dedupe */ vector<GraphRepeatInfo> repeats; findRepeats(h, grey.minExtBoundedRepeatSize, &repeats); for (const auto &repeat : repeats) { if (find(repeat.vertices.begin(), repeat.vertices.end(), seen_vert) != repeat.vertices.end()) { return true; } } } return false; }
TEST(geometry, ray_segment_intersection) { ASSERT_TRUE(has_intersection({{-1, 0, 1}, {1, 0, 1}}, {{0, -2, 1}, {0, -1, 1}})); ASSERT_FALSE(has_intersection({{-1, 0, 1}, {1, 0, 1}}, {{0, -1, 1}, {0, -2, 1}})); ASSERT_FALSE(has_intersection({{-1, 0, 1}, {1, 0, 1}}, {{0, -2, 1}, {1, -1, 1}})); }
bool RoseDedupeAuxImpl::requiresDedupeSupport( const flat_set<ReportID> &reports_in) const { /* TODO: this could be expanded to check for offset or character constraints */ // We don't want to consider dead reports (tracked by ReportManager but no // longer used) for the purposes of assigning dupe keys. flat_set<ReportID> reports; for (auto id : reports_in) { if (contains(live_reports, id)) { reports.insert(id); } } DEBUG_PRINTF("live reports: %s\n", as_string_list(reports).c_str()); const RoseGraph &g = build.g; bool has_suffix = false; bool has_outfix = false; if (!hasSafeMultiReports(reports)) { DEBUG_PRINTF("multiple reports not safe\n"); return true; } set<RoseVertex> roles; set<suffix_id> suffixes; set<const OutfixInfo *> outfixes; set<const raw_puff *> puffettes; for (ReportID r : reports) { if (contains(vert_map, r)) { insert(&roles, vert_map.at(r)); } if (contains(suffix_map, r)) { insert(&suffixes, suffix_map.at(r)); } if (contains(outfix_map, r)) { insert(&outfixes, outfix_map.at(r)); } if (contains(puff_map, r)) { insert(&puffettes, puff_map.at(r)); } } /* roles */ map<u32, u32> lits; // Literal ID -> count of occurrences. const bool has_role = !roles.empty(); for (auto v : roles) { for (const auto &lit : g[v].literals) { lits[lit]++; } if (g[v].eod_accept) { // Literals plugged into this EOD accept must be taken into account // as well. for (auto u : inv_adjacent_vertices_range(v, g)) { for (const auto &lit : g[u].literals) { lits[lit]++; } } } } /* literals */ for (const auto &m : lits) { if (m.second > 1) { DEBUG_PRINTF("lit %u used by >1 reporting roles\n", m.first); return true; } } for (auto it = begin(lits); it != end(lits); ++it) { const auto &lit1 = build.literals.at(it->first); for (auto jt = next(it); jt != end(lits); ++jt) { const auto &lit2 = build.literals.at(jt->first); if (literalsCouldRace(lit1, lit2)) { DEBUG_PRINTF("literals could race\n"); return true; } } } /* suffixes */ for (const auto &suffix : suffixes) { if (has_suffix || has_role) { return true; /* scope for badness */ } has_suffix = true; /* some lesser suffix engines (nfas, haig, castle) can raise multiple * matches for a report id at the same offset if there are multiple * report states live. */ if (suffix.haig()) { return true; } if (suffix.graph() && requiresDedupe(*suffix.graph(), reports, build.cc.grey)) { return true; } if (suffix.castle() && requiresDedupe(*suffix.castle(), reports)) { return true; } } /* outfixes */ for (const auto &outfix_ptr : outfixes) { assert(outfix_ptr); const OutfixInfo &out = *outfix_ptr; if (has_outfix || has_role || has_suffix) { return true; } has_outfix = true; if (out.haig()) { return true; /* haig may report matches with different SOM at the same offset */ } if (out.holder() && requiresDedupe(*out.holder(), reports, build.cc.grey)) { return true; } } /* mpv */ for (UNUSED const auto &puff : puffettes) { if (has_outfix || has_role || has_suffix) { return true; } has_outfix = true; } /* boundary */ if (has_intersection(build.boundary.report_at_eod, reports)) { if (has_outfix || has_role || has_suffix) { return true; } } return false; }