From e3761753ad2bdae2219b17cdb04ce052d08ce7e3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 24 Jan 2024 12:30:04 +0100 Subject: [PATCH] Some refactoring, introducing new configuration option for edge pair check core algorithm for zero distance handling. --- src/db/db/dbAsIfFlatEdges.cc | 7 +- src/db/db/dbAsIfFlatRegion.cc | 14 +- src/db/db/dbCompoundOperation.cc | 24 +- src/db/db/dbDeepEdges.cc | 7 +- src/db/db/dbDeepRegion.cc | 14 +- src/db/db/dbEdgePairRelations.cc | 28 +- src/db/db/dbEdgePairRelations.h | 119 +++++- src/db/db/dbEdgesDelegate.h | 63 ---- src/db/db/dbRegionLocalOperations.h | 50 +-- src/db/db/dbRegionUtils.cc | 7 +- src/db/unit_tests/dbEdgePairRelationsTests.cc | 353 +++++++++++++----- 11 files changed, 409 insertions(+), 277 deletions(-) diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index e4a482fe2..4f38b882e 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -761,12 +761,7 @@ AsIfFlatEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Co } } - EdgeRelationFilter check (rel, d, options.metrics); - check.set_include_zero (false); - check.set_whole_edges (options.whole_edges); - check.set_ignore_angle (options.ignore_angle); - check.set_min_projection (options.min_projection); - check.set_max_projection (options.max_projection); + EdgeRelationFilter check (rel, d, options); edge2edge_check_for_edges edge_check (check, *result, other != 0); scanner.process (edge_check, d, db::box_convert ()); diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 54f0b4f3b..5a86535fd 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1139,12 +1139,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, db::RegionIterator polygons (needs_merged_primary ? begin_merged () : begin ()); bool primary_is_merged = ! merged_semantics () || needs_merged_primary || is_merged (); - EdgeRelationFilter check (rel, d, options.metrics); - check.set_include_zero (false); - check.set_whole_edges (options.whole_edges); - check.set_ignore_angle (options.ignore_angle); - check.set_min_projection (options.min_projection); - check.set_max_projection (options.max_projection); + EdgeRelationFilter check (rel, d, options); std::vector others; std::vector foreign; @@ -1217,12 +1212,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord std::unique_ptr result (new FlatEdgePairs ()); db::PropertyMapper pm (result->properties_repository (), properties_repository ()); - EdgeRelationFilter check (rel, d, options.metrics); - check.set_include_zero (false); - check.set_whole_edges (options.whole_edges); - check.set_ignore_angle (options.ignore_angle); - check.set_min_projection (options.min_projection); - check.set_max_projection (options.max_projection); + EdgeRelationFilter check (rel, d, options); for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) { diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index 21e23c1c4..be321c493 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -1625,19 +1625,13 @@ CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (CompoundR // --------------------------------------------------------------------------------------------- CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) - : CompoundRegionMultiInputOperationNode (), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false) + : CompoundRegionMultiInputOperationNode (), m_check (rel, d, options), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false) { set_description ("check"); - - m_check.set_include_zero (false); - m_check.set_whole_edges (options.whole_edges); - m_check.set_ignore_angle (options.ignore_angle); - m_check.set_min_projection (options.min_projection); - m_check.set_max_projection (options.max_projection); } CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) - : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false) + : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false) { set_description ("check"); @@ -1645,16 +1639,10 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi if (pc_always_different (m_options.prop_constraint)) { m_different_polygons = true; } - - m_check.set_include_zero (false); - m_check.set_whole_edges (options.whole_edges); - m_check.set_ignore_angle (options.ignore_angle); - m_check.set_min_projection (options.min_projection); - m_check.set_max_projection (options.max_projection); } CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, CompoundRegionOperationNode *other, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) - : CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) + : CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options), m_different_polygons (different_polygons), m_options (options) { tl_assert (input == 0); // input is a dummy parameter @@ -1663,12 +1651,6 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi m_is_other_merged = other->is_merged (); set_description ("check"); - - m_check.set_include_zero (false); - m_check.set_whole_edges (options.whole_edges); - m_check.set_ignore_angle (options.ignore_angle); - m_check.set_min_projection (options.min_projection); - m_check.set_max_projection (options.max_projection); } db::OnEmptyIntruderHint diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 5a2812207..a9608af23 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -2046,12 +2046,7 @@ DeepEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Coord const db::DeepLayer &edges = merged_deep_layer (); - EdgeRelationFilter check (rel, d, options.metrics); - check.set_include_zero (false); - check.set_whole_edges (options.whole_edges); - check.set_ignore_angle (options.ignore_angle); - check.set_min_projection (options.min_projection); - check.set_max_projection (options.max_projection); + EdgeRelationFilter check (rel, d, options); std::unique_ptr res (new db::DeepEdgePairs (edges.derived ())); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index ceb7cf0a9..f44f0fca7 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1940,12 +1940,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons const db::DeepLayer &polygons = needs_merged_primary ? merged_deep_layer () : deep_layer (); - EdgeRelationFilter check (rel, d, options.metrics); - check.set_include_zero (false); - check.set_whole_edges (options.whole_edges); - check.set_ignore_angle (options.ignore_angle); - check.set_min_projection (options.min_projection); - check.set_max_projection (options.max_projection); + EdgeRelationFilter check (rel, d, options); std::unique_ptr res (new db::DeepEdgePairs (polygons.derived ())); @@ -2008,12 +2003,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c double mag = tr.mag (); db::Coord d_with_mag = db::coord_traits::rounded (d / mag); - EdgeRelationFilter check (rel, d_with_mag, options.metrics); - check.set_include_zero (false); - check.set_whole_edges (options.whole_edges); - check.set_ignore_angle (options.ignore_angle); - check.set_min_projection (options.min_projection); - check.set_max_projection (options.max_projection); + EdgeRelationFilter check (rel, d_with_mag, options); const db::Shapes &shapes = c->shapes (polygons.layer ()); db::Shapes &result = c->shapes (res->deep_layer ().layer ()); diff --git a/src/db/db/dbEdgePairRelations.cc b/src/db/db/dbEdgePairRelations.cc index 4875b29b4..5a6479af1 100644 --- a/src/db/db/dbEdgePairRelations.cc +++ b/src/db/db/dbEdgePairRelations.cc @@ -54,7 +54,7 @@ db::Edge::distance_type edge_projection (const db::Edge &a, const db::Edge &b) * This function applies Euclidian metrics. * If no such part is found, this function returns false. */ -bool euclidian_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output) +bool euclidian_near_part_of_edge (zero_distance_type zero_distance, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output) { // Handle the case of point-like basic edge: cannot determine // orientation @@ -68,7 +68,8 @@ bool euclidian_near_part_of_edge (bool include_zero, db::coord_traits int s2 = e.side_of (g.p2 ()); // "kissing corner" issue: force include zero if the edges are collinear and overlap. - if (! include_zero && s1 == 0 && s2 == 0 && e.intersect (g)) { + bool include_zero = (zero_distance == AlwaysIncludeZeroDistance); + if (zero_distance == IncludeZeroDistanceWhenTouch && s1 == 0 && s2 == 0 && e.intersect (g)) { include_zero = true; } @@ -197,7 +198,7 @@ bool euclidian_near_part_of_edge (bool include_zero, db::coord_traits * This function applies Square metrics. * If no such part is found, this function returns false. */ -static bool var_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, db::coord_traits::distance_type dd, const db::Edge &e, const db::Edge &other, db::Edge *output) +static bool var_near_part_of_edge (zero_distance_type zero_distance, db::coord_traits::distance_type d, db::coord_traits::distance_type dd, const db::Edge &e, const db::Edge &other, db::Edge *output) { // Handle the case of point-like basic edge: cannot determine // orientation @@ -211,7 +212,8 @@ static bool var_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output) +bool projected_near_part_of_edge (zero_distance_type zero_distance, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output) { - return var_near_part_of_edge (include_zero, d, 0, e, other, output); + return var_near_part_of_edge (zero_distance, d, 0, e, other, output); } /** @@ -325,20 +327,26 @@ bool projected_near_part_of_edge (bool include_zero, db::coord_traits * This function applies Square metrics. * If no such part is found, this function returns false. */ -bool square_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output) +bool square_near_part_of_edge (zero_distance_type zero_distance, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &other, db::Edge *output) { - return var_near_part_of_edge (include_zero, d, d, e, other, output); + return var_near_part_of_edge (zero_distance, d, d, e, other, output); } // --------------------------------------------------------------------------------- // Implementation of EdgeRelationFilter -EdgeRelationFilter::EdgeRelationFilter (edge_relation_type r, distance_type d, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) - : m_whole_edges (false), m_include_zero (true), m_r (r), m_d (d), m_metrics (metrics), m_ignore_angle (0), m_min_projection (min_projection), m_max_projection (max_projection) +EdgeRelationFilter::EdgeRelationFilter (edge_relation_type r, distance_type d, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, zero_distance_type include_zero) + : m_whole_edges (false), m_include_zero (include_zero), m_r (r), m_d (d), m_metrics (metrics), m_ignore_angle (0), m_min_projection (min_projection), m_max_projection (max_projection) { set_ignore_angle (ignore_angle); } +EdgeRelationFilter::EdgeRelationFilter (edge_relation_type r, distance_type d, const EdgesCheckOptions &options) + : m_whole_edges (false), m_include_zero (options.include_zero), m_r (r), m_d (d), m_metrics (options.metrics), m_ignore_angle (0), m_min_projection (options.min_projection), m_max_projection (options.max_projection) +{ + set_ignore_angle (options.ignore_angle); +} + void EdgeRelationFilter::set_ignore_angle (double a) { diff --git a/src/db/db/dbEdgePairRelations.h b/src/db/db/dbEdgePairRelations.h index 99b5aec6c..7dab0c9b9 100644 --- a/src/db/db/dbEdgePairRelations.h +++ b/src/db/db/dbEdgePairRelations.h @@ -98,6 +98,100 @@ enum edge_relation_type InsideRelation = 4 }; +/** + * @brief An enum specifying whether the edge relation includes zero distance + */ +enum zero_distance_type { + /** + * @brief Never include zero distance + */ + NeverIncludeZeroDistance = 0, + + /** + * @brief include zero distance when edges touch (e.g. kissing corner case) + */ + IncludeZeroDistanceWhenTouch = 1, + + /** + * @brief always include zero distance + */ + AlwaysIncludeZeroDistance = 2 +}; + +/** + * @brief A structure holding the options for the region checks (space, width, ...) + */ +struct DB_PUBLIC EdgesCheckOptions +{ + typedef db::coord_traits::distance_type distance_type; + + /** + * @brief Constructor + */ + EdgesCheckOptions (bool _whole_edges = false, + metrics_type _metrics = db::Euclidian, + double _ignore_angle = 90, + distance_type _min_projection = 0, + distance_type _max_projection = std::numeric_limits::max (), + zero_distance_type _include_zero = IncludeZeroDistanceWhenTouch) + : whole_edges (_whole_edges), + metrics (_metrics), + ignore_angle (_ignore_angle), + min_projection (_min_projection), + max_projection (_max_projection), + include_zero (_include_zero) + { } + + /** + * @brief Specifies is whole edges are to be delivered + * + * Without "whole_edges", the parts of + * the edges are returned which violate the condition. If "whole_edges" is true, the + * result will contain the complete edges participating in the result. + */ + bool whole_edges; + + /** + * @brief Measurement metrics + * + * The metrics parameter specifies which metrics to use. "Euclidian", "Square" and "Projected" + * metrics are available. + */ + metrics_type metrics; + + /** + * @brief Specifies the obtuse angle threshold + * + * "ignore_angle" allows specification of a maximum angle that connected edges can have to not participate + * in the check. By choosing 90 degree, edges with angles of 90 degree and larger are not checked, + * but acute corners are for example. + */ + double ignore_angle; + + /** + * @brief Specifies the projection limit's minimum value + * + * With min_projection and max_projection it is possible to specify how edges must be related + * to each other. If the length of the projection of either edge on the other is >= min_projection + * or < max_projection, the edges are considered for the check. + */ + distance_type min_projection; + + /** + * @brief Specifies the projection limit's maximum value + */ + distance_type max_projection; + + /** + * @brief Specifies zero distance handling + * + * This allows implementing the "kissing corners" case. When set to "WhenTouch", kissing corners will + * be reported as errors, when set to "Never", they won't. Note that with merged inputs, edges + * will not overlap except at the corners. + */ + zero_distance_type include_zero; +}; + /** * @brief A filter based on the edge pair relation * @@ -123,9 +217,14 @@ struct DB_PUBLIC EdgeRelationFilter * to each other. If the length of the projection of either edge on the other is >= min_projection * or < max_projection, the edges are considered for the check. */ - EdgeRelationFilter (edge_relation_type r, distance_type d, metrics_type metrics = db::Euclidian, double ignore_angle = 90, distance_type min_projection = 0, distance_type max_projection = std::numeric_limits::max ()); + EdgeRelationFilter (edge_relation_type r, distance_type d, metrics_type metrics = db::Euclidian, double ignore_angle = 90, distance_type min_projection = 0, distance_type max_projection = std::numeric_limits::max (), zero_distance_type include_zero = AlwaysIncludeZeroDistance); - /** + /** + * Constructs an edge relation filter from a CheckOptions structure + */ + EdgeRelationFilter (edge_relation_type r, distance_type d, const EdgesCheckOptions &options); + + /** * @brief Tests whether two edges fulfil the check fail criterion * * If the output pointer is non-null, the object will receive the edge pair that @@ -150,17 +249,17 @@ struct DB_PUBLIC EdgeRelationFilter } /** - * @brief Sets a flag indicating whether zero distance shall be included in the check + * @brief Sets a value indicating whether zero distance shall be included in the check */ - void set_include_zero (bool f) + void set_include_zero (zero_distance_type f) { m_include_zero = f; } /** - * @brief Gets a flag indicating whether zero distance shall be included in the check + * @brief Gets a value indicating whether zero distance shall be included in the check */ - bool include_zero () const + zero_distance_type include_zero () const { return m_include_zero; } @@ -262,7 +361,7 @@ struct DB_PUBLIC EdgeRelationFilter private: bool m_whole_edges; - bool m_include_zero; + zero_distance_type m_include_zero; edge_relation_type m_r; distance_type m_d; metrics_type m_metrics; @@ -273,9 +372,9 @@ private: // Internal methods exposed for testing purposes -DB_PUBLIC bool projected_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &g, db::Edge *output); -DB_PUBLIC bool square_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &g, db::Edge *output); -DB_PUBLIC bool euclidian_near_part_of_edge (bool include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &g, db::Edge *output); +DB_PUBLIC bool projected_near_part_of_edge (zero_distance_type include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &g, db::Edge *output); +DB_PUBLIC bool square_near_part_of_edge (zero_distance_type include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &g, db::Edge *output); +DB_PUBLIC bool euclidian_near_part_of_edge (zero_distance_type include_zero, db::coord_traits::distance_type d, const db::Edge &e, const db::Edge &g, db::Edge *output); DB_PUBLIC db::Edge::distance_type edge_projection (const db::Edge &a, const db::Edge &b); } diff --git a/src/db/db/dbEdgesDelegate.h b/src/db/db/dbEdgesDelegate.h index 919ba5b8a..051d671ee 100644 --- a/src/db/db/dbEdgesDelegate.h +++ b/src/db/db/dbEdgesDelegate.h @@ -39,69 +39,6 @@ namespace db { -/** - * @brief A structure holding the options for the region checks (space, width, ...) - */ -struct DB_PUBLIC EdgesCheckOptions -{ - typedef db::coord_traits::distance_type distance_type; - - /** - * @brief Constructor - */ - EdgesCheckOptions (bool _whole_edges = false, - metrics_type _metrics = db::Euclidian, - double _ignore_angle = 90, - distance_type _min_projection = 0, - distance_type _max_projection = std::numeric_limits::max ()) - : whole_edges (_whole_edges), - metrics (_metrics), - ignore_angle (_ignore_angle), - min_projection (_min_projection), - max_projection (_max_projection) - { } - - /** - * @brief Specifies is whole edges are to be delivered - * - * Without "whole_edges", the parts of - * the edges are returned which violate the condition. If "whole_edges" is true, the - * result will contain the complete edges participating in the result. - */ - bool whole_edges; - - /** - * @brief Measurement metrics - * - * The metrics parameter specifies which metrics to use. "Euclidian", "Square" and "Projected" - * metrics are available. - */ - metrics_type metrics; - - /** - * @brief Specifies the obtuse angle threshold - * - * "ignore_angle" allows specification of a maximum angle that connected edges can have to not participate - * in the check. By choosing 90 degree, edges with angles of 90 degree and larger are not checked, - * but acute corners are for example. - */ - double ignore_angle; - - /** - * @brief Specifies the projection limit's minimum value - * - * With min_projection and max_projection it is possible to specify how edges must be related - * to each other. If the length of the projection of either edge on the other is >= min_projection - * or < max_projection, the edges are considered for the check. - */ - distance_type min_projection; - - /** - * @brief Specifies the projection limit's maximum value - */ - distance_type max_projection; -}; - /** * @brief A base class for edge filters */ diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 90e91053e..997ac30ca 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -113,6 +113,7 @@ enum OppositeFilter * @brief A structure holding the options for the region checks (space, width, ...) */ struct DB_PUBLIC RegionCheckOptions + : public EdgesCheckOptions { typedef db::coord_traits::distance_type distance_type; @@ -128,12 +129,9 @@ struct DB_PUBLIC RegionCheckOptions OppositeFilter _opposite_filter = NoOppositeFilter, RectFilter _rect_filter = NoRectFilter, bool _negative = false, - PropertyConstraint _prop_constraint = IgnoreProperties) - : whole_edges (_whole_edges), - metrics (_metrics), - ignore_angle (_ignore_angle), - min_projection (_min_projection), - max_projection (_max_projection), + PropertyConstraint _prop_constraint = IgnoreProperties, + zero_distance_type _include_zero = IncludeZeroDistanceWhenTouch) + : EdgesCheckOptions (_whole_edges, _metrics, _ignore_angle, _min_projection, _max_projection, _include_zero), shielded (_shielded), opposite_filter (_opposite_filter), rect_filter (_rect_filter), @@ -141,46 +139,6 @@ struct DB_PUBLIC RegionCheckOptions prop_constraint (_prop_constraint) { } - /** - * @brief Specifies is whole edges are to be delivered - * - * Without "whole_edges", the parts of - * the edges are returned which violate the condition. If "whole_edges" is true, the - * result will contain the complete edges participating in the result. - */ - bool whole_edges; - - /** - * @brief Measurement metrics - * - * The metrics parameter specifies which metrics to use. "Euclidian", "Square" and "Projected" - * metrics are available. - */ - metrics_type metrics; - - /** - * @brief Specifies the obtuse angle threshold - * - * "ignore_angle" allows specification of a maximum angle that connected edges can have to not participate - * in the check. By choosing 90 degree, edges with angles of 90 degree and larger are not checked, - * but acute corners are for example. - */ - double ignore_angle; - - /** - * @brief Specifies the projection limit's minimum value - * - * With min_projection and max_projection it is possible to specify how edges must be related - * to each other. If the length of the projection of either edge on the other is >= min_projection - * or < max_projection, the edges are considered for the check. - */ - distance_type min_projection; - - /** - * @brief Specifies the projection limit's maximum value - */ - distance_type max_projection; - /** * @brief Specifies shielding * diff --git a/src/db/db/dbRegionUtils.cc b/src/db/db/dbRegionUtils.cc index 5084c0332..15b7b8bc7 100644 --- a/src/db/db/dbRegionUtils.cc +++ b/src/db/db/dbRegionUtils.cc @@ -359,12 +359,7 @@ SinglePolygonCheck::process (const db::Polygon &polygon, std::vector result; - EdgeRelationFilter check (m_relation, m_d, m_options.metrics); - check.set_include_zero (false); - check.set_whole_edges (m_options.whole_edges); - check.set_ignore_angle (m_options.ignore_angle); - check.set_min_projection (m_options.min_projection); - check.set_max_projection (m_options.max_projection); + EdgeRelationFilter check (m_relation, m_d, m_options); edge2edge_check_negative_or_positive > edge_check (check, result, m_options.negative, false /*=same polygons*/, false /*=same layers*/, m_options.shielded, true /*=symmetric*/); poly2poly_check poly_check (edge_check); diff --git a/src/db/unit_tests/dbEdgePairRelationsTests.cc b/src/db/unit_tests/dbEdgePairRelationsTests.cc index c0b3f918f..f836abec1 100644 --- a/src/db/unit_tests/dbEdgePairRelationsTests.cc +++ b/src/db/unit_tests/dbEdgePairRelationsTests.cc @@ -51,139 +51,139 @@ TEST(1) TEST(2) { db::Edge output; - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 10), db::Point (100, 200)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (100, 200)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 50), db::Point (100, 50)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (100, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 10), db::Point (100, 200)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (100, 200)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 50), db::Point (100, 50)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;100,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;187,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;187,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(-87,-50;187,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (0, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (0, -50)), &output), true); EXPECT_EQ (output.to_string (), "(-87,-50;0,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -100), db::Point (300, -100)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, 0), db::Point (300, -100)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -100), db::Point (300, -100)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, 0), db::Point (300, -100)), &output), true); EXPECT_EQ (output.to_string (), "(-94,-34;164,-77)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(0,0;50,-100)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (40, 0), db::Point (140, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (40, 0), db::Point (140, -200)), &output), true); EXPECT_EQ (output.to_string (), "(40,0;90,-100)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (200, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;145,-89)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -200), db::Point (200, -200)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -200), db::Point (200, -200)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;145,-89)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), true); EXPECT_EQ (output.to_string (), "(120,0;120,-98)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;100,-100)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;80,-100)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), true); EXPECT_EQ (output.to_string (), "(-80,0;-80,-60)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;-45,-89)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;100,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (50, -50), db::Point (50, -50)), &output), true); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (50, -50), db::Point (50, -50)), &output), true); EXPECT_EQ (output.to_string (), "(50,-50;50,-50)"); - EXPECT_EQ (euclidian_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (190, -50), db::Point (190, -50)), &output), false); + EXPECT_EQ (euclidian_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (190, -50), db::Point (190, -50)), &output), false); } TEST(3) { db::Edge output; - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (100, 200)), &output), false); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 50), db::Point (100, 50)), &output), false); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (100, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (100, 200)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 50), db::Point (100, 50)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;100,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;200,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;200,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(-100,-50;200,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (0, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (0, -50)), &output), true); EXPECT_EQ (output.to_string (), "(-100,-50;0,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -100), db::Point (300, -100)), &output), false); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, 0), db::Point (300, -100)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -100), db::Point (300, -100)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, 0), db::Point (300, -100)), &output), true); EXPECT_EQ (output.to_string (), "(-100,-33;200,-83)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(0,0;50,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (40, 0), db::Point (140, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (40, 0), db::Point (140, -200)), &output), true); EXPECT_EQ (output.to_string (), "(40,0;90,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (200, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;150,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -200), db::Point (200, -200)), &output), false); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -200), db::Point (200, -200)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;150,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), true); EXPECT_EQ (output.to_string (), "(120,0;120,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;100,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;80,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), true); EXPECT_EQ (output.to_string (), "(-80,0;-80,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;-60,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(-100,0;-100,-100)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;100,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (50, -50), db::Point (50, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (50, -50), db::Point (50, -50)), &output), true); EXPECT_EQ (output.to_string (), "(50,-50;50,-50)"); - EXPECT_EQ (square_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (190, -50), db::Point (190, -50)), &output), true); + EXPECT_EQ (square_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (190, -50), db::Point (190, -50)), &output), true); EXPECT_EQ (output.to_string (), "(190,-50;190,-50)"); } TEST(4) { db::Edge output; - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (100, 200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 50), db::Point (100, 50)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (100, -50)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (100, 200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 50), db::Point (100, 50)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;100,-50)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;100,-50)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (300, -50)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (300, -50)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (300, -50)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (300, -50)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;100,-50)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (0, -50)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -100), db::Point (300, -100)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, 0), db::Point (300, -100)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -50), db::Point (0, -50)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, -100), db::Point (300, -100)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-300, 0), db::Point (300, -100)), &output), true); EXPECT_EQ (output.to_string (), "(0,-50;100,-67)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, -200)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(0,0;50,-100)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (40, 0), db::Point (140, -200)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (40, 0), db::Point (140, -200)), &output), true); EXPECT_EQ (output.to_string (), "(40,0;90,-100)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (200, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -200), db::Point (200, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (200, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, -200), db::Point (200, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 200), db::Point (200, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (120, 200), db::Point (120, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 200), db::Point (100, -200)), &output), true); EXPECT_EQ (output.to_string (), "(100,0;100,-100)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 200), db::Point (80, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;80,-100)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-80, 200), db::Point (-80, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (80, 0), db::Point (-200, -200)), &output), true); EXPECT_EQ (output.to_string (), "(80,0;0,-57)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (), db::Edge (db::Point (-100, 200), db::Point (-100, -200)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 50), db::Point (100, 50)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, -50), db::Point (100, -50)), &output), true); EXPECT_EQ (output.to_string (), "(100,-50;100,-50)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (50, -50), db::Point (50, -50)), &output), true); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (50, -50), db::Point (50, -50)), &output), true); EXPECT_EQ (output.to_string (), "(50,-50;50,-50)"); - EXPECT_EQ (projected_near_part_of_edge (true, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (190, -50), db::Point (190, -50)), &output), false); + EXPECT_EQ (projected_near_part_of_edge (db::AlwaysIncludeZeroDistance, 100, db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (190, -50), db::Point (190, -50)), &output), false); } TEST(5) @@ -291,7 +291,7 @@ TEST(7) EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(1,30;1,20)"); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, 20)), &output); EXPECT_EQ (res, false); - f.set_include_zero (false); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, 20)), &output); EXPECT_EQ (res, false); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (1, 30), db::Point (1, 20)), &output); @@ -300,7 +300,7 @@ TEST(7) res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, 20)), &output); EXPECT_EQ (res, false); - f.set_include_zero (true); + f.set_include_zero (db::AlwaysIncludeZeroDistance); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 300), db::Point (0, -200)), &output); EXPECT_EQ (res, true); EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(0,110;0,-100)"); @@ -309,7 +309,7 @@ TEST(7) EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(1,110;1,-100)"); f.set_metrics (db::Square); - f.set_include_zero (true); + f.set_include_zero (db::AlwaysIncludeZeroDistance); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, 20)), &output); EXPECT_EQ (res, true); EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(0,30;0,20)"); @@ -318,7 +318,7 @@ TEST(7) EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(1,30;1,20)"); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, 20)), &output); EXPECT_EQ (res, false); - f.set_include_zero (false); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, 20)), &output); EXPECT_EQ (res, false); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (1, 30), db::Point (1, 20)), &output); @@ -327,7 +327,7 @@ TEST(7) res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, 20)), &output); EXPECT_EQ (res, false); - f.set_include_zero (true); + f.set_include_zero (db::AlwaysIncludeZeroDistance); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 300), db::Point (0, -200)), &output); EXPECT_EQ (res, true); EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(0,110;0,-100)"); @@ -336,7 +336,7 @@ TEST(7) EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(1,110;1,-100)"); f.set_metrics (db::Projection); - f.set_include_zero (true); + f.set_include_zero (db::AlwaysIncludeZeroDistance); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, -20)), &output); EXPECT_EQ (res, true); EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(0,10;0,0)"); @@ -345,7 +345,7 @@ TEST(7) EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(1,10;1,0)"); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (-1, 30), db::Point (-1, -20)), &output); EXPECT_EQ (res, false); - f.set_include_zero (false); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (0, 30), db::Point (0, 11)), &output); EXPECT_EQ (res, false); res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 10)), db::Edge (db::Point (1, 30), db::Point (1, -20)), &output); @@ -361,7 +361,7 @@ TEST(8_KissingCornerProblem) // if the projection is >0. db::EdgeRelationFilter f (db::WidthRelation, 10); - f.set_include_zero (false); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); db::EdgePair output; bool res; @@ -382,8 +382,23 @@ TEST(8_KissingCornerProblem) res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output); EXPECT_EQ (res, false); + f.set_include_zero (db::NeverIncludeZeroDistance); + + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 201), db::Point (0, 101)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 0), db::Point (1, 100)), db::Edge (db::Point (0, 201), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 50)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 0), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + f = db::EdgeRelationFilter (db::SpaceRelation, 10); - f.set_include_zero (false); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); f.set_metrics (db::Euclidian); res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output); @@ -401,4 +416,172 @@ TEST(8_KissingCornerProblem) EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,10;0,0):(0,-10;0,0)"); res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output); EXPECT_EQ (res, false); + + f.set_include_zero (db::NeverIncludeZeroDistance); + + f.set_metrics (db::Euclidian); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 100), db::Point (1, 0)), db::Edge (db::Point (0, 0), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 100), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 50), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output); + EXPECT_EQ (res, false); +} + +TEST(9_KissingCornerProblemSquareMetrics) +{ + // The kissing corner problem is solved by allowing distance-0 width and space relations and checking them + // if the projection is >0. + + db::EdgeRelationFilter f (db::WidthRelation, 10); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); + db::EdgePair output; + bool res; + + f.set_metrics (db::Square); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 201), db::Point (0, 101)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 0), db::Point (1, 100)), db::Edge (db::Point (0, 201), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 100)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,90;0,100):(0,110;0,100)"); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 50)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,40;0,100):(0,110;0,50)"); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 0), db::Point (0, -100)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,0;0,10):(0,0;0,-10)"); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + + f.set_include_zero (db::NeverIncludeZeroDistance); + + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 201), db::Point (0, 101)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 0), db::Point (1, 100)), db::Edge (db::Point (0, 201), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 50)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 0), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + + f = db::EdgeRelationFilter (db::SpaceRelation, 10); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); + + f.set_metrics (db::Square); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 100), db::Point (1, 0)), db::Edge (db::Point (0, 0), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 100), db::Point (0, 200)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,100;0,90):(0,100;0,110)"); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 50), db::Point (0, 200)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,100;0,40):(0,50;0,110)"); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, 0)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,10;0,0):(0,-10;0,0)"); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output); + EXPECT_EQ (res, false); + + f.set_include_zero (db::NeverIncludeZeroDistance); + + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 100), db::Point (1, 0)), db::Edge (db::Point (0, 0), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 100), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 50), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output); + EXPECT_EQ (res, false); +} + +TEST(10_KissingCornerProblemProjectionMetrics) +{ + // The kissing corner problem is solved by allowing distance-0 width and space relations and checking them + // if the projection is >0. It is not effective in projection metrics as there is no overlap. + + db::EdgeRelationFilter f (db::WidthRelation, 10); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); + db::EdgePair output; + bool res; + + f.set_metrics (db::Projection); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 201), db::Point (0, 101)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 0), db::Point (1, 100)), db::Edge (db::Point (0, 201), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 50)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,50;0,100):(0,100;0,50)"); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 0), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + + f.set_include_zero (db::NeverIncludeZeroDistance); + + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 201), db::Point (0, 101)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 0), db::Point (1, 100)), db::Edge (db::Point (0, 201), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 200), db::Point (0, 50)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, 0), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 0), db::Point (0, 100)), db::Edge (db::Point (0, -1), db::Point (0, -100)), &output); + EXPECT_EQ (res, false); + + f = db::EdgeRelationFilter (db::SpaceRelation, 10); + f.set_include_zero (db::IncludeZeroDistanceWhenTouch); + + f.set_metrics (db::Projection); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 100), db::Point (1, 0)), db::Edge (db::Point (0, 0), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 100), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 50), db::Point (0, 200)), &output); + EXPECT_EQ (res, true); + EXPECT_EQ (output.first ().to_string () + ":" + output.second ().to_string (), "(0,100;0,50):(0,50;0,100)"); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output); + EXPECT_EQ (res, false); + + f.set_include_zero (db::NeverIncludeZeroDistance); + + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 101), db::Point (0, 201)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (1, 100), db::Point (1, 0)), db::Edge (db::Point (0, 0), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 100), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, 50), db::Point (0, 200)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, 0)), &output); + EXPECT_EQ (res, false); + res = f.check (db::Edge (db::Point (0, 100), db::Point (0, 0)), db::Edge (db::Point (0, -100), db::Point (0, -1)), &output); + EXPECT_EQ (res, false); }