mitk::Point2D mitk::PlanarDoubleEllipse::ApplyControlPointConstraints(unsigned int index, const Point2D& point)
{
  if (index == 2 && !m_ConstrainCircle)
  {
    Point2D centerPoint = this->GetControlPoint(0);
    Vector2D outerMajorVector = this->GetControlPoint(1) - centerPoint;

    Vector2D minorDirection;
    minorDirection[0] = outerMajorVector[1];
    minorDirection[1] = -outerMajorVector[0];
    minorDirection.Normalize();

    double outerMajorRadius = outerMajorVector.GetNorm();
    double innerMajorRadius = (this->GetControlPoint(3) - centerPoint).GetNorm();
    ScalarType radius = std::max(outerMajorRadius - innerMajorRadius, std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));

    return centerPoint + minorDirection * radius;
  }
  else if (index == 3 && !m_ConstrainThickness)
  {
    Point2D centerPoint = this->GetControlPoint(0);
    Vector2D outerMajorVector = this->GetControlPoint(1) - centerPoint;

    double outerMajorRadius = outerMajorVector.GetNorm();
    double outerMinorRadius = (this->GetControlPoint(2) - centerPoint).GetNorm();
    ScalarType radius = std::max(outerMajorRadius - outerMinorRadius, std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));

    outerMajorVector.Normalize();

    return centerPoint - outerMajorVector * radius;
  }

  return point;
}
void mitk::PlanarDoubleEllipse::EvaluateFeaturesInternal()
{
  Point2D centerPoint = this->GetControlPoint(0);
  ScalarType outerMajorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(1));

  this->SetQuantity(FEATURE_ID_MAJOR_AXIS, 2 * outerMajorRadius);
  this->SetQuantity(FEATURE_ID_MINOR_AXIS, 2 * centerPoint.EuclideanDistanceTo(this->GetControlPoint(2)));
  this->SetQuantity(FEATURE_ID_THICKNESS, outerMajorRadius - centerPoint.EuclideanDistanceTo(this->GetControlPoint(3)));
}
void mitk::AffineImageCropperInteractor::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if(positionEvent == NULL)
    return;

  Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
  if(currentPickedDisplayPoint.EuclideanDistanceTo(m_InitialPickedDisplayPoint) < 1)
    return;

  vtkRenderer* currentVtkRenderer = interactionEvent->GetSender()->GetVtkRenderer();

  if ( currentVtkRenderer &&  currentVtkRenderer->GetActiveCamera())
  {
    double vpn[3];
    currentVtkRenderer->GetActiveCamera()->GetViewPlaneNormal( vpn );

    Vector3D rotationAxis;
    rotationAxis[0] = vpn[0];
    rotationAxis[1] = vpn[1];
    rotationAxis[2] = vpn[2];
    rotationAxis.Normalize();

    Vector2D move = currentPickedDisplayPoint - m_InitialPickedDisplayPoint;

    double rotationAngle = -57.3 * atan(move[0]/move[1]);
    if(move[1]<0) rotationAngle +=180;

    // Use center of data bounding box as center of rotation
    Point3D rotationCenter = m_OriginalGeometry->GetCenter();
    if(positionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D)
      rotationCenter = m_InitialPickedPoint;

    // Reset current Geometry3D to original state (pre-interaction) and
    // apply rotation
    RotationOperation op( OpROTATE, rotationCenter, rotationAxis, rotationAngle );
    Geometry3D::Pointer newGeometry = static_cast<Geometry3D*>(m_OriginalGeometry->Clone().GetPointer());
    newGeometry->ExecuteOperation( &op );
    m_SelectedNode->GetData()->SetGeometry(newGeometry);

    interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
  }
}
mitk::Point2D mitk::PlanarCross::ApplyControlPointConstraints(unsigned int index, const Point2D &point)
{
  // Apply spatial constraints from superclass and from this class until the resulting constrained
  // point converges. Although not an optimal implementation, this iterative approach
  // helps to respect both constraints from the superclass and from this class. Without this,
  // situations may occur where control points are constrained by the superclass, but again
  // moved out of the superclass bounds by the subclass, or vice versa.

  unsigned int count = 0; // ensures stop of approach if point does not converge in reasonable time
  Point2D confinedPoint = point;
  Point2D superclassConfinedPoint;
  do
  {
    superclassConfinedPoint = Superclass::ApplyControlPointConstraints(index, confinedPoint);
    confinedPoint = this->InternalApplyControlPointConstraints(index, superclassConfinedPoint);
    ++count;
  } while ((confinedPoint.EuclideanDistanceTo(superclassConfinedPoint) > mitk::eps) && (count < 32));

  return confinedPoint;
}
mitk::Point2D mitk::PlanarCross::InternalApplyControlPointConstraints(unsigned int index, const Point2D &point)
{
  // Apply constraints depending on current interaction state
  switch (index)
  {
    case 2:
    {
      // Check if 3rd control point is outside of the range (2D area) defined by the first
      // line (via the first two control points); if it is outside, clip it to the bounds
      const Point2D p1 = this->GetControlPoint(0);
      const Point2D p2 = this->GetControlPoint(1);

      Vector2D n1 = p2 - p1;
      n1.Normalize();

      const Vector2D v1 = point - p1;
      const double dotProduct = n1 * v1;
      const Point2D crossPoint = p1 + n1 * dotProduct;
      ;
      const Vector2D crossVector = point - crossPoint;

      if (dotProduct < 0.0)
      {
        // Out-of-bounds on the left: clip point to left boundary
        return (p1 + crossVector);
      }
      else if (dotProduct > p2.EuclideanDistanceTo(p1))
      {
        // Out-of-bounds on the right: clip point to right boundary
        return (p2 + crossVector);
      }
      else
      {
        // Pass back original point
        return point;
      }
    }

    case 3:
    {
      // Constrain 4th control point so that with the 3rd control point it forms
      // a line orthogonal to the first line (constraint 1); the 4th control point
      // must lie on the opposite side of the line defined by the first two control
      // points than the 3rd control point (constraint 2)
      const Point2D p1 = this->GetControlPoint(0);
      const Point2D p2 = this->GetControlPoint(1);
      const Point2D p3 = this->GetControlPoint(2);

      // Calculate distance of original point from orthogonal line the corrected
      // point should lie on to project the point onto this line
      Vector2D n1 = p2 - p1;
      n1.Normalize();

      const Vector2D v1 = point - p3;
      const double dotProduct1 = n1 * v1;

      const Point2D pointOnLine = point - n1 * dotProduct1;

      // Project new point onto line [p1, p2]
      const Vector2D v2 = pointOnLine - p1;
      double dotProduct2 = n1 * v2;

      const Point2D crossingPoint = p1 + n1 * dotProduct2;

      // Determine whether the projected point on the line, or the crossing point should be
      // used (according to the second constraint in the comment above)
      if ((pointOnLine.SquaredEuclideanDistanceTo(p3) > crossingPoint.SquaredEuclideanDistanceTo(p3)) &&
          (pointOnLine.SquaredEuclideanDistanceTo(p3) > pointOnLine.SquaredEuclideanDistanceTo(crossingPoint)))
      {
        return pointOnLine;
      }
      else
      {
        return crossingPoint;
      }
    }

    default:
      return point;
  }
}
bool mitk::PlanarEllipse::SetControlPoint( unsigned int index, const Point2D &point, bool createIfDoesNotExist )
{
    if(index == 0) // moving center point and control points accordingly
    {
        const Point2D &centerPoint = GetControlPoint( 0 );
        Point2D boundaryPoint1 = GetControlPoint( 1 );
        Point2D boundaryPoint2 = GetControlPoint( 2 );
        Point2D boundaryPoint3 = GetControlPoint( 3 );
        vnl_vector<ScalarType> vec = (point.GetVnlVector() - centerPoint.GetVnlVector());

        boundaryPoint1[0] += vec[0];
        boundaryPoint1[1] += vec[1];
        boundaryPoint2[0] += vec[0];
        boundaryPoint2[1] += vec[1];
        boundaryPoint3[0] += vec[0];
        boundaryPoint3[1] += vec[1];
        PlanarFigure::SetControlPoint( 0, point, createIfDoesNotExist );
        PlanarFigure::SetControlPoint( 1, boundaryPoint1, createIfDoesNotExist );
        PlanarFigure::SetControlPoint( 2, boundaryPoint2, createIfDoesNotExist );
        PlanarFigure::SetControlPoint( 3, boundaryPoint3, createIfDoesNotExist );
        return true;
    }
    else if (index < 3)
    {
        PlanarFigure::SetControlPoint( index, point, createIfDoesNotExist );
        int otherIndex = index+1;
        if (otherIndex > 2)
            otherIndex = 1;

        const Point2D &centerPoint = GetControlPoint( 0 );
        Point2D otherPoint = GetControlPoint( otherIndex );
        Point2D point3 = GetControlPoint( 3 );

        Vector2D vec1 = point - centerPoint;
        Vector2D vec2;

        if (index == 1 && m_TreatAsCircle )
        {
            float x = vec1[0];
            vec2[0] = vec1[1];
            vec2[1] = x;

            if (index==1)
                vec2[0] *= -1;
            else
                vec2[1] *= -1;

            otherPoint = centerPoint+vec2;
            PlanarFigure::SetControlPoint( otherIndex, otherPoint, createIfDoesNotExist );
            float r = centerPoint.EuclideanDistanceTo(otherPoint);

            // adjust additional third control point
            Point2D p3 = this->GetControlPoint(3);
            Vector2D vec3;
            vec3[0] = p3[0]-centerPoint[0];
            vec3[1] = p3[1]-centerPoint[1];
            if (vec3[0]!=0 || vec3[1]!=0)
            {
                vec3.Normalize();
                vec3 *= r;
            }
            else
            {
                vec3[0] = r;
                vec3[1] = 0;
            }
            point3 = centerPoint + vec3;
            PlanarFigure::SetControlPoint( 3, point3, createIfDoesNotExist );
        }
        else if ( vec1.GetNorm() > 0 )
        {
            float r = centerPoint.EuclideanDistanceTo(otherPoint);
            float x = vec1[0];
            vec2[0] = vec1[1];
            vec2[1] = x;

            if (index==1)
                vec2[0] *= -1;
            else
                vec2[1] *= -1;

            vec2.Normalize(); vec2 *= r;

            if ( vec2.GetNorm() > 0 )
            {
                otherPoint = centerPoint+vec2;
                PlanarFigure::SetControlPoint( otherIndex, otherPoint, createIfDoesNotExist );
            }

            // adjust third control point
            Vector2D vec3 = point3 - centerPoint; vec3.Normalize();
            double r1 = centerPoint.EuclideanDistanceTo( GetControlPoint( 1 ) );
            double r2 = centerPoint.EuclideanDistanceTo( GetControlPoint( 2 ) );
            Point2D newPoint = centerPoint + vec3*std::max(r1, r2);
            PlanarFigure::SetControlPoint( 3, newPoint, createIfDoesNotExist );

            m_TreatAsCircle = false;
        }
        return true;
    }
    else if (index == 3)
    {
        Point2D centerPoint = GetControlPoint( 0 );
        Vector2D vec3 = point - centerPoint; vec3.Normalize();
        double r1 = centerPoint.EuclideanDistanceTo( GetControlPoint( 1 ) );
        double r2 = centerPoint.EuclideanDistanceTo( GetControlPoint( 2 ) );
        Point2D newPoint = centerPoint + vec3*std::max(r1, r2);
        PlanarFigure::SetControlPoint( index, newPoint, createIfDoesNotExist );
        m_TreatAsCircle = false;
        return true;
    }
    return false;
}
void mitk::PlanarDoubleEllipse::GeneratePolyLine()
{
  this->ClearPolyLines();

  Point2D centerPoint = this->GetControlPoint(0);
  Point2D outerMajorPoint = this->GetControlPoint(1);

  Vector2D direction = outerMajorPoint - centerPoint;
  direction.Normalize();

  const ScalarType deltaAngle = vnl_math::pi / (m_NumberOfSegments / 2);

  int start = 0;
  int end = m_NumberOfSegments;

  if (direction[1] < 0.0)
  {
    direction[0] = -direction[0];
    end = m_NumberOfSegments / 2;
    start = -end;
  }

  vnl_matrix_fixed<mitk::ScalarType, 2, 2> rotation;
  rotation[1][0] = std::sin(std::acos(direction[0]));
  rotation[0][0] = direction[0];
  rotation[1][1] = direction[0];
  rotation[0][1] = -rotation[1][0];

  ScalarType outerMajorRadius = centerPoint.EuclideanDistanceTo(outerMajorPoint);
  ScalarType outerMinorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
  ScalarType innerMajorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(3));
  ScalarType innerMinorRadius = innerMajorRadius - (outerMajorRadius - outerMinorRadius);

  ScalarType angle;
  ScalarType cosAngle;
  ScalarType sinAngle;
  vnl_vector_fixed<mitk::ScalarType, 2> vector;
  Point2D point;

  for (int i = start; i < end; ++i)
  {
    angle = i * deltaAngle;
    cosAngle = std::cos(angle);
    sinAngle = std::sin(angle);

    vector[0] = outerMajorRadius * cosAngle;
    vector[1] = outerMinorRadius * sinAngle;
    vector = rotation * vector;

    point[0] = centerPoint[0] + vector[0];
    point[1] = centerPoint[1] + vector[1];

    this->AppendPointToPolyLine(0, point);

    vector[0] = innerMajorRadius * cosAngle;
    vector[1] = innerMinorRadius * sinAngle;
    vector = rotation * vector;

    point[0] = centerPoint[0] + vector[0];
    point[1] = centerPoint[1] + vector[1];

    this->AppendPointToPolyLine(1, point);
  }
}
bool mitk::PlanarDoubleEllipse::SetControlPoint(unsigned int index, const Point2D& point, bool createIfDoesNotExist)
{
  switch (index)
  {
    case 0:
    {
      Point2D centerPoint = this->GetControlPoint(0);
      Vector2D vector = point - centerPoint;

      Superclass::SetControlPoint(0, point, createIfDoesNotExist);
      Superclass::SetControlPoint(1, this->GetControlPoint(1) + vector, createIfDoesNotExist);
      Superclass::SetControlPoint(2, this->GetControlPoint(2) + vector, createIfDoesNotExist);
      Superclass::SetControlPoint(3, this->GetControlPoint(3) + vector, createIfDoesNotExist);

      break;
    }

    case 1:
    {
      Vector2D vector = point - this->GetControlPoint(1);

      Superclass::SetControlPoint(1, point, createIfDoesNotExist);

      Point2D centerPoint = this->GetControlPoint(0);
      Vector2D outerMajorVector = point - centerPoint;

      Vector2D outerMinorVector;
      outerMinorVector[0] = outerMajorVector[1];
      outerMinorVector[1] = -outerMajorVector[0];

      if (!m_ConstrainCircle)
      {
        outerMinorVector.Normalize();
        outerMinorVector *= centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
      }

      Superclass::SetControlPoint(2, centerPoint + outerMinorVector, createIfDoesNotExist);

      Vector2D innerMajorVector = outerMajorVector;

      if (!m_ConstrainThickness)
      {
        innerMajorVector.Normalize();
        innerMajorVector *= centerPoint.EuclideanDistanceTo(this->GetControlPoint(3) - vector);
      }

      Superclass::SetControlPoint(3, centerPoint - innerMajorVector, createIfDoesNotExist);

      break;
    }

    case 2:
    {
      m_ConstrainCircle = false;
      Superclass::SetControlPoint(2, point, createIfDoesNotExist);

      break;
    }

    case 3:
    {
      m_ConstrainThickness = false;
      Superclass::SetControlPoint(3, point, createIfDoesNotExist);

      break;
    }

    default:
      return false;
  }

  return true;
}
void mitk::PlanarAngle::GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight)
{
  // Generate helper-poly-line for angle
  if ( this->GetNumberOfControlPoints() < 3)
  {
    m_HelperPolyLinesToBePainted->SetElement(0, false);
    return; //We do not need to draw an angle as there are no two arms yet
  }

  this->ClearHelperPolyLines();

  const Point2D centerPoint = this->GetControlPoint( 1 );
  const Point2D boundaryPointOne = this->GetControlPoint( 0 );
  const Point2D boundaryPointTwo = this->GetControlPoint( 2 );


  double radius = centerPoint.EuclideanDistanceTo( boundaryPointOne );
  if ( radius > centerPoint.EuclideanDistanceTo( boundaryPointTwo ) )
  {
    radius = centerPoint.EuclideanDistanceTo( boundaryPointTwo );
  }

  //Fixed size radius depending on screen size for the angle
  double nonScalingRadius = displayHeight * mmPerDisplayUnit * 0.05;

  if (nonScalingRadius > radius)
  {
    m_HelperPolyLinesToBePainted->SetElement(0, false);
    return; //if the arc has a radius that is longer than the shortest arm it should not be painted
  }

  m_HelperPolyLinesToBePainted->SetElement(0, true);
  radius = nonScalingRadius;

  double angle = this->GetQuantity( FEATURE_ID_ANGLE );

  //Determine from which arm the angle should be drawn

  Vector2D v0 = boundaryPointOne - centerPoint;
  Vector2D v1 = boundaryPointTwo - centerPoint;
  Vector2D v2;
  v2[0] = 1.0;
  v2[1] = 0.0;

  v0[0] = v0[0] * cos( 0.001 ) - v0[1] * sin( 0.001 ); //rotate one arm a bit
  v0[1] = v0[0] * sin( 0.001 ) + v0[1] * cos( 0.001 );
  v0.Normalize();
  v1.Normalize();
  double testAngle = acos( v0 * v1 );
  //if the rotated arm is closer to the other arm than before it is the one from which we start drawing
  //else we start drawing from the other arm (we want to draw in the mathematically positive direction)
  if( angle > testAngle )
  {
    v1[0] = v0[0] * cos( -0.001 ) - v0[1] * sin( -0.001 );
    v1[1] = v0[0] * sin( -0.001 ) + v0[1] * cos( -0.001 );

    //We determine if the arm is mathematically forward or backward
    //assuming we rotate between -pi and pi
    if ( acos( v0 * v2 ) > acos ( v1 * v2 ))
    {
      testAngle = acos( v1 * v2 );
    }
    else
    {
      testAngle = -acos( v1 * v2 );
    }
  }
  else
  {
    v0[0] = v1[0] * cos( -0.001 ) - v1[1] * sin( -0.001 );
    v0[1] = v1[0] * sin( -0.001 ) + v1[1] * cos( -0.001 );
    //We determine if the arm is mathematically forward or backward
    //assuming we rotate between -pi and pi
    if ( acos( v0 * v2 ) < acos ( v1 * v2 ))
    {
      testAngle = acos( v1 * v2 );
    }
    else
    {
      testAngle = -acos( v1 * v2 );
    }
  }
  // Generate poly-line with 16 segments
  for ( int t = 0; t < 16; ++t )
  {
    double alpha = (double) t * angle / 15.0 + testAngle;

    Point2D polyLinePoint;
    polyLinePoint[0] = centerPoint[0] + radius * cos( alpha );
    polyLinePoint[1] = centerPoint[1] + radius * sin( alpha );

    this->AppendPointToHelperPolyLine(0, polyLinePoint);
  }
}