3#ifndef __stir_LORCoordinates_H__
4#define __stir_LORCoordinates_H__
33template <
class coordT>
35template <
class coordT>
36class LORInAxialAndSinogramCoordinates;
37template <
class coordT>
38class LORInCylinderCoordinates;
39template <
class coordT>
40class LORInAxialAndNoArcCorrSinogramCoordinates;
41template <
class coordT>
57template <
class coordT>
63 virtual LOR* clone()
const = 0;
79template <
class coordT>
84 void check_state()
const
87 assert(_psi <
static_cast<coordT
>(2 *
_PI));
101 coordT z()
const {
return _z; }
102 coordT& z() {
return _z; }
104 inline PointOnCylinder();
105 inline PointOnCylinder(
const coordT z,
const coordT psi);
116template <
class coordT>
117class LORCylindricalCoordinates_z_and_radius
121 void check_state()
const { assert(_radius > 0); }
124 explicit LORCylindricalCoordinates_z_and_radius(coordT radius = 1)
129 LORCylindricalCoordinates_z_and_radius(coordT z1, coordT z2, coordT radius)
158 coordT radius()
const
164 inline void set_radius_no_check(
const coordT new_radius)
167 assert(new_radius > 0);
168 _z1 *= new_radius / _radius;
169 _z2 *= new_radius / _radius;
170 _radius = new_radius;
183template <
class coordT>
184class LORInCylinderCoordinates :
public LOR<coordT>
186#ifdef STIR_COMPILING_SWIG_WRAPPER
190 typedef LORInCylinderCoordinates<coordT> self_type;
193 void check_state()
const
224 void reset(coordT radius = 1)
228 _p2.psi() =
static_cast<coordT
>(
_PI);
231 coordT radius()
const
244 assert(new_radius > 0);
245 if (_radius == new_radius)
246 return Succeeded::yes;
248 const coordT min_radius = _radius * fabs(cos((_p1.psi() - _p2.psi()) / 2));
249 if (new_radius >= min_radius)
250 return Succeeded::no;
251 _p1.z() *= new_radius / _radius;
252 _p2.z() *= new_radius / _radius;
253 _radius = new_radius;
254 return Succeeded::yes;
271 self_type* clone()
const override
273 return new self_type(*
this);
276 Succeeded change_representation(LORInCylinderCoordinates<coordT>&,
const double radius)
const override;
278 Succeeded change_representation(LORInAxialAndNoArcCorrSinogramCoordinates<coordT>&,
const double radius)
const override;
280 Succeeded change_representation(LORInAxialAndSinogramCoordinates<coordT>&,
const double radius)
const override;
282 Succeeded get_intersections_with_cylinder(LORAs2Points<coordT>&,
const double radius)
const override;
285 PointOnCylinder<coordT> _p1;
286 PointOnCylinder<coordT> _p2;
294template <
class coordT>
295class LORAs2Points :
public LOR<coordT>
297#ifdef STIR_COMPILING_SWIG_WRAPPER
301 typedef LORAs2Points<coordT> self_type;
321 inline LORAs2Points();
340 self_type* clone()
const override
342 return new self_type(*
this);
345 Succeeded change_representation(LORInCylinderCoordinates<coordT>&,
const double radius)
const override;
347 Succeeded change_representation(LORInAxialAndNoArcCorrSinogramCoordinates<coordT>&,
const double radius)
const override;
349 Succeeded change_representation(LORInAxialAndSinogramCoordinates<coordT>&,
const double radius)
const override;
351 Succeeded get_intersections_with_cylinder(LORAs2Points<coordT>&,
const double radius)
const override;
354 Succeeded change_representation_for_block(LORInAxialAndNoArcCorrSinogramCoordinates<coordT>&,
const double radius)
const;
357 CartesianCoordinate3D<coordT> _p1;
358 CartesianCoordinate3D<coordT> _p2;
365template <
class coordT>
366class LORInAxialAndSinogramCoordinates :
public LOR<coordT>,
private LORCylindricalCoordinates_z_and_radius<coordT>
369#ifdef STIR_COMPILING_SWIG_WRAPPER
373 typedef LORInAxialAndSinogramCoordinates<coordT> self_type;
376 typedef LORCylindricalCoordinates_z_and_radius<coordT> private_base_type;
378 void check_state()
const
380 assert(private_base_type::_radius > 0);
381 assert(_s > -private_base_type::_radius);
382 assert(_s < private_base_type::_radius);
383 assert(_phi <
static_cast<coordT
>(
_PI));
391 return private_base_type::z1();
396 return private_base_type::z1();
401 return private_base_type::z2();
406 return private_base_type::z2();
432 return asin(_s / private_base_type::_radius);
444 inline explicit LORInAxialAndSinogramCoordinates(
const coordT radius = 1);
451 inline LORInAxialAndSinogramCoordinates(
452 const coordT z1,
const coordT z2,
const coordT phi,
const coordT s,
const coordT radius = 1,
const bool swapped =
false);
454 inline LORInAxialAndSinogramCoordinates(
const LORInCylinderCoordinates<coordT>&);
456 inline LORInAxialAndSinogramCoordinates(
const LORInAxialAndNoArcCorrSinogramCoordinates<coordT>&);
460 LORInAxialAndSinogramCoordinates(
const LORAs2Points<coordT>&);
463 self_type* clone()
const override
465 return new self_type(*
this);
468 void reset(coordT radius = 1)
472 private_base_type::_radius = radius;
474 coordT radius()
const
477 return private_base_type::_radius;
480 inline Succeeded set_radius(
const coordT new_radius)
482 if (private_base_type::_radius == new_radius)
483 return Succeeded::yes;
484 assert(new_radius > 0);
485 if (fabs(s()) >= new_radius)
486 return Succeeded::no;
487 this->set_radius_no_check(new_radius);
488 return Succeeded::yes;
491 Succeeded change_representation(LORInCylinderCoordinates<coordT>&,
const double radius)
const override;
493 Succeeded change_representation(LORInAxialAndNoArcCorrSinogramCoordinates<coordT>&,
const double radius)
const override;
495 Succeeded change_representation(LORInAxialAndSinogramCoordinates<coordT>&,
const double radius)
const override;
497 Succeeded get_intersections_with_cylinder(LORAs2Points<coordT>&,
const double radius)
const override;
509template <
class coordT>
510class LORInAxialAndNoArcCorrSinogramCoordinates :
public LOR<coordT>,
private LORCylindricalCoordinates_z_and_radius<coordT>
513#ifdef STIR_COMPILING_SWIG_WRAPPER
517 typedef LORInAxialAndNoArcCorrSinogramCoordinates<coordT> self_type;
518 typedef LORCylindricalCoordinates_z_and_radius<coordT> private_base_type;
521 void check_state()
const
523 assert(private_base_type::_radius > 0);
524 assert(_beta >=
static_cast<coordT
>(-
_PI / 2));
525 assert(_beta <
static_cast<coordT
>(
_PI / 2));
526 assert(_phi <
static_cast<coordT
>(
_PI));
534 return private_base_type::z1();
539 return private_base_type::z1();
544 return private_base_type::z2();
549 return private_base_type::z2();
585 return private_base_type::_radius * sin(_beta);
588 void reset(coordT radius = 1)
592 private_base_type::_radius = radius;
594 coordT radius()
const
597 return private_base_type::_radius;
600 inline Succeeded set_radius(
const coordT new_radius)
602 if (private_base_type::_radius == new_radius)
603 return Succeeded::yes;
604 assert(new_radius > 0);
605 if (fabs(s()) >= new_radius)
606 return Succeeded::no;
607 this->set_radius_no_check(new_radius);
608 return Succeeded::yes;
611 inline explicit LORInAxialAndNoArcCorrSinogramCoordinates(
const coordT radius = 1);
618 inline LORInAxialAndNoArcCorrSinogramCoordinates(
619 const coordT z1,
const coordT z2,
const coordT phi,
const coordT beta,
const coordT radius = 1,
const bool swapped =
false);
621 inline LORInAxialAndNoArcCorrSinogramCoordinates(
const LORInCylinderCoordinates<coordT>&);
623 inline LORInAxialAndNoArcCorrSinogramCoordinates(
const LORInAxialAndSinogramCoordinates<coordT>&);
627 LORInAxialAndNoArcCorrSinogramCoordinates(
const LORAs2Points<coordT>&);
630 self_type* clone()
const override
632 return new self_type(*
this);
635 Succeeded change_representation(LORInCylinderCoordinates<coordT>&,
const double radius)
const override;
637 Succeeded change_representation(LORInAxialAndNoArcCorrSinogramCoordinates<coordT>&,
const double radius)
const override;
639 Succeeded change_representation(LORInAxialAndSinogramCoordinates<coordT>&,
const double radius)
const override;
641 Succeeded get_intersections_with_cylinder(LORAs2Points<coordT>&,
const double radius)
const override;
654template <
class coordT1,
class coordT2>
661template <
class coordT1,
class coordT2>
663 const LORAs2Points<coordT2>& coords,
664 const double radius);
669template <
class coordT1,
class coordT2>
671 const LORAs2Points<coordT2>& cart_coords,
672 const double radius);
678template <
class coordT1,
class coordT2>
680 const LORAs2Points<coordT2>& cart_coords,
681 const double radius);
defines the stir::CartesianCoordinate3D<coordT> class
Implementations for LORCoordinates.h.
Declaration of class stir::Succeeded.
a templated class for 3-dimensional coordinates.
Definition CartesianCoordinate3D.h:53
A class for LORs.
Definition LORCoordinates.h:296
bool is_swapped() const override
Return if the LOR direction is opposite from normal.
Definition LORCoordinates.h:335
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
bool is_swapped() const override
Return if the LOR direction is opposite from normal.
Definition LORCoordinates.h:434
A class for LORs.
Definition LORCoordinates.h:185
bool is_swapped() const override
Return if the LOR direction is opposite from normal.
Definition LORCoordinates.h:220
A base class for specifying an LOR with geometric coordinates.
Definition LORCoordinates.h:59
virtual bool is_swapped() const =0
Return if the LOR direction is opposite from normal.
A class for a point on a cylinder.
Definition LORCoordinates.h:81
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
Succeeded set_radius(coordT new_radius)
Changes the radius of the LOR.
Definition LORCoordinates.h:241
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