Coverage Report

Created: 2025-10-12 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/include/geos/algorithm/MinimumDiameter.h
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2023 Paul Ramsey <pramsey@cleverelephant.ca>
7
 * Copyright (C) 2005-2006 Refractions Research Inc.
8
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
9
 *
10
 * This is free software; you can redistribute and/or modify it under
11
 * the terms of the GNU Lesser General Public Licence as published
12
 * by the Free Software Foundation.
13
 * See the COPYING file for more information.
14
 *
15
 **********************************************************************/
16
17
#pragma once
18
19
#include <geos/geom/Coordinate.h>
20
#include <geos/geom/LineSegment.h>
21
22
#include <memory>
23
#include <geos/export.h>
24
25
// Forward declarations
26
namespace geos {
27
namespace geom {
28
class GeometryFactory;
29
class Geometry;
30
class LineString;
31
class CoordinateSequence;
32
}
33
}
34
35
36
namespace geos {
37
namespace algorithm { // geos::algorithm
38
39
/** \brief
40
 * Computes the minimum diameter of a geom::Geometry
41
 *
42
 * The minimum diameter is defined to be the width of the smallest band that
43
 * contains the geometry, where a band is a strip of the plane defined
44
 * by two parallel lines. This can be thought of as the smallest hole
45
 * that the geometry can be moved through, with a single rotation.
46
 *
47
 * The first step in the algorithm is computing the convex hull of the Geometry.
48
 * If the input Geometry is known to be convex, a hint can be supplied to
49
 * avoid this computation.
50
 *
51
 * This class can also be used to compute a line segment representing
52
 * the minimum diameter, the supporting line segment of the minimum diameter,
53
 * and a minimum-width rectangle of the input geometry.
54
 * This rectangle will have width equal to the minimum diameter, and have
55
 * one side parallel to the supporting segment.
56
 *
57
 * In degenerate cases the rectangle may be a LineString or a Point.
58
 * (Note that this may not be the enclosing rectangle with minimum area;
59
 * use MinimumAreaRectangle to compute this.)
60
 *
61
 * @see ConvexHull
62
 * @see MinimumAreaRectangle
63
 */
64
class GEOS_DLL MinimumDiameter {
65
private:
66
    const geom::Geometry* inputGeom;
67
    bool isConvex;
68
69
    std::unique_ptr<geom::CoordinateSequence> convexHullPts;
70
71
    geom::LineSegment minBaseSeg;
72
    geom::Coordinate minWidthPt;
73
    std::size_t minPtIndex;
74
    double minWidth;
75
    void computeMinimumDiameter();
76
    void computeWidthConvex(const geom::Geometry* geom);
77
78
    /**
79
     * Compute the width information for a ring of Coordinate.
80
     * Leaves the width information in the instance variables.
81
     *
82
     * @param pts
83
     * @return
84
     */
85
    void computeConvexRingMinDiameter(const geom::CoordinateSequence* pts);
86
87
    unsigned int findMaxPerpDistance(const geom::CoordinateSequence* pts,
88
                                     const geom::LineSegment* seg, unsigned int startIndex);
89
90
    static unsigned int getNextIndex(const geom::CoordinateSequence* pts,
91
                                     unsigned int index);
92
93
    static double computeC(double a, double b, const geom::Coordinate& p);
94
95
    static geom::LineSegment computeSegmentForLine(double a, double b, double c);
96
97
    static std::unique_ptr<geom::Geometry> computeMaximumLine(
98
                        const geom::CoordinateSequence* pts,
99
                        const geom::GeometryFactory* factory);
100
101
public:
102
0
    ~MinimumDiameter() = default;
103
104
    /** \brief
105
     * Compute a minimum diameter for a given [Geometry](@ref geom::Geometry).
106
     *
107
     * @param newInputGeom a Geometry
108
     */
109
    MinimumDiameter(const geom::Geometry* newInputGeom);
110
111
    /** \brief
112
     * Compute a minimum diameter for a given Geometry,
113
     * with a hint if the Geometry is convex
114
     * (e.g. a convex Polygon or LinearRing,
115
     * or a two-point LineString, or a Point).
116
     *
117
     * @param newInputGeom a Geometry which is convex
118
     * @param newIsConvex `true` if the input geometry is convex
119
     */
120
    MinimumDiameter(const geom::Geometry* newInputGeom,
121
                    const bool newIsConvex);
122
123
    /** \brief
124
     * Gets the length of the minimum diameter of the input Geometry.
125
     *
126
     * @return the length of the minimum diameter
127
     */
128
    double getLength();
129
130
    /** \brief
131
     * Gets the geom::Coordinate forming one end of the minimum diameter.
132
     *
133
     * @return a coordinate forming one end of the minimum diameter
134
     */
135
    const geom::Coordinate& getWidthCoordinate();
136
137
    /** \brief
138
     * Gets the segment forming the base of the minimum diameter.
139
     *
140
     * @return the segment forming the base of the minimum diameter
141
     */
142
    std::unique_ptr<geom::LineString> getSupportingSegment();
143
144
    /** \brief
145
     * Gets a LineString which is a minimum diameter.
146
     *
147
     * @return a LineString which is a minimum diameter
148
     */
149
    std::unique_ptr<geom::LineString> getDiameter();
150
151
    /** \brief
152
     * Gets the rectangular Polygon which encloses the input geometry
153
     * and is based on the minimum diameter supporting segment.
154
     *
155
     * The rectangle has width equal to the minimum diameter, and a longer
156
     * length. If the convex hill of the input is degenerate (a line or point)
157
     * a LineString or Point is returned.
158
     * This is not necessarily the rectangle with minimum area.
159
     * Use MinimumAreaRectangle to compute this.
160
     *
161
     * @return the the minimum-width rectangle enclosing the geometry
162
     * @see MinimumAreaRectangle
163
     */
164
    std::unique_ptr<geom::Geometry> getMinimumRectangle();
165
166
    /** \brief
167
     * Gets the minimum rectangle enclosing a geometry.
168
     *
169
     * @param geom the geometry
170
     * @return a rectangle enclosing the input (or a line or point if degenerate)
171
     * @see MinimumAreaRectangle
172
    */
173
    static std::unique_ptr<geom::Geometry> getMinimumRectangle(geom::Geometry* geom);
174
175
    /** \brief
176
     * Gets the length of the minimum diameter enclosing a geometry.
177
     * @param geom the geometry
178
     * @return the length of the minimum diameter of the geometry
179
     */
180
    static std::unique_ptr<geom::Geometry> getMinimumDiameter(geom::Geometry* geom);
181
182
};
183
184
} // namespace geos::algorithm
185
} // namespace geos