#include <Quadrics.hpp>
Static Public Member Functions | |
| static double | cube (double x) |
| static double | cube (double x0, double x1) |
| static int | distinctIntersectionsCone (Vec r0, Vec k, double cosTheta, double &x1, double &x2) |
| static int | distinctIntersectionsCylinder (Vec r0, Vec k, double kq2, double radius, double &x1, double &x2) |
| static int | distinctIntersectionsSphere (Vec r0, Vec k, double radius, double &x1, double &x2) |
| static int | distinctSolutions (double a, double b, double c, double &x1, double &x2) |
| static int | distinctSolutions (double b, double c, double &x1, double &x2) |
| static bool | doSpheresOverlap (Vec center1, double radius1, Vec center2, double radius2) |
| static double | firstIntersectionCone (Vec r0, Vec k, double cosTheta) |
| static double | firstIntersectionCylinder (Vec r0, Vec k, double kq2, double radius) |
| static double | firstIntersectionSphere (Vec r0, Vec k, double radius) |
| static double | firstIntersectionSphere (Vec r0, Vec k, Vec center, double radius) |
| static double | intersectionHorizontalPlane (Vec r0, Vec k, double zPlane) |
| static double | intersectionMeridionalPlane (Vec r0, Vec k, double sinPhi, double cosPhi) |
| static bool | isPositionInSphere (Vec p, Vec center, double radius) |
| static bool | isSphereInShell (Vec center, double radius, double rmin, double rmax) |
| static bool | isSphericalCellInSphere (double rmin, double rmax, double thetaMin, double thetaMax, double phiMin, double phiMax, Vec center, double radius) |
| static double | smallestPositiveSolution (double a, double b, double c) |
| static double | smallestPositiveSolution (double b, double c) |
| static bool | sphereIntersectsPlane (double sphereRadius, double outOfPlaneCenterCoord, double &circleRadius) |
| static double | sqrtDiffSquares (double a, double b) |
| static double | square (double x) |
| static double | volumeSphere (double radius) |
Static Private Member Functions | |
| static double | minCosineOverInterval (double amp, double phase, double tlo, double thi) |
Static Private Attributes | |
| static constexpr double | EPS |
This static class offers a collection of low-level geometric building blocks: raising a value to the second or third power, solving a quadratic equation, and a set of elementary sphere/plane tests and ray/quadric intersections centered on or relative to the origin.
All implementations are provided inline in the header.
|
inlinestatic |
This function returns \(x^3\).
|
inlinestatic |
This function returns \(x_1^3 - x_0^3 = (x_1-x_0)(x_1^2 + x_1 x_0 + x_0^2)\). The second form is used because it is more numerically stable.
|
inlinestatic |
This function determines the solutions of the intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the double cone described in firstIntersectionCone(), i.e. the two-root counterpart of that function: it solves the same defining equation and quadratic, but through distinctSolutions() rather than smallestPositiveSolution(), so that both roots (or the single root of a linearly-degenerate case) are returned rather than only the smallest positive one. The degenerate cone with zero cosine (i.e. the xy-plane) is handled as a special case, with at most one solution, obtained only if the ray is not parallel to it. The return value has the same meaning as for distinctSolutions(): 2 for two distinct solutions (stored in x1 and x2), 1 for a single solution (stored in x1), or 0 for none.
|
inlinestatic |
This function determines the solutions of the intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the infinite cylinder described in firstIntersectionCylinder(), i.e. the two-root counterpart of that function: it solves the same defining equation and quadratic, but through distinctSolutions() rather than smallestPositiveSolution(), so that both roots are returned rather than only the smallest positive one; kq2 has the same meaning as there. The return value has the same meaning as for distinctSolutions(): 2 for two distinct solutions (stored in x1 and x2), or 0 if there are none, which includes the case where the ray is parallel to the z-axis (kq2 is zero).
|
inlinestatic |
This function determines the solutions of the intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the sphere described in firstIntersectionSphere(), i.e. the two-root counterpart of that function: it solves the same defining equation and quadratic, but through distinctSolutions() rather than smallestPositiveSolution(), so that both roots are returned rather than only the smallest positive one. The return value has the same meaning as for distinctSolutions(): 2 for two distinct solutions (stored in x1 and x2), or 0 if there are none.
|
inlinestatic |
This function determines the solutions of \(ax^2 + 2bx + c = 0\). If there are two distinct real solutions, they are stored in the arguments x1 and x2, and the function returns 2. If the equation degenerates to a linear equation with a single finite solution, this solution is stored in the argument x1. In that case, x2 remains unchanged and the function returns 1. Otherwise, i.e. if there are no real solutions or the non-generate quadratic equation has two identical solutions, x1 and x2 remain unchanged, and the function returns 0.
|
inlinestatic |
This function determines the solutions of \(x^2 + 2bx + c = 0\). If there are two distinct real solutions, they are stored in the arguments x1 and x2, and the function returns 2. Otherwise, i.e. if there are no real solutions or there is just one real solution, x1 and x2 remain unchanged, and the function returns 0.
Evaluating \(-b \pm \sqrt{b^2-c}\) directly for both roots would lose precision through catastrophic cancellation whenever the two terms nearly cancel for one of the roots. To avoid this, only the root for which \(-b\) and the square root have the same sign – so that they add rather than cancel – is evaluated directly: \(-b-\sqrt{b^2-c}\) if \(b>0\) (since \(-b\) is then negative), or \(-b+\sqrt{b^2-c}\) otherwise. The other root is then obtained from Vieta's formula \(x_1 x_2 = c\).
|
inlinestatic |
This function returns true if the specified spheres overlap or touch, and false otherwise.
This function returns the distance to the first intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the double cone, centered on the origin and aligned with the z-axis, that has the given cosine of its opening angle, or zero if there is no intersection ahead along the ray. The degenerate cone with zero cosine (i.e. the xy-plane) is handled as a special case.
Substituting \({\bf{p}}(s) = {\bf{r}}_0 + s\hat{\bf{k}}\) into the cone's defining equation \(\cos^2\theta\,|{\bf{p}}|^2 = p_z^2\) gives the quadratic
\[ (\cos^2\theta - k_z^2)\,s^2 + 2s\,(\cos^2\theta\,({\bf{r}}_0\cdot\hat{\bf{k}}) - r_{0,z}\,k_z) + (\cos^2\theta\,r_0^2 - r_{0,z}^2) = 0, \]
whose smallest positive solution, if any, is the returned distance.
|
inlinestatic |
This function returns the distance to the first intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the infinite cylinder of given radius, centered on and aligned with the z-axis, or zero if there is no intersection ahead along the ray (either no real intersection, both intersections lie behind the ray's origin, or the ray direction is parallel to the z-axis). The squared length \(k_x^2+k_y^2\) of the projection of \(\hat{\bf{k}}\) onto the xy-plane is passed in as kq2 rather than recomputed, because the caller typically needs the first intersection with several cylinders of different radii for the same ray, all sharing the same kq2.
Substituting \({\bf{p}}(s) = {\bf{r}}_0 + s\hat{\bf{k}}\) into the cylinder's defining equation \(p_x^2+p_y^2 = \text{radius}^2\) gives the quadratic
\[ (k_x^2+k_y^2)\,s^2 + 2s\,(r_{0,x}k_x + r_{0,y}k_y) + (r_{0,x}^2 + r_{0,y}^2 - \text{radius}^2) = 0, \]
whose smallest positive solution, if any, is the returned distance; kq2 is the leading coefficient \(k_x^2+k_y^2\).
This function returns the distance to the first intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the sphere of given radius centered at the origin, or zero if there is no intersection ahead along the ray (either no real intersection, or both intersections lie behind the ray's origin).
Substituting \({\bf{p}}(s) = {\bf{r}}_0 + s\hat{\bf{k}}\) into the sphere's defining equation \(|{\bf{p}}|^2 = \text{radius}^2\) gives the quadratic
\[ s^2 + 2s\, ({\bf{r}}_0\cdot\hat{\bf{k}}) + (r_0^2 - \text{radius}^2) = 0, \]
whose smallest positive solution, if any, is the returned distance.
This function returns the distance to the first intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the sphere of given center and radius, or zero if there is no intersection ahead along the ray. This is the arbitrary-center counterpart of the other firstIntersectionSphere() overload, obtained by translating the ray so that the sphere's center coincides with the origin – i.e. by substituting \({\bf{r}}_0 - \text{center}\) for \({\bf{r}}_0\) in that overload's defining equation.
This function returns the distance to the intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the horizontal plane, perpendicular to the z-axis, at the given z coordinate, or zero if the ray direction is parallel to the plane.
Substituting \({\bf{p}}(s) = {\bf{r}}_0 + s\hat{\bf{k}}\) into the plane's defining equation \(p_z = z_\text{plane}\) and solving for \(s\) gives
\[ s = \frac{z_\text{plane} - r_{0,z}}{k_z}. \]
|
inlinestatic |
This function returns the distance to the intersection of the ray \(({\bf{r}}_0, \hat{\bf{k}})\) with the meridional half-plane, through the origin and the z-axis, at the azimuth with given sine and cosine, or zero if the ray direction is parallel to the plane.
Substituting \({\bf{p}}(s) = {\bf{r}}_0 + s\hat{\bf{k}}\) into the plane's defining equation \(p_x\sin\varphi - p_y\cos\varphi = 0\) and solving for \(s\) gives
\[ s = -\frac{r_{0,x}\sin\varphi - r_{0,y}\cos\varphi}{k_x\sin\varphi - k_y\cos\varphi}. \]
This function returns true if the given position is inside the sphere with given center and radius, and false otherwise (a position exactly on the sphere's surface counts as inside).
|
inlinestatic |
This function returns true if the sphere with given center and radius is fully inside the spherical shell, centered on the origin, with given inner and outer radii (no straggling nor touching allowed).
|
inlinestatic |
This function returns true if the "spherical box" cell – the region with radius between rmin and rmax, polar angle (colatitude) between thetaMin and thetaMax, and azimuth between phiMin and phiMax, all measured around the origin – lies fully inside the sphere with the given center and radius (touching allowed).
The radial extent is handled exactly: for a fixed direction, the squared distance to a point at radius r is a convex function of r, so its maximum over [rmin,rmax] is always attained at one of the two endpoints, regardless of curvature. What remains is finding the direction within the cell's angular box that lies farthest, in projection, from the sphere's center. Because the azimuthal term of that projection is scaled by sin(theta), which is nonnegative throughout the box, the farthest azimuth can be found first, independently of theta, and the result then feeds a second, one-dimensional search over theta. Each of those two searches reduces to checking whether the antipodal direction falls within the relevant bound, and otherwise evaluating the two boundary values – never a full numerical optimization.
|
inlinestatic |
This function returns the smallest positive solution of \(ax^2 + 2bx + c = 0\), or zero if there is no positive solution. If the equation degenerates to a linear equation, this equation is solved instead.
|
inlinestatic |
This function returns the smallest positive solution of \(x^2 + 2bx + c = 0\), or zero if there is no positive solution.
As in distinctSolutions(), only the root for which \(-b\) and \(\sqrt{b^2-c}\) have the same sign is evaluated directly – \(-b-\sqrt{b^2-c}\) if \(b>0\), or \(-b+\sqrt{b^2-c}\) if \(b<0\) – avoiding the catastrophic cancellation that evaluating both roots directly would incur; the other root, when it is needed, is obtained from it through Vieta's formula \(x_1 x_2 = c\) rather than by evaluating the numerically unsafe combination directly.
|
inlinestatic |
This function determines the circle formed by intersecting a sphere (given its radius and its center's coordinate along the axis perpendicular to the plane) with a coordinate plane through the origin. It returns true and sets circleRadius if the sphere reaches the plane; it returns false (leaving circleRadius unchanged) if it doesn't. The circle's center in the plane is simply the sphere center's own two in-plane coordinates, so the caller already has those and doesn't need them returned here.
By the Pythagorean relation between the sphere's radius \(R\), its center's out-of-plane offset \(d\), and the radius \(\rho\) of the circle cut out of the plane,
\[ \rho = \sqrt{R^2 - d^2}, \]
which is real, and thus returned, only if \(|d|<R\).
|
inlinestatic |
This function returns \(\sqrt{a^2-b^2}\) for \(|a|\ge|b|\), computed as \(\sqrt{(a-b)(a+b)}\) rather than directly from \(a^2-b^2\), to avoid the loss of precision that direct evaluation would incur through catastrophic cancellation when \(|a|\) and \(|b|\) are close. The argument to the square root is clamped to zero in case rounding error would otherwise make it (slightly) negative even though the exact value is nonnegative.
|
inlinestatic |
This function returns \(x^2\).
|
inlinestatic |
This function returns the volume of a sphere with given radius, \(V = \frac{4}{3}\pi r^3\).