22 #include <itkSpatialOrientationAdapter.h>
24 #include <vtkTransform.h>
26 #include <vnl/vnl_cross.h>
33 :
Superclass(other), m_ReferenceGeometry(other.m_ReferenceGeometry)
43 VnlVector normal = vnl_cross_3d(transform->GetMatrix().GetVnlMatrix().get_column(0),
44 transform->GetMatrix().GetVnlMatrix().get_column(1));
47 ScalarType len = transform->GetMatrix().GetVnlMatrix().get_column(2).two_norm();
55 vnl_vector_fixed<double, 3> zed = transform->GetMatrix().GetVnlMatrix().get_column(2);
58 if (vnl_determinant(transform->GetMatrix().GetVnlMatrix()) < 0)
60 MITK_DEBUG <<
"EnsurePerpendicularNormal(): Lefthanded geometry preserved, rh-normal: [ " << normal <<
" ],";
62 MITK_DEBUG <<
"lh-normal: [ " << normal <<
" ], original vector zed is: [ " << zed <<
" ]";
70 double feps = std::numeric_limits<float>::epsilon();
71 double zedsMagnitude = zed.two_norm();
72 feps = feps * zedsMagnitude * 2;
77 vnl_vector_fixed<double, 3> parallel;
78 for (
unsigned int i = 0; i < 3; ++i)
80 parallel[i] = normal[i] / zed[i];
83 if ((parallel[0] + feps < parallel[1] || feps + parallel[1] < parallel[0]) &&
84 (parallel[0] + feps < parallel[2] || feps + parallel[2] < parallel[0]))
87 <<
"EnsurePerpendicularNormal(): Plane geometry was _/askew/_, so here it gets rectified by substituting"
88 <<
" the 3rd column of the indexToWorldMatrix with an appropriate normal vector: [ " << normal
89 <<
" ], original vector zed was: [ " << zed <<
" ].";
91 Matrix3D matrix = transform->GetMatrix();
92 matrix.GetVnlMatrix().set_column(2, normal);
93 transform->SetMatrix(matrix);
115 assert(bounds[0] == 0);
116 assert(bounds[2] == 0);
118 assert(bounds[1] > 0);
119 assert(bounds[3] > 0);
136 MITK_WARN <<
"Warning! Call of the deprecated function PlaneGeometry::IndexToWorld(point, vec, vec). Use "
137 "PlaneGeometry::IndexToWorld(vec, vec) instead!";
149 MITK_WARN <<
"Warning! Call of the deprecated function PlaneGeometry::WorldToIndex(point, vec, vec). Use "
150 "PlaneGeometry::WorldToIndex(vec, vec) instead!";
172 AffineTransform3D::MatrixType matrix;
173 AffineTransform3D::MatrixType::InternalMatrixType &vnlmatrix = matrix.GetVnlMatrix();
175 vnlmatrix.set_identity();
176 vnlmatrix(0, 0) = spacing[0];
177 vnlmatrix(1, 1) = spacing[1];
178 vnlmatrix(2, 2) = spacing[2];
179 transform->SetIdentity();
180 transform->SetMatrix(matrix);
182 InitializeStandardPlane(width, height, transform.GetPointer(), planeorientation, zPosition, frontside, rotated, top);
230 switch (planeorientation)
238 if (rotated ==
false)
265 if (rotated ==
false)
286 if (rotated ==
false)
301 if (rotated ==
false)
320 if (rotated ==
false)
335 if (rotated ==
false)
352 itkExceptionMacro(
"unknown PlaneOrientation");
357 normal[normalDirection] = top ? 1 : -1;
359 if ( transform !=
nullptr )
361 origin = transform->TransformPoint( origin );
362 rightDV = transform->TransformVector( rightDV );
363 bottomDV = transform->TransformVector( bottomDV );
364 normal = transform->TransformVector( normal );
367 ScalarType bounds[6] = {0, width, 0, height, 0, 1};
372 matrix.GetVnlMatrix().set_column(0, rightDV);
373 matrix.GetVnlMatrix().set_column(1, bottomDV);
374 matrix.GetVnlMatrix().set_column(2, normal);
375 planeTransform->SetMatrix(matrix);
398 matrix.GetVnlMatrix().normalize_columns();
399 mitk::AffineTransform3D::MatrixType::InternalMatrixType inverseMatrix = matrix.GetInverse();
409 for (
int i = 0; i < 3; ++i)
411 int dominantAxis = itk::Function::Max3(
416 axes[i] = dominantAxis;
417 directions[i] = itk::Function::Sign(inverseMatrix[dominantAxis][i]);
418 extents[i] = geometry3D->
GetExtent(dominantAxis);
419 spacings[i] = geometry3D->
GetSpacing()[dominantAxis];
423 matrix[0][0] = inverseMatrix[axes[0]][0] * directions[0] * spacings[0];
424 matrix[1][0] = inverseMatrix[axes[0]][1] * directions[0] * spacings[0];
425 matrix[2][0] = inverseMatrix[axes[0]][2] * directions[0] * spacings[0];
426 matrix[0][1] = inverseMatrix[axes[1]][0] * directions[1] * spacings[1];
427 matrix[1][1] = inverseMatrix[axes[1]][1] * directions[1] * spacings[1];
428 matrix[2][1] = inverseMatrix[axes[1]][2] * directions[1] * spacings[1];
429 matrix[0][2] = inverseMatrix[axes[2]][0] * directions[2] * spacings[2];
430 matrix[1][2] = inverseMatrix[axes[2]][1] * directions[2] * spacings[2];
431 matrix[2][2] = inverseMatrix[axes[2]][2] * directions[2] * spacings[2];
437 for (
int i = 0; i < 3; ++i)
440 double offset = directions[i] > 0 ? 0.0 : extents[i];
444 offset += directions[i] * 0.5;
447 for (
int j = 0; j < 3; ++j)
449 worldOrigin[j] -= offset * matrix[j][i];
453 switch(planeorientation)
471 itkExceptionMacro(
"unknown PlaneOrientation");
474 ScalarType bounds[6]= { 0, width, 0, height, 0, 1 };
478 transform->SetMatrix(matrix);
479 transform->SetOffset(worldOrigin.GetVectorFromOrigin());
482 width, height, transform, planeorientation, zPosition, frontside, rotated, top);
490 switch(planeorientation)
505 itkExceptionMacro(
"unknown PlaneOrientation");
512 mitk::AffineTransform3D::MatrixType matrix = affineTransform->GetMatrix();
513 matrix.GetVnlMatrix().normalize_columns();
514 mitk::AffineTransform3D::MatrixType::InternalMatrixType inverseMatrix = matrix.GetInverse();
517 int dominantAxis = itk::Function::Max3(
518 inverseMatrix[0][worldAxis],
519 inverseMatrix[1][worldAxis],
520 inverseMatrix[2][worldAxis]);
566 VnlVector normal = vnl_cross_3d(rightVector, downVector);
572 if (spacing !=
nullptr)
574 rightDV *= (*spacing)[0];
575 downDV *= (*spacing)[1];
576 normal *= (*spacing)[2];
581 matrix.GetVnlMatrix().set_column(0, rightDV);
582 matrix.GetVnlMatrix().set_column(1, downDV);
583 matrix.GetVnlMatrix().set_column(2, normal);
584 transform->SetMatrix(matrix);
587 ScalarType bounds[6] = {0, width, 0, height, 0, 1};
595 VnlVector rightVectorVnl(3), downVectorVnl;
597 if (
Equal(normal[1], 0.0f) ==
false)
599 FillVector3D(rightVectorVnl, 1.0f, -normal[0] / normal[1], 0.0f);
600 rightVectorVnl.normalize();
606 downVectorVnl = vnl_cross_3d(normal.GetVnlVector(), rightVectorVnl);
607 downVectorVnl.normalize();
619 VnlVector normal = vnl_cross_3d(rightVector, downVector);
628 matrix.GetVnlMatrix().set_column(0, rightVector);
629 matrix.GetVnlMatrix().set_column(1, downVector);
630 matrix.GetVnlMatrix().set_column(2, normal);
631 transform->SetMatrix(matrix);
653 if (considerBoundingBox)
669 planeNormal.Normalize();
671 Vector3D direction = itk::CrossProduct(normal, planeNormal);
673 if (direction.GetSquaredNorm() <
eps)
678 double N1dN2 = normal * planeNormal;
679 double determinant = 1.0 - N1dN2 * N1dN2;
684 double d1 = normal * origin;
685 double d2 = planeNormal * planeOrigin;
687 double c1 = (d1 - d2 * N1dN2) / determinant;
688 double c2 = (d2 - d1 * N1dN2) / determinant;
690 Vector3D p = normal * c1 + planeNormal * c2;
691 crossline.
GetPoint().GetVnlVector() = p.GetVnlVector();
725 planeNormal.Normalize();
728 lineDirection.Normalize();
730 double t = planeNormal * lineDirection;
738 t = (planeNormal * diff) / t;
740 intersectionPoint = line.
GetPoint() + lineDirection * t;
750 t = planeNormal * lineDirection;
759 t = (planeNormal * diff) / t;
788 newGeometry->UnRegister();
789 return newGeometry.GetPointer();
802 if (planeOp ==
nullptr)
813 Vector3D rotationAxis = itk::CrossProduct(orientationVector, defaultVector);
816 double rotationAngle = atan2((
double)rotationAxis.GetNorm(), (double)(orientationVector * defaultVector));
817 rotationAngle *= 180.0 / vnl_math::pi;
819 transform->PostMultiply();
820 transform->Identity();
821 transform->Translate(center[0], center[1], center[2]);
822 transform->RotateWXYZ(rotationAngle, rotationAxis[0], rotationAxis[1], rotationAxis[2]);
823 transform->Translate(-center[0], -center[1], -center[2]);
836 matrix.GetVnlMatrix().set_column(0, op->
GetTransform()->GetMatrix().GetVnlMatrix().get_column(0));
837 matrix.GetVnlMatrix().set_column(1, op->
GetTransform()->GetMatrix().GetVnlMatrix().get_column(1));
838 matrix.GetVnlMatrix().set_column(2, op->
GetTransform()->GetMatrix().GetVnlMatrix().get_column(2));
839 transform2->SetMatrix(matrix);
841 transform2->SetOffset(offset);
866 os << indent <<
" Normal: " <<
GetNormal() << std::endl;
898 ScalarType bounds[6] = {0, width, 0, height, 0, 1};
947 MITK_WARN <<
"Deprecated function! Call Project(vec3D,vec3D) instead.";
964 Point2D pt2d_mm_start, pt2d_mm_end;
966 bool inside =
Map(atPt3d_mm, pt2d_mm_start);
967 pt3d_mm_end = atPt3d_mm + vec3d_mm;
968 inside &=
Map(pt3d_mm_end, pt2d_mm_end);
969 vec2d_mm = pt2d_mm_end - pt2d_mm_start;
ScalarType GetExtent(unsigned int direction) const
Set the time bounds (in ms)
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
static void EnsurePerpendicularNormal(AffineTransform3D *transform)
Change transform so that the third column of the transform-martix is perpendicular to the first two c...
bool IntersectionPointParam(const Line3D &line, double &t) const
Calculate line parameter of intersection point between the plane and a line.
itk::BoundingBox< unsigned long, 3, ScalarType > BoundingBox
Standard 3D-BoundingBox typedef.
itk::SmartPointer< Self > Pointer
double Angle(const PlaneGeometry *plane) const
Calculate the angle between two planes.
vtkMatrix4x4 * GetVtkMatrix()
virtual void ExecuteOperation(Operation *operation) override
void SetDirection(const itk::Vector< TCoordRep, NPointDimension > &direction)
Set the direction vector of the line.
unsigned int IntersectWithPlane2D(const PlaneGeometry *plane, Point2D &lineFrom, Point2D &lineTo) const
Calculate two points where another plane intersects the border of this plane.
void SetIndexToWorldTransform(mitk::AffineTransform3D *transform)
bool IntersectionPoint(const Line3D &line, Point3D &intersectionPoint) const
Calculate intersection point between the plane and a line.
ScalarType SignedDistanceFromPlane(const Point3D &pt3d_mm) const
Signed distance of the point from the plane (bounding-box not considered)
virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override
Base class of all Operation-classes.
virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 2D point in mm (pt2d_m...
vnl_vector< ScalarType > VnlVector
bool IsOnPlane(const Point3D &point) const
Returns whether the point is on the plane (bounding-box not considered)
virtual ScalarType SignedDistance(const Point3D &pt3d_mm) const
DataCollection - Class to facilitate loading/accessing structured data.
ScalarType Distance(const Point3D &pt3d_mm) const
Distance of the point from the geometry (bounding-box not considered)
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
void Initialize()
Initialize the BaseGeometry.
Constants for most interaction classes, due to the generic StateMachines.
VnlVector GetNormalVnl() const
Normal of the plane as VnlVector.
VnlVector GetMatrixColumn(unsigned int direction) const
Get a VnlVector along bounding-box in the specified direction, length is spacing. ...
const itk::Vector< TCoordRep, NPointDimension > & GetDirection() const
Get the direction vector of the line.
virtual void WorldToIndex(const Point2D &pt_mm, Point2D &pt_units) const
const BoundsArrayType GetBounds() const
virtual void IndexToWorld(const Point2D &pt_units, Point2D &pt_mm) const
virtual void CheckIndexToWorldTransform(mitk::AffineTransform3D *transform) override
CheckIndexToWorldTransform.
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Vector3D GetNormal() const
Normal of the plane.
itk::SmartPointer< const Self > ConstPointer
ScalarType DistanceFromPlane(const Point3D &pt3d_mm) const
Distance of the point from the plane (bounding-box not considered)
const mitk::BaseGeometry * m_ReferenceGeometry
virtual bool IsAbove(const Point3D &pt3d_mm, bool considerBoundingBox=false) const
Calculates, whether a point is below or above the plane. There are two different calculation methods...
void SetVtkMatrixDeepCopy(vtkTransform *vtktransform)
virtual void SetSizeInUnits(mitk::ScalarType width, mitk::ScalarType height)
Set the width and height of this 2D-geometry in units by calling SetBounds. This does not change the ...
bool IsParallel(const PlaneGeometry *plane) const
Returns whether the plane is parallel to another plane.
const itk::Point< TCoordRep, NPointDimension > & GetPoint() const
Get start point of the line.
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
void Modified() const override
Overload of function Modified() to prohibit several calls of Modified() using the ModifiedLock class...
Operation for setting a plane (defined by its origin and normal)
void SetReferenceGeometry(const mitk::BaseGeometry *geometry)
Set the geometrical frame of reference in which this PlaneGeometry is placed.
itk::AffineGeometryFrame< ScalarType, 3 >::TransformType AffineTransform3D
virtual bool Project(const mitk::Point3D &pt3d_mm, mitk::Point3D &projectedPt3d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 3D point in mm (projec...
bool HasReferenceGeometry() const
MITKCORE_EXPORT const ScalarType sqrteps
Point3D ProjectPointOntoPlane(const Point3D &pt) const
Returns the lot from the point to the plane.
const BaseGeometry * GetReferenceGeometry() const
Get the geometrical frame of reference for this PlaneGeometry.
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
void SetBounds(const BoundsArrayType &bounds)
Set the bounding box (in index/unit coordinates)
itk::Point< TCoordRep, NPointDimension > GetPoint2() const
Get end point of the line.
bool IntersectionLine(const PlaneGeometry *plane, Line3D &crossline) const
Calculate the intersecting line of two planes.
virtual itk::LightObject::Pointer InternalClone() const override
clones the geometry
void SetExtentInMM(int direction, ScalarType extentInMM)
Set the extent of the bounding-box in the specified direction in mm.
static int RectangleLineIntersection(TCoordRep x1, TCoordRep y1, TCoordRep x2, TCoordRep y2, itk::Point< TCoordRep, 2 > p, itk::Vector< TCoordRep, 2 > d, itk::Point< TCoordRep, 2 > &s1, itk::Point< TCoordRep, 2 > &s2)
Calculates the intersection points of a straight line in 2D with a rectangle.
void SetMatrixByVectors(const VnlVector &rightVector, const VnlVector &downVector, ScalarType thickness=1.0)
Initialize plane by right-/down-vector.
AffineTransform3D::Pointer GetTransform()
virtual void CheckBounds(const BoundsArrayType &bounds) override
CheckBounds.
virtual void InitializePlane(const Point3D &origin, const Vector3D &normal)
Initialize plane by origin and normal (size is 1.0 mm in all directions, direction of right-/down-vec...
MITKCORE_EXPORT const ScalarType eps
virtual void InitializeStandardPlane(const BaseGeometry *geometry3D, PlaneOrientation planeorientation=Axial, ScalarType zPosition=0, bool frontside=true, bool rotated=false, bool top=true)
Initialize a plane with orientation planeorientation (default: axial) with respect to BaseGeometry (d...
bool IsBoundingBoxNull() const
Describes a two-dimensional, rectangular plane.
bool IsInside(const mitk::Point3D &p) const
Test whether the point p (world coordinates in mm) is inside the bounding box.
OperationType GetOperationType()
ScalarType GetExtentInMM(int direction) const
Get the extent of the bounding-box in the specified direction in mm.
virtual bool GetImageGeometry() const
Is this an ImageGeometry?
BaseGeometry Describes the geometry of a data object.
virtual void ExecuteOperation(Operation *operation) override
executes affine operations (translate, rotate, scale)
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.
BoundingBoxType::BoundsArrayType BoundsArrayType
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
virtual const BoundingBoxType * GetBoundingBox()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.