// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2020 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include // The circle containing the arc is represented as |X-C| = R where C is the // center and R is the radius. The arc is defined by two points end0 and // end1 on the circle so that end1 is obtained from end0 by traversing // counterclockwise. The application is responsible for ensuring that end0 // and end1 are on the circle and that they are properly ordered. namespace WwiseGTE { template class Arc2 { public: // Construction and destruction. The default constructor sets the // center to (0,0), radius to 1, end0 to (1,0), and end1 to (0,1). Arc2() : center(Vector2::Zero()), radius((Real)1) { end[0] = Vector2::Unit(0); end[1] = Vector2::Unit(1); } Arc2(Vector2 const& inCenter, Real inRadius, Vector2const& inEnd0, Vector2const& inEnd1) : center(inCenter), radius(inRadius) { end[0] = inEnd0; end[1] = inEnd1; } // Test whether P is on the arc. The application must ensure that P // is on the circle; that is, |P-C| = R. This test works for any // angle between B-C and A-C, not just those between 0 and pi // radians. bool Contains(Vector2 const& p) const { // Assert: |P-C| = R where P is the input point, C is the circle // center and R is the circle radius. For P to be on the arc from // A to B, it must be on the side of the plane containing A with // normal N = Perp(B-A) where Perp(u,v) = (v,-u). Vector2 diffPE0 = p - end[0]; Vector2 diffE1E0 = end[1] - end[0]; Real dotPerp = DotPerp(diffPE0, diffE1E0); return dotPerp >= (Real)0; } Vector2 center; Real radius; std::array, 2> end; public: // Comparisons to support sorted containers. bool operator==(Arc2 const& arc) const { return center == arc.center && radius == arc.radius && end[0] == arc.end[0] && end[1] == arc.end[1]; } bool operator!=(Arc2 const& arc) const { return !operator==(arc); } bool operator< (Arc2 const& arc) const { if (center < arc.center) { return true; } if (center > arc.center) { return false; } if (radius < arc.radius) { return true; } if (radius > arc.radius) { return false; } if (end[0] < arc.end[0]) { return true; } if (end[0] > arc.end[0]) { return false; } return end[1] < arc.end[1]; } bool operator<=(Arc2 const& arc) const { return !arc.operator<(*this); } bool operator> (Arc2 const& arc) const { return arc.operator<(*this); } bool operator>=(Arc2 const& arc) const { return !operator<(arc); } }; }