Coverage Report

Created: 2026-09-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/geom/Triangle.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
7
 *
8
 * This is free software; you can redistribute and/or modify it under
9
 * the terms of the GNU Lesser General Public Licence as published
10
 * by the Free Software Foundation.
11
 * See the COPYING file for more information.
12
 *
13
 **********************************************************************/
14
15
#include <geos/geom/Triangle.h>
16
#include <geos/geom/Coordinate.h>
17
#include <geos/algorithm/CGAlgorithmsDD.h>
18
#include <geos/algorithm/Orientation.h>
19
#include <geos/algorithm/Angle.h>
20
21
using geos::algorithm::Angle;
22
using geos::algorithm::Orientation;
23
24
namespace geos {
25
namespace geom { // geos::geom
26
27
28
bool
29
Triangle::isIsoceles()
30
0
{
31
0
    double len0 = p1.distance(p2);
32
0
    double len1 = p0.distance(p2);
33
0
    double len2 = p0.distance(p1);
34
0
    if (len0 == len1 || len1 == len2 || len2 == len0)
35
0
        return true;
36
0
    else
37
0
        return false;
38
0
}
39
40
void
41
Triangle::inCentre(CoordinateXY& result)
42
0
{
43
    // the lengths of the sides, labelled by their opposite vertex
44
0
    double len0 = p1.distance(p2);
45
0
    double len1 = p0.distance(p2);
46
0
    double len2 = p0.distance(p1);
47
0
    double circum = len0 + len1 + len2;
48
0
    double inCentreX = (len0 * p0.x + len1 * p1.x + len2 * p2.x)  / circum;
49
0
    double inCentreY = (len0 * p0.y + len1 * p1.y + len2 * p2.y)  / circum;
50
51
0
    result = CoordinateXY(inCentreX, inCentreY);
52
0
}
53
54
55
CoordinateXY
56
Triangle::inCentre(const CoordinateXY& p0,
57
        const CoordinateXY& p1,
58
        const CoordinateXY& p2)
59
0
{
60
0
    Triangle tri(p0, p1, p2);
61
0
    CoordinateXY result;
62
0
    tri.inCentre(result);
63
0
    return result;
64
0
}
65
66
67
void
68
Triangle::circumcentre(CoordinateXY& result)
69
0
{
70
0
    double cx = p2.x;
71
0
    double cy = p2.y;
72
0
    double ax = p0.x - cx;
73
0
    double ay = p0.y - cy;
74
0
    double bx = p1.x - cx;
75
0
    double by = p1.y - cy;
76
77
0
    double denom = 2 * det(ax, ay, bx, by);
78
0
    double numx = det(ay, ax * ax + ay * ay, by, bx * bx + by * by);
79
0
    double numy = det(ax, ax * ax + ay * ay, bx, bx * bx + by * by);
80
81
0
    double ccx = cx - numx / denom;
82
0
    double ccy = cy + numy / denom;
83
84
0
    result = CoordinateXY(ccx, ccy);
85
0
}
86
87
88
double
89
Triangle::circumradius(
90
    const CoordinateXY& a,
91
    const CoordinateXY& b,
92
    const CoordinateXY& c)
93
0
{
94
0
    double A = a.distance(b);
95
0
    double B = b.distance(c);
96
0
    double C = c.distance(a);
97
0
    double triArea = area(a, b, c);
98
0
    if (triArea == 0.0)
99
0
        return std::numeric_limits<double>::infinity();
100
101
0
    return (A * B * C) / (4 * triArea);
102
0
}
103
104
105
void
106
Triangle::circumcentreDD(CoordinateXY& result)
107
0
{
108
0
    result = algorithm::CGAlgorithmsDD::circumcentreDD(p0, p1, p2);
109
0
}
110
111
/* public static */
112
const CoordinateXY
113
Triangle::circumcentre(const CoordinateXY& p0, const CoordinateXY& p1, const CoordinateXY& p2)
114
0
{
115
0
    Triangle t(p0, p1, p2);
116
0
    CoordinateXY c;
117
0
    t.circumcentre(c);
118
0
    return c;
119
0
}
120
121
/* private */
122
double
123
Triangle::det(double m00, double m01, double m10, double m11) const
124
0
{
125
0
    return m00 * m11 - m01 * m10;
126
0
}
127
128
129
/* public static */
130
bool
131
Triangle::isAcute(const CoordinateXY& a, const CoordinateXY& b, const CoordinateXY& c)
132
0
{
133
0
    if (!Angle::isAcute(a, b, c))
134
0
        return false;
135
0
    if (!Angle::isAcute(b, c, a))
136
0
        return false;
137
0
    if (!Angle::isAcute(c, a, b))
138
0
        return false;
139
0
    return true;
140
0
}
141
142
143
/* public static */
144
bool
145
Triangle::isCCW(const CoordinateXY& a, const CoordinateXY& b, const CoordinateXY& c)
146
0
{
147
0
    return Orientation::COUNTERCLOCKWISE == Orientation::index(a, b, c);
148
0
}
149
150
151
/* public static */
152
bool
153
Triangle::intersects(const CoordinateXY& a, const CoordinateXY& b, const CoordinateXY& c, const CoordinateXY& p)
154
0
{
155
0
    int exteriorIndex = isCCW(a, b, c) ?
156
0
        Orientation::CLOCKWISE : Orientation::COUNTERCLOCKWISE;
157
0
    if (exteriorIndex == Orientation::index(a, b, p))
158
0
        return false;
159
0
    if (exteriorIndex == Orientation::index(b, c, p))
160
0
        return false;
161
0
    if (exteriorIndex == Orientation::index(c, a, p))
162
0
        return false;
163
0
    return true;
164
0
}
165
166
167
/* public static */
168
double
169
Triangle::length(const CoordinateXY& a, const CoordinateXY& b, const CoordinateXY& c)
170
0
{
171
0
    return a.distance(b) + b.distance(c) + c.distance(a);
172
0
}
173
174
/* public */
175
double
176
Triangle::length() const
177
0
{
178
0
    return length(p0, p1, p2);
179
0
}
180
181
/* public static */
182
double
183
Triangle::area(const CoordinateXY& a, const CoordinateXY& b, const CoordinateXY& c)
184
0
{
185
0
    return std::abs(((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2);
186
0
}
187
188
/* public */
189
double
190
Triangle::area() const
191
0
{
192
0
    return area(p0, p1, p2);
193
0
}
194
195
/* public static */
196
double
197
Triangle::longestSideLength(const CoordinateXY& a, const CoordinateXY& b, const CoordinateXY& c)
198
0
{
199
0
    double lenAB = a.distance(b);
200
0
    double lenBC = b.distance(c);
201
0
    double lenCA = c.distance(a);
202
0
    double maxLen = lenAB;
203
0
    if (lenBC > maxLen)
204
0
        maxLen = lenBC;
205
0
    if (lenCA > maxLen)
206
0
        maxLen = lenCA;
207
0
    return maxLen;
208
0
}
209
210
211
212
} // namespace geos::geom
213
} // namespace geos