Skip to content

Commit

Permalink
Rename Angle::sinCos -> sinCosSnap
Browse files Browse the repository at this point in the history
  • Loading branch information
mwtoews committed Nov 15, 2023
1 parent 758238d commit dcde8ad
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 14 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
20xx-xx-xx

- New things:
- Add Angle::sinCos to avoid small errors, e.g. with buffer operations (GH-978, Mike Taves)
- Add Angle::sinCosSnap to avoid small errors, e.g. with buffer operations (GH-978, Mike Taves)

- Breaking Changes

Expand Down
9 changes: 5 additions & 4 deletions include/geos/algorithm/Angle.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,21 +218,22 @@ class GEOS_DLL Angle {
static double diff(double ang1, double ang2);

/// \brief
/// Computes both sin and cos of an angle.
/// Computes both sin and cos of an angle, snapping near-zero values
/// to zero.
///
/// The angle does not need to be normalized. Unlike std::sin
/// and std::cos, this method will clip near-zero values to zero
/// and std::cos, this method will snap near-zero values to zero
/// for (e.g.) sin(pi) and cos(pi/2).
///
/// @param ang the input angle (in radians)
/// @param rSin the result of sin(ang)
/// @param rCos the result of cos(ang)
///
static inline void sinCos(const double ang, double& rSin, double& rCos) {
static inline void sinCosSnap(const double ang, double& rSin, double& rCos) {
// calculate both; may be optimized with FSINCOS instruction
rSin = std::sin(ang);
rCos = std::cos(ang);
// clip near zero values
// snap near-zero values
if (std::fabs(rSin) < 5e-16) rSin = 0.0;
if (std::fabs(rCos) < 5e-16) rCos = 0.0;
}
Expand Down
6 changes: 3 additions & 3 deletions src/operation/buffer/OffsetSegmentGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ OffsetSegmentGenerator::addLineEndCap(const Coordinate& p0, const Coordinate& p1
// segment endpoints
Coordinate squareCapSideOffset;
double sinangle, cosangle;
Angle::sinCos(angle, sinangle, cosangle);
Angle::sinCosSnap(angle, sinangle, cosangle);
squareCapSideOffset.x = fabs(distance) * cosangle;
squareCapSideOffset.y = fabs(distance) * sinangle;

Expand Down Expand Up @@ -283,7 +283,7 @@ OffsetSegmentGenerator::addDirectedFillet(const Coordinate& p, double startAngle
double sinangle, cosangle;
Coordinate pt;
for (int i = 0; i < nSegs; i++) {
Angle::sinCos(startAngle + directionFactor * i * angleInc, sinangle, cosangle);
Angle::sinCosSnap(startAngle + directionFactor * i * angleInc, sinangle, cosangle);
pt.x = p.x + radius * cosangle;
pt.y = p.y + radius * sinangle;
segList.addPt(pt);
Expand Down Expand Up @@ -583,7 +583,7 @@ Coordinate
OffsetSegmentGenerator::project(const Coordinate& pt, double d, double dir)
{
double sindir, cosdir;
Angle::sinCos(dir, sindir, cosdir);
Angle::sinCosSnap(dir, sindir, cosdir);
double x = pt.x + d * cosdir;
double y = pt.y + d * sindir;
return Coordinate(x, y);
Expand Down
6 changes: 3 additions & 3 deletions src/util/GeometricShapeFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ GeometricShapeFactory::createCircle()
uint32_t iPt = 0;
double sinang, cosang;
for(uint32_t i = 0; i < nPts; i++) {
Angle::sinCos(i * Angle::PI_TIMES_2 / nPts, sinang, cosang);
Angle::sinCosSnap(i * Angle::PI_TIMES_2 / nPts, sinang, cosang);
double x = xRadius * cosang + centreX;
double y = yRadius * sinang + centreY;
(*pts)[iPt++] = coord(x, y);
Expand Down Expand Up @@ -170,7 +170,7 @@ GeometricShapeFactory::createArc(double startAng, double angExtent)
uint32_t iPt = 0;
double sinang, cosang;
for(uint32_t i = 0; i < nPts; i++) {
Angle::sinCos(startAng + i * angInc, sinang, cosang);
Angle::sinCosSnap(startAng + i * angInc, sinang, cosang);
double x = xRadius * cosang + centreX;
double y = yRadius * sinang + centreY;
(*pts)[iPt++] = coord(x, y);
Expand Down Expand Up @@ -201,7 +201,7 @@ GeometricShapeFactory::createArcPolygon(double startAng, double angExtent)
(*pts)[iPt++] = coord(centreX, centreY);
double sinang, cosang;
for(uint32_t i = 0; i < nPts; i++) {
Angle::sinCos(startAng + i * angInc, sinang, cosang);
Angle::sinCosSnap(startAng + i * angInc, sinang, cosang);
double x = xRadius * cosang + centreX;
double y = yRadius * sinang + centreY;
(*pts)[iPt++] = coord(x, y);
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/algorithm/AngleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void object::test<5>
TOL);
}

// testSinCos()
// testSinCosSnap()
template<>
template<>
void object::test<6>
Expand All @@ -174,7 +174,7 @@ void object::test<6>
for (int angdeg = -720; angdeg <= 720; angdeg++) {
const double ang = Angle::toRadians(angdeg);

Angle::sinCos(ang, rSin, rCos);
Angle::sinCosSnap(ang, rSin, rCos);

double cSin = std::sin(ang);
double cCos = std::cos(ang);
Expand All @@ -192,7 +192,7 @@ void object::test<6>
// use radian increments that don't snap to exact degrees or zero
for (double angrad = -6.3; angrad < 6.3; angrad += 0.013) {

Angle::sinCos(angrad, rSin, rCos);
Angle::sinCosSnap(angrad, rSin, rCos);

ensure_equals(std::to_string(angrad), rSin, std::sin(angrad));
ensure_equals(std::to_string(angrad), rCos, std::cos(angrad));
Expand Down

0 comments on commit dcde8ad

Please sign in to comment.