Mantid
Loading...
Searching...
No Matches
Sphere.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10
11#ifdef ENABLE_OPENCASCADE
12// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
13// used.
14// Undefine it here before we include the headers to avoid a warning
15#ifdef _MSC_VER
16#undef _USE_MATH_DEFINES
17#ifdef M_SQRT1_2
18#undef M_SQRT1_2
19#endif
20#endif
21
23GNU_DIAG_OFF("conversion")
24GNU_DIAG_OFF("cast-qual")
25#include <BRepPrimAPI_MakeSphere.hxx>
26GNU_DIAG_ON("conversion")
27GNU_DIAG_ON("cast-qual")
28#endif
29
30namespace Mantid::Geometry {
32using Kernel::V3D;
33
38Sphere::Sphere() : Sphere({0, 0, 0}, 0.0) {}
39
45Sphere::Sphere(const Kernel::V3D &centre, double radius) : Quadratic(), m_centre{centre}, m_radius{radius} {
46 setBaseEqn();
47}
48
53Sphere *Sphere::doClone() const { return new Sphere(*this); }
54
59std::unique_ptr<Sphere> Sphere::clone() const { return std::unique_ptr<Sphere>(doClone()); }
60
70int Sphere::setSurface(const std::string &Pstr) {
71 std::string Line = Pstr;
72 std::string item;
73 if (!Mantid::Kernel::Strings::section(Line, item) || tolower(item[0]) != 's' || item.length() > 2)
74 return -1;
75
76 std::vector<double> cent(3, 0.0);
77 double R;
78 if (item.length() == 2) // sx/sy/sz
79 {
80 if (tolower(item[1]) != 'o') {
81 const auto pType = static_cast<std::size_t>(tolower(item[1]) - 'x');
82 if (pType > 2)
83 return -3;
84 if (!Mantid::Kernel::Strings::section(Line, cent[pType]))
85 return -4;
86 }
87 } else if (item.length() == 1) {
88 std::size_t index;
89 for (index = 0; index < 3 && Mantid::Kernel::Strings::section(Line, cent[index]); index++)
90 ;
91 if (index != 3)
92 return -5;
93 } else
94 return -6;
96 return -7;
97
98 m_centre = Kernel::V3D(cent[0], cent[1], cent[2]);
99 m_radius = R;
100 setBaseEqn();
101 return 0;
102}
103
112int Sphere::side(const Kernel::V3D &Pt) const
113
114{
115 // MG: Surface test - This does not use onSurface since it would double the
116 // amount of
117 // computation if the object is not on the surface which is most likely
118 const double xdiff(Pt.X() - m_centre.X()), ydiff(Pt.Y() - m_centre.Y()), zdiff(Pt.Z() - m_centre.Z());
119 const double displace = sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff) - m_radius;
120 if (fabs(displace) < Tolerance) {
121 return 0;
122 }
123 return (displace > 0.0) ? 1 : -1;
124}
125
131bool Sphere::onSurface(const Kernel::V3D &Pt) const { return (distance(Pt) <= Tolerance); }
132
139double Sphere::distance(const Kernel::V3D &Pt) const {
140 const Kernel::V3D disp_vec = Pt - m_centre;
141 return std::abs(disp_vec.norm() - m_radius);
142}
143
149 m_centre += Pt;
151}
152
158 m_centre.rotate(MA);
160}
161
166double Sphere::centreToPoint(const V3D &pt) const {
167 const Kernel::V3D displace_vec = pt - m_centre;
168 return displace_vec.norm();
169}
170
176 m_centre = A;
177 setBaseEqn();
178}
179
185 BaseEqn[0] = 1.0; // A x^2
186 BaseEqn[1] = 1.0; // B y^2
187 BaseEqn[2] = 1.0; // C z^2
188 BaseEqn[3] = 0.0; // D xy
189 BaseEqn[4] = 0.0; // E xz
190 BaseEqn[5] = 0.0; // F yz
191 BaseEqn[6] = -2.0 * m_centre[0]; // G x
192 BaseEqn[7] = -2.0 * m_centre[1]; // H y
193 BaseEqn[8] = -2.0 * m_centre[2]; // J z
195}
196
202void Sphere::write(std::ostream &OX) const {
203 std::ostringstream cx;
205 cx.precision(Surface::Nprecision);
206 if (m_centre.distance(Kernel::V3D(0, 0, 0)) < Tolerance) {
207 cx << "so " << m_radius;
208 } else {
209 cx << "s " << m_centre << " " << m_radius;
210 }
212}
213
224void Sphere::getBoundingBox(double &xmax, double &ymax, double &zmax, double &xmin, double &ymin, double &zmin) {
225 xmax = m_centre[0] + m_radius;
226 ymax = m_centre[1] + m_radius;
227 zmax = m_centre[2] + m_radius;
228 xmin = m_centre[0] - m_radius;
229 ymin = m_centre[1] - m_radius;
230 zmin = m_centre[2] - m_radius;
231}
232
233#ifdef ENABLE_OPENCASCADE
234TopoDS_Shape Sphere::createShape() {
235 return BRepPrimAPI_MakeSphere(gp_Pnt(m_centre[0], m_centre[1], m_centre[2]), m_radius).Shape();
236}
237#endif
238
239} // namespace Mantid::Geometry
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#define fabs(x)
Definition: Matrix.cpp:22
double radius
Definition: Rasterize.cpp:31
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Impliments a line.
Definition: Line.h:43
Holds a basic quadratic surface.
Definition: Quadratic.h:29
std::vector< double > BaseEqn
Base equation (as a 10 point vector)
Definition: Quadratic.h:35
void displace(const Kernel::V3D &) override
Apply a general displacement to the surface.
Definition: Quadratic.cpp:244
void rotate(const Kernel::Matrix< double > &) override
Rotate the surface by matrix MX.
Definition: Quadratic.cpp:258
Holds a Sphere as vector form.
Definition: Sphere.h:29
void displace(const Kernel::V3D &) override
Apply a shift of the centre.
Definition: Sphere.cpp:148
void setBaseEqn() override
Generates the quadratic equation.
Definition: Sphere.cpp:184
void rotate(const Kernel::Matrix< double > &) override
Apply a Rotation matrix.
Definition: Sphere.cpp:157
std::unique_ptr< Sphere > clone() const
Makes a clone (implicit virtual copy constructor)
Definition: Sphere.cpp:59
bool onSurface(const Kernel::V3D &) const override
Checks whether the give input point is on the surface.
Definition: Sphere.cpp:131
Kernel::V3D m_centre
Point for centre.
Definition: Sphere.h:31
void write(std::ostream &) const override
Writes the sphere equatation in MCNP format.
Definition: Sphere.cpp:202
double m_radius
Radius of sphere.
Definition: Sphere.h:32
int setSurface(const std::string &) override
Set the sphere defination by input string in MCNP format.
Definition: Sphere.cpp:70
double distance(const Kernel::V3D &) const override
Gets the distance from the sphere to the input point.
Definition: Sphere.cpp:139
void getBoundingBox(double &xmax, double &ymax, double &zmax, double &xmin, double &ymin, double &zmin) override
Calculates the bounding box for the sphere and returns the bounding box values.
Definition: Sphere.cpp:224
Sphere * doClone() const override
Makes a clone (implicit virtual copy constructor)
Definition: Sphere.cpp:53
int side(const Kernel::V3D &) const override
Checks the given input point to be inside, outside or on the surface of sphere.
Definition: Sphere.cpp:112
Sphere()
Default constructor make sphere at the origin radius zero.
Definition: Sphere.cpp:38
double centreToPoint(const Kernel::V3D &pt) const
Compute the distance from the centre of the sphere to the given point.
Definition: Sphere.cpp:166
void setCentre(const Kernel::V3D &)
Setter for centre of sphere.
Definition: Sphere.cpp:175
void writeHeader(std::ostream &) const
Writes out the start of an MCNPX surface description .
Definition: Surface.cpp:71
static const int Nprecision
Precision of the output.
Definition: Surface.h:41
Numerical Matrix class.
Definition: Matrix.h:42
Class for 3D vectors.
Definition: V3D.h:34
double distance(const V3D &v) const noexcept
Calculates the distance between two vectors.
Definition: V3D.h:287
constexpr double scalar_prod(const V3D &v) const noexcept
Calculates the cross product.
Definition: V3D.h:274
constexpr double X() const noexcept
Get x.
Definition: V3D.h:232
constexpr double Y() const noexcept
Get y.
Definition: V3D.h:233
void rotate(const Matrix< double > &) noexcept
Rotate a point by a matrix.
Definition: V3D.cpp:217
double norm() const noexcept
Definition: V3D.h:263
constexpr double Z() const noexcept
Get z.
Definition: V3D.h:234
int section(std::string &A, T &out)
Convert and cut a string.
Definition: Strings.cpp:573
MANTID_KERNEL_DLL void writeMCNPX(const std::string &Line, std::ostream &OX)
Write file in standard MCNPX input form.
Definition: Strings.cpp:421
constexpr double Tolerance
Standard tolerance value.
Definition: Tolerance.h:12