32template <
class coordT>
33PointOnCylinder<coordT>::PointOnCylinder()
37template <
class coordT>
38PointOnCylinder<coordT>::PointOnCylinder(
const coordT z,
const coordT psi)
43template <
class coordT>
44LORInCylinderCoordinates<coordT>::LORInCylinderCoordinates(
const coordT radius)
48template <
class coordT>
49LORInCylinderCoordinates<coordT>::LORInCylinderCoordinates(
const PointOnCylinder<coordT>& p1,
50 const PointOnCylinder<coordT>& p2,
57template <
class coordT>
58LORAs2Points<coordT>::LORAs2Points()
61template <
class coordT>
62LORAs2Points<coordT>::LORAs2Points(
const CartesianCoordinate3D<coordT>& p1,
const CartesianCoordinate3D<coordT>& p2)
67template <
class coordT>
68LORInAxialAndSinogramCoordinates<coordT>::LORInAxialAndSinogramCoordinates(
const coordT radius)
69 : LORCylindricalCoordinates_z_and_radius<coordT>(radius),
77template <
class coordT>
78LORInAxialAndSinogramCoordinates<coordT>::LORInAxialAndSinogramCoordinates(
79 const coordT z1,
const coordT z2,
const coordT phi,
const coordT s,
const coordT radius,
const bool swapped)
80 : LORCylindricalCoordinates_z_and_radius<coordT>(z1, z2, radius),
89 std::swap(private_base_type::_z1, private_base_type::_z2);
95template <
class coordT>
96LORInAxialAndNoArcCorrSinogramCoordinates<coordT>::LORInAxialAndNoArcCorrSinogramCoordinates(
const coordT radius)
106template <
class coordT>
107LORInAxialAndNoArcCorrSinogramCoordinates<coordT>::LORInAxialAndNoArcCorrSinogramCoordinates(
108 const coordT z1,
const coordT z2,
const coordT phi,
const coordT beta,
const coordT radius,
const bool swapped)
109 : LORCylindricalCoordinates_z_and_radius<coordT>(z1, z2, radius),
118 std::swap(private_base_type::_z1, private_base_type::_z2);
128template <
class coordT>
130 : _radius(na_coords.radius())
132 _p1.z() = na_coords.z1();
133 _p2.z() = na_coords.z2();
134 _p1.psi() =
to_0_2pi(na_coords.phi() + na_coords.beta());
135 _p2.psi() =
to_0_2pi(na_coords.phi() - na_coords.beta() +
static_cast<coordT
>(
_PI));
141template <
class coordT>
142LORInCylinderCoordinates<coordT>::LORInCylinderCoordinates(
const LORInAxialAndSinogramCoordinates<coordT>& coords)
143 : _radius(coords.radius())
145 _p1.z() = coords.z1();
146 _p2.z() = coords.z2();
147 _p1.psi() =
to_0_2pi(coords.phi() + coords.beta());
148 _p2.psi() =
to_0_2pi(coords.phi() - coords.beta() +
static_cast<coordT
>(
_PI));
149 if (coords.is_swapped())
154template <
class coordT>
159 _beta =
to_0_2pi((cyl_coords.p1().psi() - cyl_coords.p2().psi() +
static_cast<coordT
>(
_PI)) / 2);
161 _beta -=
static_cast<coordT
>(2 *
_PI);
162 _phi =
to_0_2pi((cyl_coords.p1().psi() + cyl_coords.p2().psi() -
static_cast<coordT
>(
_PI)) / 2);
166 if (_phi <
static_cast<coordT
>(
_PI))
168 if (_beta >=
static_cast<coordT
>(
_PI) / 2)
170 _beta =
static_cast<coordT
>(
_PI) - _beta;
171 _z2 = cyl_coords.p1().z();
172 _z1 = cyl_coords.p2().z();
175 else if (_beta < -
static_cast<coordT
>(
_PI) / 2)
177 _beta = -
static_cast<coordT
>(
_PI) - _beta;
178 _z2 = cyl_coords.p1().z();
179 _z1 = cyl_coords.p2().z();
185 _z1 = cyl_coords.p1().z();
186 _z2 = cyl_coords.p2().z();
192 _phi -=
static_cast<coordT
>(
_PI);
194 if (_beta >=
static_cast<coordT
>(
_PI) / 2)
196 _beta -=
static_cast<coordT
>(
_PI);
197 _z1 = cyl_coords.p1().z();
198 _z2 = cyl_coords.p2().z();
201 else if (_beta < -
static_cast<coordT
>(
_PI) / 2)
203 _beta +=
static_cast<coordT
>(
_PI);
204 _z1 = cyl_coords.p1().z();
205 _z2 = cyl_coords.p2().z();
211 _z2 = cyl_coords.p1().z();
212 _z1 = cyl_coords.p2().z();
218 assert(_beta >= -
_PI / 2);
219 assert(_beta <=
_PI / 2);
222template <
class coordT>
223LORInAxialAndNoArcCorrSinogramCoordinates<coordT>::LORInAxialAndNoArcCorrSinogramCoordinates(
232 get_sino_coords(z1(), z2(), _phi, _beta, _swapped, cyl_coords);
236template <
class coordT>
246 get_sino_coords(z1(), z2(), _phi, beta, _swapped, cyl_coords);
247 _s = this->_radius * sin(beta);
251template <
class coordT>
252LORInAxialAndSinogramCoordinates<coordT>::LORInAxialAndSinogramCoordinates(
257 _swapped(coords.is_swapped())
262template <
class coordT>
263LORInAxialAndNoArcCorrSinogramCoordinates<coordT>::LORInAxialAndNoArcCorrSinogramCoordinates(
267 _beta(coords.beta()),
268 _swapped(coords.is_swapped())
274template <
class coordT>
280template <
class coordT>
287template <
class coordT>
291 p1().z() = cyl_coords.p1().z();
292 p1().y() = -cyl_coords.radius() * cos(cyl_coords.p1().psi());
293 p1().x() = cyl_coords.radius() * sin(cyl_coords.p1().psi());
295 p2().z() = cyl_coords.p2().z();
296 p2().y() = -cyl_coords.radius() * cos(cyl_coords.p2().psi());
297 p2().x() = cyl_coords.radius() * sin(cyl_coords.p2().psi());
300template <
class coordT>
306template <
class coordT>
312template <
class coordT1,
class coordT2>
334 const double b = d.x() * c1.x() + d.y() * c1.y();
336 double argsqrt =
square(b) - a * e;
339 return Succeeded::no;
341 const coordT2 root =
static_cast<coordT2
>(sqrt(argsqrt));
343 auto l1 =
static_cast<coordT2
>((-b - root) / a);
344 auto l2 =
static_cast<coordT2
>((-b + root) / a);
346 intersection_coords.p1() = d * l1 + c1;
347 intersection_coords.p2() = d * l2 + c1;
348 assert(fabs(
square(intersection_coords.p1().x()) +
square(intersection_coords.p1().y()) -
square(radius))
349 <
square(radius) * 10.E-5);
350 assert(fabs(
square(intersection_coords.p2().x()) +
square(intersection_coords.p2().y()) -
square(radius))
351 <
square(radius) * 10.E-5);
352 return Succeeded::yes;
355template <
class coordT1,
class coordT2>
363 return Succeeded::no;
367 cyl_coords.reset(
static_cast<float>(radius));
371 cyl_coords.p1().z() =
static_cast<coordT1
>(c1.z());
372 cyl_coords.p2().z() =
static_cast<coordT1
>(c2.z());
374 return Succeeded::yes;
377template <
class coordT1,
class coordT2>
385 return Succeeded::no;
387 return Succeeded::yes;
390template <
class coordT1,
class coordT2>
398 return Succeeded::no;
400 return Succeeded::yes;
403template <
class coordT>
405LORAs2Points<coordT>::change_representation(LORInCylinderCoordinates<coordT>& lor,
const double radius)
const
410template <
class coordT>
417template <
class coordT>
424template <
class coordT>
426LORAs2Points<coordT>::get_intersections_with_cylinder(
LORAs2Points<coordT>& lor,
const double radius)
const
431template <
class coordT>
434 const double radius)
const
442 const double argsqrt = (
square(radius) * dxy2 -
square(d.x() * c1.y() - d.y() * c1.x()));
445 cyl_coords.reset(
static_cast<float>(radius));
449 cyl_coords.p1().z() =
static_cast<coordT
>(c1.z());
450 cyl_coords.p2().z() =
static_cast<coordT
>(c2.z());
454 return Succeeded::no;
456 return Succeeded::yes;
459#define DEFINE_LOR_GET_FUNCTIONS(TYPE) \
460 template <class coordT> \
461 Succeeded TYPE<coordT>::change_representation(LORInCylinderCoordinates<coordT>& lor, const double radius) const \
464 return lor.set_radius(static_cast<coordT>(radius)); \
467 template <class coordT> \
468 Succeeded TYPE<coordT>::change_representation(LORInAxialAndNoArcCorrSinogramCoordinates<coordT>& lor, const double radius) \
472 return lor.set_radius(static_cast<coordT>(radius)); \
475 template <class coordT> \
476 Succeeded TYPE<coordT>::change_representation(LORInAxialAndSinogramCoordinates<coordT>& lor, const double radius) const \
479 return lor.set_radius(static_cast<coordT>(radius)); \
482 template <class coordT> \
483 Succeeded TYPE<coordT>::get_intersections_with_cylinder(LORAs2Points<coordT>& lor, const double radius) const \
485 LORAs2Points<coordT> actual_lor = *this; \
486 if (find_LOR_intersections_with_cylinder(lor, actual_lor, radius) == Succeeded::no) \
487 return Succeeded::no; \
488 return Succeeded::yes; \
495#undef DEFINE_LOR_GET_FUNCTIONS
Declaration of class stir::Succeeded.
a templated class for 3-dimensional coordinates.
Definition CartesianCoordinate3D.h:53
A class for LORs.
Definition LORCoordinates.h:296
Succeeded change_representation_for_block(LORInAxialAndNoArcCorrSinogramCoordinates< coordT > &, const double radius) const
Calculate intersections with block. Used in: ProjDataInfoBlocksOnCylindrical::get_LOR.
Definition LORCoordinates.inl:433
An internal class for LORs. Do not use.
Definition LORCoordinates.h:118
A class for LORs.
Definition LORCoordinates.h:511
bool is_swapped() const override
Return if the LOR direction is opposite from normal.
Definition LORCoordinates.h:571
A class for LORs.
Definition LORCoordinates.h:367
A class for LORs.
Definition LORCoordinates.h:185
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
Succeeded find_LOR_intersections_with_cylinder(LORInCylinderCoordinates< coordT1 > &, const LORAs2Points< coordT2 > &, const double radius)
Given an LOR, find its intersection with a (infintely long) cylinder.
Definition LORCoordinates.inl:357
#define _PI
The constant pi to high precision.
Definition common.h:141
NUMBER square(const NUMBER &x)
returns the square of a number, templated.
Definition common.h:154
defines stir::modulo() and related functions
FloatOrDouble from_min_pi_plus_pi_to_0_2pi(const FloatOrDouble phi)
A function to convert an angle from one range to another.
Definition modulo.h:118
FloatOrDouble to_0_2pi(const FloatOrDouble phi)
Convert angle to standard range.
Definition modulo.h:138