1 /* Copyright Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14
15 /** @file Circle.h
16         @author Jukka Jyl�nki
17         @brief The Circle geometry object. */
18 #pragma once
19
20 #include "../MathGeoLibFwd.h"
21 #include "../Math/float3.h"
22
23 #ifdef MATH_ENABLE_STL_SUPPORT
24 #include <vector>
25 #endif
26
27 MATH_BEGIN_NAMESPACE
28
29 /// A two-dimensional circle in 3D space.
30 /** This class represents both a hollow circle (only edge) and a solid circle (disc). */
31 class Circle
32 {
33 public:
34         /// The center position of this circle.
35         vec pos;
36
37         /// The normal direction of this circle. [similarOverload: pos]
38         /** A circle is a two-dimensional object in 3D space. This normal vector (together with the pos member)
39                 specifies the plane in which this circle lies in.
40                 This vector is always normalized. If you assign to this member directly, be sure to only assign normalized vectors. */
41         vec normal;
42
43         /// The radius of the circle. [similarOverload: pos]
44         /** This parameter must be strictly positive to specify a non-degenerate circle. If zero is specified, this circle
45                 is considered to be degenerate.
46                 @see Circle::Circle(). */
47         float r;
48
49         /// The default constructor does not initialize any members of this class.
50         /** This means that the values of the members pos, normal and r are all undefined after creating a new circle using
51                 this default constructor. Remember to assign to them before use.
52                 @see pos, normal, r. */
53         Circle() {}
54
55         /// Constructs a new circle by explicitly specifying the member variables.
56         /** @param center The center point of the circle.
57                 @param normal The direction vector that specifies the orientation of this circle. This vector must be normalized,
58                         this constructor will not normalize the vector for you (for performance reasons).
59                 @param radius The radius of the circle.
60                 @see pos, normal, r. */
61         Circle(const vec &center, const vec &normalfloat radius);
62
63         /// Returns a normalized direction vector to the 'U direction' of the circle.
64         /** This vector lies on the plane of this circle.
65                 The U direction specifies the first basis vector of a local space of this circle. */
66         vec BasisU() const;
67
68         /// Returns a normalized direction vector to the 'V direction' of the circle.
69         /** This vector lies on the plane of this circle.
70                 The U direction specifies the second basis vector of a local space of this circle. */
71         vec BasisV() const;
72
73         /// Returns a point at the edge of this circle.
74         /** @param angleRadians The direction of the point to get. A full circle is generated by the range [0, 2*pi],
75                         but it is ok to pass in values outside this range.
76                 @note This function is equivalent to calling GetPoint(float angleRadians, float d) with a value of d == 1.
77                 @return A point in world space at the edge of this circle. */
78         vec GetPoint(float angleRadians) const;
79
80         /// Returns a point inside this circle.
81         /** @param angleRadians The direction of the point to get. A full circle is generated by the range [0, 2*pi],
82                         but it is ok to pass in values outside this range.
83                 @param d A value in the range [0,1] that specifies the normalzied distance of the point from the center of the circle.
84                         A value of 0 returns the center point of this circle. A value of 1 returns a point at the edge of this circle.
85                         The range of d is not restricted, so it is ok to pass in values larger than 1 to generate a point lying completely
86                         outside this circle. */
87         vec GetPoint(float angleRadians, float dconst;
88
89         /// Returns the center point of this circle.
90         /** This point is also the center of mass for this circle. The functions CenterPoint() and Centroid() are equivalent.
91                 @see pos. */
92         vec CenterPoint() const return pos; }
93         vec Centroid() const return pos; } ///< [similarOverload: CenterPoint]
94
95         /// Computes an extreme point of this Circle/Disc in the given direction.
96         /** An extreme point is a farthest point of this Circle/Disc in the given direction. Given a direction,
97                 this point is not necessarily unique.
98                 @param direction The direction vector of the direction to find the extreme point. This vector may
99                         be unnormalized, but may not be null.
100                 @return An extreme point of this Circle/Disc in the given direction. The returned point is always at
101                         the edge of this Circle. */
102         vec ExtremePoint(const vec &direction) const;
103
104         /// Computes the plane this circle is contained in.
105         /** All the points of this circle lie inside this plane.
106                 @see class Plane. */
107         Plane ContainingPlane() const;
108
109         /// Translates this Circle in world space.
110         /** @param offset The amount of displacement to apply to this Circle, in world space coordinates.
111                 @see Transform(). */
112         void Translate(const vec &offset);
113
114         /// Applies a transformation to this Circle.
115         /** @param transform The transformation to apply to this Circle. This transformation must be
116                 affine, and must contain an orthogonal set of column vectors (may not contain shear or projection).
117                 The transformation can only contain uniform scale, and may not contain mirroring.
118                 @see Translate(), Scale(), classes float3x3, float3x4, float4x4, Quat. */
119         void Transform(const float3x3 &transform);
120         void Transform(const float3x4 &transform);
121         void Transform(const float4x4 &transform);
122         void Transform(const Quat &transform);
123
124         /// Tests if the given point is contained at the edge of this circle.
125         /** @param point The target point to test.
126                 @param maxDistance The epsilon threshold to test the distance against. This effectively turns the circle into a torus
127                         for this test.
128                 @see DistanceToEdge(), DistanceToDisc(), ClosestPointToEdge(), ClosestPointToDisc().
129                 @todo Implement DiscContains(float3/LineSegment/Triangle). */
130         bool EdgeContains(const vec &point, float maxDistance = 1e-6f) const;
131
132         // Returns true if the given point lies inside this filled circle.
133         // @param maxDistance The epsilon threshold to test the distance against.
134 //      bool DiscContains(const vec &point, float maxDistance = 1e-6f) const;
135 //      bool DiscContains(const LineSegment &lineSegment, float maxDistance = 1e-6f) const;
136
137         /// Computes the distance of the given object to the edge of this circle.
138         /** @todo Implement DistanceToEdge(Ray/LineSegment/Line).
139                 @return The distance of the given point to the edge of this circle. If the point is contained on this circle,
140                         the value 0 is returned.
141                 @see DistanceToDisc(), ClosestPointToEdge(), ClosestPointToDisc(). */
142         float DistanceToEdge(const vec &point) const;
143 //      float DistanceToEdge(const Ray &ray, float *d, vec *closestPoint) const;
144 //      float DistanceToEdge(const LineSegment &lineSegment, float *d, vec *closestPoint) const;
145 //      float DistanceToEdge(const Line &line, float *d, vec *closestPoint) const;
146
147         /// Computes the distance of the given object to this disc (filled circle).
148         /** If the point is contained inside this disc, the value 0 is returned.
149                 @see DistanceToEdge(), ClosestPointToEdge(), ClosestPointToDisc().
150                 @todo Implement DistanceToDisc(Ray/LineSegment/Line). */
151         float DistanceToDisc(const vec &point) const;
152 /*
153         float DistanceToDisc(const Ray &ray, float *d, vec *closestPoint) const;
154         float DistanceToDisc(const LineSegment &lineSegment, float *d, vec *closestPoint) const;
155         float DistanceToDisc(const Line &line, float *d, vec *closestPoint) const;
156 */
157         /// Computes the closest point on the edge of this circle to the given point.
158         /** @todo Implement ClosestPointToEdge(Ray/LineSegment/Line).
159                 @see DistanceToEdge(), DistanceToDisc(), ClosestPointToDisc(). */
160         vec ClosestPointToEdge(const vec &point) const;
161 //      vec ClosestPointToEdge(const Ray &ray, float *d) const;
162 //      vec ClosestPointToEdge(const LineSegment &lineSegment, float *d) const;
163 //      vec ClosestPointToEdge(const Line &line, float *d) const;
164
165         /// Computes the closest point on the disc of this circle to the given object.
166         /** @todo Implement ClosestPointToDisc(Ray/LineSegment/Line).
167                 @see DistanceToEdge(), DistanceToDisc(), ClosestPointToEdge(). */
168         vec ClosestPointToDisc(const vec &point) const;
169
170         /// Tests this circle for an intersection against the given plane.
171         /** @note For Circle-Plane intersection, there is no need to differentiate between a hollow or a filled circle (disc).
172                 @return The number of intersection points found for this circle and the given plane.
173                 @see IntersectsDisc(). */
174         int Intersects(const Plane &plane, vec *pt1, vec *pt2) const;
175         int Intersects(const Plane &plane) const;
176
177         /// Tests this disc for an intersection against the given object.
178         /** @see Intersects(). */
179         bool IntersectsDisc(const Line &line) const;
180         bool IntersectsDisc(const LineSegment &lineSegment) const;
181         bool IntersectsDisc(const Ray &ray) const;
182
183 #ifdef MATH_ENABLE_STL_SUPPORT
184         /// Tests if this circle intersects the faces of the given OBB.
185         /** @param obb The bounding box to test against. This box is treated as "hollow", i.e. only the faces of the OBB are considered to be
186                         a part of the OBB.
187                 @return A vector that contains all the detected points of intersection for this circle and the given OBB. If the circle is fully
188                         contained inside the OBB, or is fully outside the OBB, no intersection occurs, and the returned vector has zero elements.
189                 @see Intersects(), IntersectsDisc(). */
190         VecArray IntersectsFaces(const OBB &obb) const;
191
192         VecArray IntersectsFaces(const AABB &aabb) const;
193
194         /// Returns a human-readable representation of this circle. Most useful for debugging purposes.
195         /** The returned string specifies the center position, normal direction and the radius of this circle. */
196         std::string ToString() const;
197 #endif
198
199 #ifdef MATH_QT_INTEROP
200         operator QString() const return toString(); }
201         QString toString() const return QString::fromStdString(ToString()); }
202 #endif
203 };
204
205 Circle operator *(const float3x3 &transform, const Circle &circle);
206 Circle operator *(const float3x4 &transform, const Circle &circle);
207 Circle operator *(const float4x4 &transform, const Circle &circle);
208 Circle operator *(const Quat &transform, const Circle &circle);
209
210 #ifdef MATH_QT_INTEROP
211 Q_DECLARE_METATYPE(Circle)
212 Q_DECLARE_METATYPE(Circle*)
213 #endif
214
215 #ifdef MATH_ENABLE_STL_SUPPORT
216 std::ostream &operator <<(std::ostream &o, const Circle &circle);
217 #endif
218
219 MATH_END_NAMESPACE

Go back to previous page