← Back to team overview

kicad-developers team mailing list archive

[PATCH] QA: Polyset Distance tests

 

Hi,

Following the QA patch set just merged, here are a couple more.

1) Add tests on SHAPE_POLY_SET::Distance and a few geometry helpers
for concisely constructing test objects. Notably: this test would have
caught the bug just fixed in 90178eb68.
2) Some internal QA tidy up to make the qa-internal includes clearer.

(These tests do not concern, conflict with or affect the recent
SHAPE_POLY_SET Collision problems.)

Cheers,

John
From f2df038f45edc6c88ec0f506fe7d604002ea8701 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Mon, 28 Jan 2019 10:36:54 +0000
Subject: [PATCH 2/2] QA: Tidy qa_utils headers

Move into own include directory for clarity. Also allows qa_utils
to use its own private headers in qa/qa_utils without exposing them
through the target_include_directories directive.
---
 qa/common_tools/main.cpp                               |  2 +-
 qa/common_tools/tools/coroutines/coroutine_tools.h     |  2 +-
 qa/common_tools/tools/io_benchmark/io_benchmark.cpp    |  4 ++--
 qa/common_tools/tools/io_benchmark/io_benchmark.h      | 10 +++++-----
 qa/pcbnew_tools/pcbnew_tools.cpp                       |  2 +-
 qa/pcbnew_tools/tools/drc_tool/drc_tool.cpp            |  4 ++--
 qa/pcbnew_tools/tools/drc_tool/drc_tool.h              |  2 +-
 qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.cpp   |  4 ++--
 qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.h     |  2 +-
 .../tools/polygon_generator/polygon_generator.h        |  2 +-
 .../polygon_triangulation/polygon_triangulation.h      |  2 +-
 qa/pcbnew_utils/board_file_utils.cpp                   |  2 +-
 qa/qa_utils/CMakeLists.txt                             |  1 -
 qa/qa_utils/{ => include/qa_utils}/scoped_timer.h      |  9 +++------
 .../{ => include/qa_utils}/stdstream_line_reader.h     | 10 ++++------
 qa/qa_utils/{ => include/qa_utils}/utility_program.h   |  0
 qa/qa_utils/stdstream_line_reader.cpp                  |  2 +-
 qa/qa_utils/utility_program.cpp                        |  2 +-
 18 files changed, 28 insertions(+), 34 deletions(-)
 rename qa/qa_utils/{ => include/qa_utils}/scoped_timer.h (91%)
 rename qa/qa_utils/{ => include/qa_utils}/stdstream_line_reader.h (94%)
 rename qa/qa_utils/{ => include/qa_utils}/utility_program.h (100%)

diff --git a/qa/common_tools/main.cpp b/qa/common_tools/main.cpp
index f42f83d40..f537fd826 100644
--- a/qa/common_tools/main.cpp
+++ b/qa/common_tools/main.cpp
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 #include "tools/coroutines/coroutine_tools.h"
 #include "tools/io_benchmark/io_benchmark.h"
diff --git a/qa/common_tools/tools/coroutines/coroutine_tools.h b/qa/common_tools/tools/coroutines/coroutine_tools.h
index 89f54501e..221a57b11 100644
--- a/qa/common_tools/tools/coroutines/coroutine_tools.h
+++ b/qa/common_tools/tools/coroutines/coroutine_tools.h
@@ -2,7 +2,7 @@
 #ifndef COROUTINES_UTILTY_H
 #define COROUTINES_UTILTY_H
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 /// A tool to test a simple coroutine
 extern KI_TEST::UTILITY_PROGRAM coroutine_tool;
diff --git a/qa/common_tools/tools/io_benchmark/io_benchmark.cpp b/qa/common_tools/tools/io_benchmark/io_benchmark.cpp
index a1df3f280..23c557857 100644
--- a/qa/common_tools/tools/io_benchmark/io_benchmark.cpp
+++ b/qa/common_tools/tools/io_benchmark/io_benchmark.cpp
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -36,7 +36,7 @@
 #include <wx/wfstream.h>
 #include <wx/filename.h>
 
-#include "stdstream_line_reader.h"
+#include <qa_utils/stdstream_line_reader.h>
 
 
 using CLOCK = std::chrono::steady_clock;
diff --git a/qa/common_tools/tools/io_benchmark/io_benchmark.h b/qa/common_tools/tools/io_benchmark/io_benchmark.h
index b115ce744..6f16d9668 100644
--- a/qa/common_tools/tools/io_benchmark/io_benchmark.h
+++ b/qa/common_tools/tools/io_benchmark/io_benchmark.h
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2018-2019 KiCad Developers, see CHANGELOG.TXT for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -21,11 +21,11 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#ifndef IO_BENCHMARK_H
-#define IO_BENCHMARK_H
+#ifndef QA_COMMON_TOOLS_IO_BENCHMARK__H
+#define QA_COMMON_TOOLS_IO_BENCHMARK__H
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 extern KI_TEST::UTILITY_PROGRAM io_benchmark_tool;
 
-#endif // IO_BENCHMARK_H
\ No newline at end of file
+#endif // QA_COMMON_TOOLS_IO_BENCHMARK__H
\ No newline at end of file
diff --git a/qa/pcbnew_tools/pcbnew_tools.cpp b/qa/pcbnew_tools/pcbnew_tools.cpp
index 4b810b8b9..1d57cd41d 100644
--- a/qa/pcbnew_tools/pcbnew_tools.cpp
+++ b/qa/pcbnew_tools/pcbnew_tools.cpp
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 #include "tools/drc_tool/drc_tool.h"
 #include "tools/pcb_parser/pcb_parser_tool.h"
diff --git a/qa/pcbnew_tools/tools/drc_tool/drc_tool.cpp b/qa/pcbnew_tools/tools/drc_tool/drc_tool.cpp
index 28b3acd93..83ded9fa6 100644
--- a/qa/pcbnew_tools/tools/drc_tool/drc_tool.cpp
+++ b/qa/pcbnew_tools/tools/drc_tool/drc_tool.cpp
@@ -36,8 +36,8 @@
 #include <drc/courtyard_overlap.h>
 #include <drc/drc_marker_factory.h>
 
-#include <scoped_timer.h>
-#include <stdstream_line_reader.h>
+#include <qa_utils/scoped_timer.h>
+#include <qa_utils/stdstream_line_reader.h>
 
 
 using DRC_DURATION = std::chrono::microseconds;
diff --git a/qa/pcbnew_tools/tools/drc_tool/drc_tool.h b/qa/pcbnew_tools/tools/drc_tool/drc_tool.h
index accb2e97b..da5ab20c4 100644
--- a/qa/pcbnew_tools/tools/drc_tool/drc_tool.h
+++ b/qa/pcbnew_tools/tools/drc_tool/drc_tool.h
@@ -24,7 +24,7 @@
 #ifndef PCBNEW_TOOLS_DRC_TOOL_H
 #define PCBNEW_TOOLS_DRC_TOOL_H
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 /// A tool to run DRC tools on KiCad PCBs from the command line
 extern KI_TEST::UTILITY_PROGRAM drc_tool;
diff --git a/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.cpp b/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.cpp
index e29447bc8..2bf77679f 100644
--- a/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.cpp
+++ b/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.cpp
@@ -37,8 +37,8 @@
 
 #include <wx/cmdline.h>
 
-#include <scoped_timer.h>
-#include <stdstream_line_reader.h>
+#include <qa_utils/scoped_timer.h>
+#include <qa_utils/stdstream_line_reader.h>
 
 using PARSE_DURATION = std::chrono::microseconds;
 
diff --git a/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.h b/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.h
index cfbe4fb57..cd574f728 100644
--- a/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.h
+++ b/qa/pcbnew_tools/tools/pcb_parser/pcb_parser_tool.h
@@ -24,7 +24,7 @@
 #ifndef PCBNEW_TOOLS_PCB_PARSER_UTILITY_H
 #define PCBNEW_TOOLS_PCB_PARSER_UTILITY_H
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 /// A tool to parse kicad PCBs from the command line
 extern KI_TEST::UTILITY_PROGRAM pcb_parser_tool;
diff --git a/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.h b/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.h
index bab141224..f2b3d575c 100644
--- a/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.h
+++ b/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.h
@@ -24,7 +24,7 @@
 #ifndef PCBNEW_TOOLS_POLYGON_GENERATOR_UTILITY_H
 #define PCBNEW_TOOLS_POLYGON_GENERATOR_UTILITY_H
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 /// A tool to parse kicad PCBs from the command line
 extern KI_TEST::UTILITY_PROGRAM polygon_generator_tool;
diff --git a/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.h b/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.h
index b3410db60..8b1b560f4 100644
--- a/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.h
+++ b/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.h
@@ -24,7 +24,7 @@
 #ifndef PCBNEW_TOOLS_POLYGON_TRIANGULATION_UTILITY_H
 #define PCBNEW_TOOLS_POLYGON_TRIANGULATION_UTILITY_H
 
-#include <utility_program.h>
+#include <qa_utils/utility_program.h>
 
 /// A tool to parse kicad PCBs from the command line
 extern KI_TEST::UTILITY_PROGRAM polygon_triangulation_tool;
diff --git a/qa/pcbnew_utils/board_file_utils.cpp b/qa/pcbnew_utils/board_file_utils.cpp
index d4969ae91..395bfa708 100644
--- a/qa/pcbnew_utils/board_file_utils.cpp
+++ b/qa/pcbnew_utils/board_file_utils.cpp
@@ -30,7 +30,7 @@
 
 #include <class_board.h>
 
-#include <stdstream_line_reader.h>
+#include <qa_utils/stdstream_line_reader.h>
 
 namespace KI_TEST
 {
diff --git a/qa/qa_utils/CMakeLists.txt b/qa/qa_utils/CMakeLists.txt
index 1e8bcffe2..20fed4511 100644
--- a/qa/qa_utils/CMakeLists.txt
+++ b/qa/qa_utils/CMakeLists.txt
@@ -42,5 +42,4 @@ target_link_libraries( qa_utils
 
 target_include_directories( qa_utils PUBLIC
     include
-    ${CMAKE_CURRENT_SOURCE_DIR}
 )
\ No newline at end of file
diff --git a/qa/qa_utils/scoped_timer.h b/qa/qa_utils/include/qa_utils/scoped_timer.h
similarity index 91%
rename from qa/qa_utils/scoped_timer.h
rename to qa/qa_utils/include/qa_utils/scoped_timer.h
index 028bfef46..78a855d5c 100644
--- a/qa/qa_utils/scoped_timer.h
+++ b/qa/qa_utils/include/qa_utils/scoped_timer.h
@@ -32,15 +32,13 @@
  * ON construction, a timer is started, and on destruction, the timer is
  * ended, and the time difference is written into the given duration
  */
-template<typename DURATION>
-class SCOPED_TIMER
+template <typename DURATION> class SCOPED_TIMER
 {
     using CLOCK = std::chrono::steady_clock;
     using TIME_PT = std::chrono::time_point<CLOCK>;
 
 public:
-    SCOPED_TIMER( DURATION& aDuration ):
-        m_duration( aDuration )
+    SCOPED_TIMER( DURATION& aDuration ) : m_duration( aDuration )
     {
         m_start = CLOCK::now();
     }
@@ -54,9 +52,8 @@ public:
     }
 
 private:
-
     DURATION& m_duration;
-    TIME_PT m_start;
+    TIME_PT   m_start;
 };
 
 #endif // SCOPED_TIMER_h
\ No newline at end of file
diff --git a/qa/qa_utils/stdstream_line_reader.h b/qa/qa_utils/include/qa_utils/stdstream_line_reader.h
similarity index 94%
rename from qa/qa_utils/stdstream_line_reader.h
rename to qa/qa_utils/include/qa_utils/stdstream_line_reader.h
index 81c238dc6..491e3a010 100644
--- a/qa/qa_utils/stdstream_line_reader.h
+++ b/qa/qa_utils/include/qa_utils/stdstream_line_reader.h
@@ -28,8 +28,8 @@
 
 #include <richio.h>
 
-#include <istream>
 #include <fstream>
+#include <istream>
 
 /**
  * LINE_READER that wraps a given std::istream instance.
@@ -37,21 +37,20 @@
 class STDISTREAM_LINE_READER : public LINE_READER
 {
 public:
-
     STDISTREAM_LINE_READER();
 
     ~STDISTREAM_LINE_READER();
 
-    char* ReadLine()  override;
+    char* ReadLine() override;
 
     /**
      * Set the stream for this line reader.
      * @param aStream a stream to read
      */
-    void SetStream( std::istream&  aStream );
+    void SetStream( std::istream& aStream );
 
 private:
-    std::string m_buffer;
+    std::string   m_buffer;
     std::istream* m_stream;
 };
 
@@ -62,7 +61,6 @@ private:
 class IFSTREAM_LINE_READER : public STDISTREAM_LINE_READER
 {
 public:
-
     IFSTREAM_LINE_READER( const wxFileName& aFileName );
 
     void Rewind();
diff --git a/qa/qa_utils/utility_program.h b/qa/qa_utils/include/qa_utils/utility_program.h
similarity index 100%
rename from qa/qa_utils/utility_program.h
rename to qa/qa_utils/include/qa_utils/utility_program.h
diff --git a/qa/qa_utils/stdstream_line_reader.cpp b/qa/qa_utils/stdstream_line_reader.cpp
index d473f3442..ededd0ca3 100644
--- a/qa/qa_utils/stdstream_line_reader.cpp
+++ b/qa/qa_utils/stdstream_line_reader.cpp
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include "stdstream_line_reader.h"
+#include <qa_utils/stdstream_line_reader.h>
 
 #include <ios>
 
diff --git a/qa/qa_utils/utility_program.cpp b/qa/qa_utils/utility_program.cpp
index 39457c44a..47908d253 100644
--- a/qa/qa_utils/utility_program.cpp
+++ b/qa/qa_utils/utility_program.cpp
@@ -20,7 +20,7 @@
  * or you may write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
-#include "utility_program.h"
+#include <qa_utils/utility_program.h>
 
 #include <wx/msgout.h>
 
-- 
2.20.1

From ad9b2a07b395eb782277c28e04d5edd83c7fc8e7 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Mon, 28 Jan 2019 10:28:02 +0000
Subject: [PATCH 1/2] QA: Add some tests on SHAPE_POLY_SET::Distance

These tests pick up the bug fixed in: 90178eb6812eead81a2523fbb7cce665413637eb
(as it is already fixed there is no failure).
---
 qa/common/CMakeLists.txt                      |   1 +
 .../geometry/test_shape_poly_set_distance.cpp | 149 ++++++++++++++++++
 qa/qa_utils/CMakeLists.txt                    |   5 +
 .../geometry/line_chain_construction.cpp      |  49 ++++++
 .../geometry/poly_set_construction.cpp        |  54 +++++++
 qa/qa_utils/geometry/seg_construction.cpp     |  39 +++++
 .../geometry/line_chain_construction.h        |  56 +++++++
 .../qa_utils/geometry/poly_set_construction.h |  59 +++++++
 .../qa_utils/geometry/seg_construction.h      |  56 +++++++
 9 files changed, 468 insertions(+)
 create mode 100644 qa/common/geometry/test_shape_poly_set_distance.cpp
 create mode 100644 qa/qa_utils/geometry/line_chain_construction.cpp
 create mode 100644 qa/qa_utils/geometry/poly_set_construction.cpp
 create mode 100644 qa/qa_utils/geometry/seg_construction.cpp
 create mode 100644 qa/qa_utils/include/qa_utils/geometry/line_chain_construction.h
 create mode 100644 qa/qa_utils/include/qa_utils/geometry/poly_set_construction.h
 create mode 100644 qa/qa_utils/include/qa_utils/geometry/seg_construction.h

diff --git a/qa/common/CMakeLists.txt b/qa/common/CMakeLists.txt
index 5b105f139..24b065141 100644
--- a/qa/common/CMakeLists.txt
+++ b/qa/common/CMakeLists.txt
@@ -50,6 +50,7 @@ set( common_srcs
     geometry/test_segment.cpp
     geometry/test_shape_arc.cpp
     geometry/test_shape_poly_set_collision.cpp
+    geometry/test_shape_poly_set_distance.cpp
     geometry/test_shape_poly_set_iterator.cpp
 
     view/test_zoom_controller.cpp
diff --git a/qa/common/geometry/test_shape_poly_set_distance.cpp b/qa/common/geometry/test_shape_poly_set_distance.cpp
new file mode 100644
index 000000000..79de9620a
--- /dev/null
+++ b/qa/common/geometry/test_shape_poly_set_distance.cpp
@@ -0,0 +1,149 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 CERN
+ * @author Alejandro García Montoro <alejandro.garciamontoro@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <unit_test_utils/unit_test_utils.h>
+
+#include <convert_to_biu.h>
+
+#include <geometry/shape_poly_set.h>
+
+#include <qa_utils/geometry/poly_set_construction.h>
+#include <qa_utils/geometry/seg_construction.h>
+
+/**
+ * Declares the Boost test suite fixture.
+ */
+BOOST_AUTO_TEST_SUITE( SPSDistance )
+
+struct SPS_DISTANCE_TO_SEG_CASE
+{
+    std::string m_case_name;
+
+    /// list of lists of polygon points
+    SHAPE_POLY_SET m_polyset;
+
+    /// the segment to check distance to
+    SEG m_seg;
+    int m_seg_width;
+
+    /// The expected answer
+    int m_exp_dist;
+};
+
+static std::vector<SPS_DISTANCE_TO_SEG_CASE> GetSPSSegDistCases()
+{
+    namespace KT = KI_TEST;
+    std::vector<SPS_DISTANCE_TO_SEG_CASE> cases;
+
+    // Single 10mm square at origin
+    const SHAPE_POLY_SET square_10mm_0_0 = KT::BuildPolyset( {
+            KT::BuildSquareChain( Millimeter2iu( 10 ) ),
+    } );
+
+    // Double square: 10mm each, one at (0, 0), one at (10, 0)
+    const SHAPE_POLY_SET squares_10mm_0_0_and_20_0 = KT::BuildPolyset( {
+            KT::BuildSquareChain( Millimeter2iu( 10 ) ),
+            KT::BuildSquareChain( Millimeter2iu( 10 ), //
+                    { Millimeter2iu( 20 ), Millimeter2iu( 0 ) } ),
+    } );
+
+    // Hollow square: 10mm hole in 20mm square, at origin
+    const SHAPE_POLY_SET hollow_square_20_10_at_0_0 =
+            KT::BuildHollowSquare( Millimeter2iu( 20 ), Millimeter2iu( 10 ) );
+
+    cases.push_back( {
+            "Square poly -> 1D segment",
+            square_10mm_0_0,
+            KT::BuildHSeg( { Millimeter2iu( 0 ), Millimeter2iu( 15 ) }, Millimeter2iu( 10 ) ),
+            Millimeter2iu( 0 ), // 1-d segment
+            Millimeter2iu( 10 ),
+    } );
+
+    cases.push_back( {
+            "Square poly -> 2D (thick) segment",
+            square_10mm_0_0,
+            KT::BuildHSeg( { Millimeter2iu( 0 ), Millimeter2iu( 15 ) }, Millimeter2iu( 10 ) ),
+            Millimeter2iu( 2 ), // thick segment
+            Millimeter2iu( 9 ),
+    } );
+
+    cases.push_back( {
+            "Two Squares poly -> 2D segment (nearest second square)", squares_10mm_0_0_and_20_0,
+            KT::BuildHSeg( { Millimeter2iu( 15 ), Millimeter2iu( 15 ) }, Millimeter2iu( 10 ) ),
+            Millimeter2iu( 2 ), // thick segment
+            Millimeter2iu( 9 ), // from line to second square
+    } );
+
+    cases.push_back( {
+            "Square poly -> one intersect", square_10mm_0_0,
+            KT::BuildHSeg( { Millimeter2iu( -5 ), Millimeter2iu( 0 ) }, Millimeter2iu( 10 ) ),
+            Millimeter2iu( 0 ), // 1-d segment
+            Millimeter2iu( 0 ), // intersect
+    } );
+
+    cases.push_back( {
+            "Square poly -> multiple intersection", square_10mm_0_0,
+            KT::BuildHSeg( { Millimeter2iu( -5 ), Millimeter2iu( 0 ) }, Millimeter2iu( 20 ) ),
+            Millimeter2iu( 0 ), // 1-d segment
+            Millimeter2iu( 0 ), // intersect
+    } );
+
+    cases.push_back( {
+            "Square poly -> 1D seg touching", square_10mm_0_0,
+            // touch left side at (-5, 0)
+            KT::BuildHSeg( { Millimeter2iu( -10 ), Millimeter2iu( 0 ) }, Millimeter2iu( 5 ) ),
+            Millimeter2iu( 0 ), // 2D segment
+            Millimeter2iu( 0 ), // intersect
+    } );
+
+    cases.push_back( {
+            "Square poly -> 2D seg (end cap is nearest)", square_10mm_0_0,
+            KT::BuildHSeg( { Millimeter2iu( -20 ), Millimeter2iu( 0 ) }, Millimeter2iu( 10 ) ),
+            Millimeter2iu( 2 ), // 2D segment, 1mm cap radius
+            Millimeter2iu( 4 ), // 4mm short, 5mm to wire end, -1mm radius
+    } );
+
+    return cases;
+};
+
+/**
+ * Check segment distances
+ */
+BOOST_AUTO_TEST_CASE( SegDistance )
+{
+    for( const auto& c : GetSPSSegDistCases() )
+    {
+        BOOST_TEST_CONTEXT( c.m_case_name )
+        {
+            SHAPE_POLY_SET polyset = c.m_polyset;
+
+            int dist = polyset.Distance( c.m_seg, c.m_seg_width );
+
+            // right answer?
+            BOOST_CHECK_EQUAL( dist, c.m_exp_dist );
+        }
+    }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/qa/qa_utils/CMakeLists.txt b/qa/qa_utils/CMakeLists.txt
index bc04b72ca..1e8bcffe2 100644
--- a/qa/qa_utils/CMakeLists.txt
+++ b/qa/qa_utils/CMakeLists.txt
@@ -22,6 +22,10 @@
 set( QA_UTIL_COMMON_SRC
     stdstream_line_reader.cpp
     utility_program.cpp
+
+    geometry/line_chain_construction.cpp
+    geometry/poly_set_construction.cpp
+    geometry/seg_construction.cpp
 )
 
 # A generic library of useful functions for various testing purposes
@@ -37,5 +41,6 @@ target_link_libraries( qa_utils
 )
 
 target_include_directories( qa_utils PUBLIC
+    include
     ${CMAKE_CURRENT_SOURCE_DIR}
 )
\ No newline at end of file
diff --git a/qa/qa_utils/geometry/line_chain_construction.cpp b/qa/qa_utils/geometry/line_chain_construction.cpp
new file mode 100644
index 000000000..56d1b906d
--- /dev/null
+++ b/qa/qa_utils/geometry/line_chain_construction.cpp
@@ -0,0 +1,49 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <qa_utils/geometry/line_chain_construction.h>
+
+namespace KI_TEST
+{
+
+SHAPE_LINE_CHAIN BuildRectChain( const VECTOR2I& aSize, const VECTOR2I& aCentre )
+{
+    const std::vector<VECTOR2I> pts = {
+        { aCentre.x - aSize.x / 2, aCentre.y - aSize.y / 2 },
+        { aCentre.x - aSize.x / 2, aCentre.y + aSize.y / 2 },
+        { aCentre.x + aSize.x / 2, aCentre.y + aSize.y / 2 },
+        { aCentre.x + aSize.x / 2, aCentre.y - aSize.y / 2 },
+    };
+
+    SHAPE_LINE_CHAIN chain( pts.data(), pts.size() );
+    chain.SetClosed( true );
+
+    return chain;
+}
+
+SHAPE_LINE_CHAIN BuildSquareChain( int aSize, const VECTOR2I& aCentre )
+{
+    return BuildRectChain( { aSize, aSize }, aCentre );
+}
+
+} // namespace KI_TEST
\ No newline at end of file
diff --git a/qa/qa_utils/geometry/poly_set_construction.cpp b/qa/qa_utils/geometry/poly_set_construction.cpp
new file mode 100644
index 000000000..ab2326b7c
--- /dev/null
+++ b/qa/qa_utils/geometry/poly_set_construction.cpp
@@ -0,0 +1,54 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <qa_utils/geometry/poly_set_construction.h>
+
+#include <qa_utils/geometry/line_chain_construction.h>
+
+namespace KI_TEST
+{
+
+SHAPE_POLY_SET BuildPolyset( const std::vector<SHAPE_LINE_CHAIN>& aOutlines )
+{
+    SHAPE_POLY_SET polyset;
+
+    for( const auto& outline : aOutlines )
+    {
+        polyset.AddOutline( outline );
+    }
+
+    return polyset;
+}
+
+
+SHAPE_POLY_SET BuildHollowSquare( int aOuterSize, int aInnerSize, const VECTOR2I& aCentre )
+{
+    SHAPE_POLY_SET polyset;
+
+    polyset.AddOutline( BuildRectChain( { aOuterSize, aOuterSize }, aCentre ) );
+    polyset.AddHole( BuildRectChain( { aInnerSize, aInnerSize }, aCentre ) );
+
+    return polyset;
+}
+
+} // namespace KI_TEST
\ No newline at end of file
diff --git a/qa/qa_utils/geometry/seg_construction.cpp b/qa/qa_utils/geometry/seg_construction.cpp
new file mode 100644
index 000000000..bf77eb9d6
--- /dev/null
+++ b/qa/qa_utils/geometry/seg_construction.cpp
@@ -0,0 +1,39 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <qa_utils/geometry/seg_construction.h>
+
+namespace KI_TEST
+{
+
+SEG BuildHSeg( const VECTOR2I& aStart, int aLength )
+{
+    return SEG{ { aStart.x, aStart.y }, { aStart.x + aLength, aStart.y } };
+}
+
+SEG BuildVSeg( const VECTOR2I& aStart, int aLength )
+{
+    return SEG{ { aStart.x, aStart.y }, { aStart.x, aStart.y + aLength } };
+}
+
+} // namespace KI_TEST
\ No newline at end of file
diff --git a/qa/qa_utils/include/qa_utils/geometry/line_chain_construction.h b/qa/qa_utils/include/qa_utils/geometry/line_chain_construction.h
new file mode 100644
index 000000000..ef35b0541
--- /dev/null
+++ b/qa/qa_utils/include/qa_utils/geometry/line_chain_construction.h
@@ -0,0 +1,56 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+/**
+ * @file
+ * Utilities for creating useful line chain idioms commonly founds in
+ * QA utilities and tests
+ */
+
+#ifndef QA_UTILS_GEOMETRY_LINE_CHAIN_CONSTRUCTION__H
+#define QA_UTILS_GEOMETRY_LINE_CHAIN_CONSTRUCTION__H
+
+#include <geometry/shape_line_chain.h>
+
+namespace KI_TEST
+{
+
+/**
+ * Builds a rectangular #SHAPE_LINE_CHAIN of a certain size at a certain centre
+ * @param  aSize   the rectangle size
+ * @param  aCentre centre of the rectangle
+ * @return         a closed line chain of the rectangle
+ */
+SHAPE_LINE_CHAIN BuildRectChain( const VECTOR2I& aSize, const VECTOR2I& aCentre = { 0, 0 } );
+
+/**
+ * Builds a square #SHAPE_LINE_CHAIN of a certain size at a certain centre
+ * @param  aSize   the square size (x == y)
+ * @param  aCentre centre of the square
+ * @return         a closed line chain of the square
+ */
+SHAPE_LINE_CHAIN BuildSquareChain( int aSize, const VECTOR2I& aCentre = { 0, 0 } );
+
+} // namespace KI_TEST
+
+#endif // QA_UTILS_GEOMETRY_LINE_CHAIN_CONSTRUCTION__H
\ No newline at end of file
diff --git a/qa/qa_utils/include/qa_utils/geometry/poly_set_construction.h b/qa/qa_utils/include/qa_utils/geometry/poly_set_construction.h
new file mode 100644
index 000000000..71a67a2e4
--- /dev/null
+++ b/qa/qa_utils/include/qa_utils/geometry/poly_set_construction.h
@@ -0,0 +1,59 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+/**
+ * @file
+ * Utilities for creating useful polygon shapes that are commonly
+ * found in QA utilities and tests.
+ */
+
+#ifndef QA_UTILS_GEOMETRY_POLY_SET_CONSTRUCTION__H
+#define QA_UTILS_GEOMETRY_POLY_SET_CONSTRUCTION__H
+
+#include <geometry/shape_poly_set.h>
+
+#include <qa_utils/geometry/line_chain_construction.h>
+
+namespace KI_TEST
+{
+
+/**
+ * Construct a #SHAPE_POLY_SET from a list of points for each of outlines
+ * (no holes)
+ */
+SHAPE_POLY_SET BuildPolyset( const std::vector<SHAPE_LINE_CHAIN>& aOutlines );
+
+/**
+ * Build a #SHAPE_POLY_SET in the shape of a square outline, with a square
+ * hole, both centred at the given point.
+ * @param  aOuterSize the size (x and y) of the outer square
+ * @param  aInnerSize the size (x and y) of the hole
+ * @param  aCentre    the centre point of both squares (default: origin)
+ * @return            a SHAPE_POLY_SET of the desired shape
+ */
+SHAPE_POLY_SET BuildHollowSquare(
+        int aOuterSize, int aInnerSize, const VECTOR2I& aCentre = { 0, 0 } );
+
+} // namespace KI_TEST
+
+#endif // QA_UTILS_GEOMETRY_POLY_SET_CONSTRUCTION__H
\ No newline at end of file
diff --git a/qa/qa_utils/include/qa_utils/geometry/seg_construction.h b/qa/qa_utils/include/qa_utils/geometry/seg_construction.h
new file mode 100644
index 000000000..f2c4b1b1c
--- /dev/null
+++ b/qa/qa_utils/include/qa_utils/geometry/seg_construction.h
@@ -0,0 +1,56 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+/**
+ * @file
+ * Utilities for creating useful line chain idioms commonly founds in
+ * QA utilities and tests
+ */
+
+#ifndef QA_UTILS_GEOMETRY_SEG_CONSTRUCTION__H
+#define QA_UTILS_GEOMETRY_SEG_CONSTRUCTION__H
+
+#include <geometry/seg.h>
+
+namespace KI_TEST
+{
+
+/**
+ * Build a horizontal segment from a point with a length
+ * @param  aStart  the starting point
+ * @param  aLength the segment length
+ * @return         the resulting segment
+ */
+SEG BuildHSeg( const VECTOR2I& aStart, int aLength );
+
+/**
+ * Build a vertical segment from a point with a length
+ * @param  aStart  the starting point
+ * @param  aLength the segment length
+ * @return         the resulting segment
+ */
+SEG BuildVSeg( const VECTOR2I& aStart, int aLength );
+
+} // namespace KI_TEST
+
+#endif // QA_UTILS_GEOMETRY_SEG_CONSTRUCTION__H
\ No newline at end of file
-- 
2.20.1


Follow ups