diff --git a/Core/Documentation/Doxygen/Concepts/GeometryOverview.dox b/Core/Documentation/Doxygen/Concepts/GeometryOverview.dox index 1a6d25bf68..eb794fb851 100644 --- a/Core/Documentation/Doxygen/Concepts/GeometryOverview.dox +++ b/Core/Documentation/Doxygen/Concepts/GeometryOverview.dox @@ -1,133 +1,147 @@ namespace mitk{ /** \page GeometryOverviewPage Geometry Overview Available sections: -# \ref GeometryOverviewPage_Introduction "Introduction to Geometries" -# \ref GeometryOverviewPage_Concept "The Geometry Concept" -# \ref GeometryOverviewPage_Putting_Together "IMPORTANT: Putting it together for an Image" -# \ref GeometryOverviewPage_Connection "Connection between MITK, ITK and VTK Geometries"\n\n \section GeometryOverviewPage_Introduction Introduction to Geometries Geometries are used to describe the geometrical properties of data objects in space and time.\n To use the geometry classes in the right way you have to understand the three different coordinate types present in MITK:\n\n \image html CoordinateTypes.png
The different coordinate types\n\n
\n -# World coordinates: - - World coordinates are describing the actual spacial position of all MITK objects regarding a global coordinate system, normally specified by the imaging modality + - World coordinates are describing the actual spacial position of all MITK objects regarding a global coordinate system, normally specified by the imaging modality + - World coordinates are represented by mitk::Point3D objects. - The geometry defines the offset, orientation, and scale of the considered data objects in reference to the world coordinate systems. - World coordinates are always measured in mm - If you are dealing with an image geometry, the origin of an image is pointing to the CENTER of the bottom-left-back voxel.\n - If you are NOT dealing with an image geometry (no defined discrete Voxels), the origin is pointing to the bottom-left-back CORNER - Index coordinates can be converted to world coordinates by calling Geometry3D::IndexToWorld()\n\n \image html worldcoordinateSystem.png
Corner-based coordinates\n\n
\image html WorldcoordinateSystemCenterBased.png
Center-based image-coordinates\n\n
\n -# Continuous index coordinates: - Dividing world coordinates through the pixel spacing and simultanously taking the offset into account leads to continuous index coordinates inside your dataobject.\n So continuous coordinates can be float values! + - Continuous index coordinates are represented by mitk::Point3D objects. - They can be obtained by calling Geometry3D::WorldToIndex(), where &pt_mm is a point in worldcoordinates.\n -# Index coordinate system: - Index coordinates are discrete values that address voxels of a data object explicitly. + - Index coordinates are represented by mitk::Index3D objects. - Basically they are continuous index coordinates which are rounded from half integer up. - E.g. (0,0) specifies the very first pixel of a 2D image, (0,1) the pixel of the next column in the same row - If you have world coordinates, they can be converted to discrete index coordinates by calling Geometry3D::WorldToIndex()\n\n +\section GeometryOverviewPage_PointsAndVector Difference between Points and Vectors + +Like ITK, MITK differenciate between points and vectors. A point defines a position in a coordinate system while a +vector is the distance between two points. Therefore points and vectors behave different if a coordinate transformation +is applied. An offest in a coordinate transformation will affect a transformed point but not a vector. + +An Example:\n +If two systems are given, which differ by a offset of (1,0,0). The point A(2,2,2) in system one will correspont to point A'(3,2,2) in the second system. +But a vector a(2,2,2) will correspond to the vector a'(2,2,2). + + \section GeometryOverviewPage_Concept The Geometry Concept As the superclass of all MITK geometries Geometry3D holds: - a spacial bounding box which is axes-parallel in index coordinates (often discrete indices of pixels), to be accessed by Geometry3D::GetBoundingBox() - a time related bounding box which holds the temporal validity of the considered data object in milliseconds (start and end time), to be accessed by Geometry3D::GetTimeBounds().\n The default for 3D geometries is minus infinity to plus infinity, meaning the object is always displayed independent of displayed time in MITK. - position information in form of a Euclidean transform in respect to world coordinates (i.e. a linear transformation matrix and offset) to convert (discrete or continuous) index coordinates to world coordinates and vice versa,\n to be accessed by Geometry3D::GetIndexToWorldTransform()\n See also: \ref GeometryOverviewPage_Introduction "Introduction to Geometries" - Many other properties (e.g. origin, extent, ...) which can be found in the \ref Geometry3D "class documentation" - VERY IMPORTANT:\n A flag called isImageGeometry, which indicates whether the coordinates are center-based or not!\n See also: \ref GeometryOverviewPage_Introduction "Introduction to Geometries" and \ref GeometryOverviewPage_Putting_Together "IMPORTANT: Putting it together for an Image"\n\n Every data object which is (sub-)class of BaseData has a Geometry3D, to be more specific, a TimeSlicedGeometry, to be accessed by BaseData::GetTimeSlicedGeometry().\n This is because all data objects are objects in space and time. The data values are often stored in index coordinates, e.g., integer pixel/voxel or time indices.\n The information required to convert these index coordinates into a world coordinate system, with spatiotemporal coordinates in millimeters and milliseconds, is stored in Geometry3D\n class and its sub-classes. TimeSlicedGeometry describes a spatiotemporal geometry consisting of spatial geometries existing at different times, and allocates each geometry at a valid time step a discrete number. It contains a list of Geometry3D instances to be accessed by\n TimeSlicedGeometry::GetGeometry3D(t), with t between 0 and TimeSlicedGeometry::GetTimeSteps().\n To convert between world time in milliseconds and the integer timestep number use TimeSlicedGeometry::MSToTimeStep(), for conversion in the opposite direction\n TimeSlicedGeometry::TimeStepToMS(). Often all Geometry3D instances contained in a TimeSlicedGeometry have the same temporal extent.\n The initialization for this case can be done using TimeSlicedGeometry::InitializeEvenlyTimed(Geometry3D *geometry3D, unsigned int timeSteps). The Geometry3D parameter must have a limited life span set by Geometry3D::SetTimeBounds(). It is used as the first Geometry3D contained in the TimeSlicedGeometry (thus returned by TimeSlicedGeometry:: GetGeometry3D(0)). The next one will start to have a valid time range immediately at the end of validness of the processor. The bounding boxes and spacial transformations are copied.\n The instance of Geometry3D provided to TimeSlicedGeometry::InitializeEvenlyTimed is referenced, not copied! TimeSlicedGeometry is a Geometry3D itself. Its bounding box and transformation is usually the same as the bounding box and transformations of the contained Geometry3D instances.\n Its life span (to be accessed by TimeSlicedGeometry::GetTimeBounds()) is the span from the initial valid time of the first contained Geometry3D to the termination of the last valid time of contained Geometry3Ds. TimeSlicedGeometry can also contain Geometry3D instances that do not have the same Euclidean geometry. In that case, TimeSlicedGeometry::GetEvenlyTimed() has to be false. SlicedGeometry3D is a sub-class of Geometry3D, which describes data objects consisting of slices, e.g., objects of type Image (or SlicedData, which is the super-class of Image). Therefore, Image::GetTimeSlicedGeometry() will contain a list of SlicedGeometry3D instances. There is a special method SlicedData::GetSlicedGeometry(t) which directly returns\n a SlicedGeometry3D to avoid the need of casting. Comparable to TimeSlicedGeometry the class SlicedGeometry3D contains a list of Geometry2D objects describing the slices in the image. Instead of time steps we have spatial steps here from 0 to GetSlices(). SlicedGeometry3D::InitializeEvenlySpaced (Geometry2D *geometry2D, unsigned int slices) initializes a stack of slices with the same thickness, one starting at the position where the previous one ends. Geometry2D provides methods for working with 2D manifolds (i.e., simply spoken, an object that can be described using a 2D coordinate-system) in 3D space.\n For example it allows mapping of a 3D point on the 2D manifold using Geometry2D::Map(). A subclass of Geometry2D called PlaneGeometry, explicitly describes a 2D rectangular plane.\n Another important subclass of Geometry2D is the DisplayGeometry which describes the geometry of the display (the monitor screen). Basically it represents a rectangular view on a 2D world geometry\n The DisplayGeometry converts between screen and world coordinates, processes input events (e.g. mouse click) and provides methods for zooming and panning.\n \image html DisplayGeometry.png
Display Geometry\n\n
Finally there is the AbstractTransformGeometry which describes a 2D manifold in 3D space, defined by a vtkAbstractTransform. It is a abstract superclass for arbitrary user defined geometries\n An example is the ThinPlateSplineCurvedGeometry.\n \subsection GeometryOverviewPage_Putting_Together IMPORTANT: Putting it together for an Image Please read this section accurately if you are working with Images! The definition of the position of the corners of an image is different than the one of other data objects: As mentioned in the previous section, world coordinates of data objects (e.g. surfaces ) usually specify the bottom left back corner of an object. In contrast to that a geometry of an Image is center-based, which means that the world coordinates of a voxel belonging to an image points to the center of that voxel. E.g: \image html PixelCenterBased.png
Center-based voxel\n\n
If the origin of e.g. a surface lies at (15,10,0) in world coordinates, the origin`s world coordinates for an image are internally calculated like the following:
(15-0.5*X-Spacing\n 10-0.5*Y-Spacing\n 0-0.5*Z-Spacing)\n
If the image`s spacing is (x,y,z)=(1,1,3) then the corner coordinates are (14.5,9.5,-1.5). If your geometry describes an image, the member variable isImageGeometry must be changed to true. This variable indicates also if your geometry is center-based or not.\n The change can be done in two ways:\n -# You are sure that your origin is already center-based. Whether because you adjusted it manually or you copied it from another image.\n In that case, you can call the function setImageGeometry(true) or imageGeometryOn() to set the bool variable to true. -# You created a new geometry, did not manually adjust the origin to be center-based and have the bool value isImageGeometry set to false (default).\n In that case, call the function ChangeImageGeometryConsideringOriginOffset(true). It will adjust your origin automatically and set the bool flag to true.\n If you experience displaced contours, figures or other stuff, it is an indicator that you have not considered the origin offset mentioned above.\n\n An image has a TimeSlicedGeometry, which contains one or more SlicedGeometry3D instances (one for each time step), all of which contain one or more instances of (sub-classes of) Geometry2D (usually PlaneGeometry).\n As a reminder: Geometry instances referring to images need a slightly different definition of corners, see Geometry3D::SetImageGeometry. This is usualy automatically called by Image.\n\n \section GeometryOverviewPage_Connection Connection between MITK, ITK and VTK Geometries \image html ITK_VTK_MITK_Geometries.png \n\n - VTK transformation for rendering - ITK transformation for calculations - Both automatically updated when one is changed\n Attention:Not automatically updated when changed hardcoded. Example: geometry->GetVtkMatrix()->Rotate(....) */ } \ No newline at end of file